Home | History | Annotate | Line # | Download | only in dist
fpsp.s revision 1.1.6.2
      1  1.1.6.2  bouyer #
      2  1.1.6.2  bouyer # $NetBSD: fpsp.s,v 1.1.6.2 2000/11/20 20:11:29 bouyer Exp $
      3  1.1.6.2  bouyer #
      4  1.1.6.2  bouyer 
      5  1.1.6.2  bouyer #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      6  1.1.6.2  bouyer # MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
      7  1.1.6.2  bouyer # M68000 Hi-Performance Microprocessor Division
      8  1.1.6.2  bouyer # M68060 Software Package Production Release
      9  1.1.6.2  bouyer #
     10  1.1.6.2  bouyer # M68060 Software Package Copyright (C) 1993, 1994, 1995, 1996 Motorola Inc.
     11  1.1.6.2  bouyer # All rights reserved.
     12  1.1.6.2  bouyer #
     13  1.1.6.2  bouyer # THE SOFTWARE is provided on an "AS IS" basis and without warranty.
     14  1.1.6.2  bouyer # To the maximum extent permitted by applicable law,
     15  1.1.6.2  bouyer # MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
     16  1.1.6.2  bouyer # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS
     17  1.1.6.2  bouyer # FOR A PARTICULAR PURPOSE and any warranty against infringement with
     18  1.1.6.2  bouyer # regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
     19  1.1.6.2  bouyer # and any accompanying written materials.
     20  1.1.6.2  bouyer #
     21  1.1.6.2  bouyer # To the maximum extent permitted by applicable law,
     22  1.1.6.2  bouyer # IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
     23  1.1.6.2  bouyer # (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
     24  1.1.6.2  bouyer # BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
     25  1.1.6.2  bouyer # ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
     26  1.1.6.2  bouyer #
     27  1.1.6.2  bouyer # Motorola assumes no responsibility for the maintenance and support
     28  1.1.6.2  bouyer # of the SOFTWARE.
     29  1.1.6.2  bouyer #
     30  1.1.6.2  bouyer # You are hereby granted a copyright license to use, modify, and distribute the
     31  1.1.6.2  bouyer # SOFTWARE so long as this entire notice is retained without alteration
     32  1.1.6.2  bouyer # in any modified and/or redistributed versions, and that such modified
     33  1.1.6.2  bouyer # versions are clearly identified as such.
     34  1.1.6.2  bouyer # No licenses are granted by implication, estoppel or otherwise under any
     35  1.1.6.2  bouyer # patents or trademarks of Motorola, Inc.
     36  1.1.6.2  bouyer #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     37  1.1.6.2  bouyer 
     38  1.1.6.2  bouyer #
     39  1.1.6.2  bouyer # freal.s:
     40  1.1.6.2  bouyer #	This file is appended to the top of the 060FPSP package
     41  1.1.6.2  bouyer # and contains the entry points into the package. The user, in
     42  1.1.6.2  bouyer # effect, branches to one of the branch table entries located
     43  1.1.6.2  bouyer # after _060FPSP_TABLE.
     44  1.1.6.2  bouyer #	Also, subroutine stubs exist in this file (_fpsp_done for
     45  1.1.6.2  bouyer # example) that are referenced by the FPSP package itself in order
     46  1.1.6.2  bouyer # to call a given routine. The stub routine actually performs the
     47  1.1.6.2  bouyer # callout. The FPSP code does a "bsr" to the stub routine. This
     48  1.1.6.2  bouyer # extra layer of hierarchy adds a slight performance penalty but
     49  1.1.6.2  bouyer # it makes the FPSP code easier to read and more mainatinable.
     50  1.1.6.2  bouyer #
     51  1.1.6.2  bouyer 
     52  1.1.6.2  bouyer set	_off_bsun,	0x00
     53  1.1.6.2  bouyer set	_off_snan,	0x04
     54  1.1.6.2  bouyer set	_off_operr,	0x08
     55  1.1.6.2  bouyer set	_off_ovfl,	0x0c
     56  1.1.6.2  bouyer set	_off_unfl,	0x10
     57  1.1.6.2  bouyer set	_off_dz,	0x14
     58  1.1.6.2  bouyer set	_off_inex,	0x18
     59  1.1.6.2  bouyer set	_off_fline,	0x1c
     60  1.1.6.2  bouyer set	_off_fpu_dis,	0x20
     61  1.1.6.2  bouyer set	_off_trap,	0x24
     62  1.1.6.2  bouyer set	_off_trace,	0x28
     63  1.1.6.2  bouyer set	_off_access,	0x2c
     64  1.1.6.2  bouyer set	_off_done,	0x30
     65  1.1.6.2  bouyer 
     66  1.1.6.2  bouyer set	_off_imr,	0x40
     67  1.1.6.2  bouyer set	_off_dmr,	0x44
     68  1.1.6.2  bouyer set	_off_dmw,	0x48
     69  1.1.6.2  bouyer set	_off_irw,	0x4c
     70  1.1.6.2  bouyer set	_off_irl,	0x50
     71  1.1.6.2  bouyer set	_off_drb,	0x54
     72  1.1.6.2  bouyer set	_off_drw,	0x58
     73  1.1.6.2  bouyer set	_off_drl,	0x5c
     74  1.1.6.2  bouyer set	_off_dwb,	0x60
     75  1.1.6.2  bouyer set	_off_dww,	0x64
     76  1.1.6.2  bouyer set	_off_dwl,	0x68
     77  1.1.6.2  bouyer 
     78  1.1.6.2  bouyer _060FPSP_TABLE:
     79  1.1.6.2  bouyer 
     80  1.1.6.2  bouyer ###############################################################
     81  1.1.6.2  bouyer 
     82  1.1.6.2  bouyer # Here's the table of ENTRY POINTS for those linking the package.
     83  1.1.6.2  bouyer 	bra.l		_fpsp_snan
     84  1.1.6.2  bouyer 	short		0x0000
     85  1.1.6.2  bouyer 	bra.l		_fpsp_operr
     86  1.1.6.2  bouyer 	short		0x0000
     87  1.1.6.2  bouyer 	bra.l		_fpsp_ovfl
     88  1.1.6.2  bouyer 	short		0x0000
     89  1.1.6.2  bouyer 	bra.l		_fpsp_unfl
     90  1.1.6.2  bouyer 	short		0x0000
     91  1.1.6.2  bouyer 	bra.l		_fpsp_dz
     92  1.1.6.2  bouyer 	short		0x0000
     93  1.1.6.2  bouyer 	bra.l		_fpsp_inex
     94  1.1.6.2  bouyer 	short		0x0000
     95  1.1.6.2  bouyer 	bra.l		_fpsp_fline
     96  1.1.6.2  bouyer 	short		0x0000
     97  1.1.6.2  bouyer 	bra.l		_fpsp_unsupp
     98  1.1.6.2  bouyer 	short		0x0000
     99  1.1.6.2  bouyer 	bra.l		_fpsp_effadd
    100  1.1.6.2  bouyer 	short		0x0000
    101  1.1.6.2  bouyer 
    102  1.1.6.2  bouyer 	space 		56
    103  1.1.6.2  bouyer 
    104  1.1.6.2  bouyer ###############################################################
    105  1.1.6.2  bouyer 	global		_fpsp_done
    106  1.1.6.2  bouyer _fpsp_done:
    107  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    108  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_done,%pc),%d0
    109  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    110  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    111  1.1.6.2  bouyer 	rtd		&0x4
    112  1.1.6.2  bouyer 
    113  1.1.6.2  bouyer 	global		_real_ovfl
    114  1.1.6.2  bouyer _real_ovfl:
    115  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    116  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_ovfl,%pc),%d0
    117  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    118  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    119  1.1.6.2  bouyer 	rtd		&0x4
    120  1.1.6.2  bouyer 
    121  1.1.6.2  bouyer 	global		_real_unfl
    122  1.1.6.2  bouyer _real_unfl:
    123  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    124  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_unfl,%pc),%d0
    125  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    126  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    127  1.1.6.2  bouyer 	rtd		&0x4
    128  1.1.6.2  bouyer 
    129  1.1.6.2  bouyer 	global		_real_inex
    130  1.1.6.2  bouyer _real_inex:
    131  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    132  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_inex,%pc),%d0
    133  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    134  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    135  1.1.6.2  bouyer 	rtd		&0x4
    136  1.1.6.2  bouyer 
    137  1.1.6.2  bouyer 	global		_real_bsun
    138  1.1.6.2  bouyer _real_bsun:
    139  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    140  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_bsun,%pc),%d0
    141  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    142  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    143  1.1.6.2  bouyer 	rtd		&0x4
    144  1.1.6.2  bouyer 
    145  1.1.6.2  bouyer 	global		_real_operr
    146  1.1.6.2  bouyer _real_operr:
    147  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    148  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_operr,%pc),%d0
    149  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    150  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    151  1.1.6.2  bouyer 	rtd		&0x4
    152  1.1.6.2  bouyer 
    153  1.1.6.2  bouyer 	global		_real_snan
    154  1.1.6.2  bouyer _real_snan:
    155  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    156  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_snan,%pc),%d0
    157  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    158  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    159  1.1.6.2  bouyer 	rtd		&0x4
    160  1.1.6.2  bouyer 
    161  1.1.6.2  bouyer 	global		_real_dz
    162  1.1.6.2  bouyer _real_dz:
    163  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    164  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_dz,%pc),%d0
    165  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    166  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    167  1.1.6.2  bouyer 	rtd		&0x4
    168  1.1.6.2  bouyer 
    169  1.1.6.2  bouyer 	global		_real_fline
    170  1.1.6.2  bouyer _real_fline:
    171  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    172  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_fline,%pc),%d0
    173  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    174  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    175  1.1.6.2  bouyer 	rtd		&0x4
    176  1.1.6.2  bouyer 
    177  1.1.6.2  bouyer 	global		_real_fpu_disabled
    178  1.1.6.2  bouyer _real_fpu_disabled:
    179  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    180  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_fpu_dis,%pc),%d0
    181  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    182  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    183  1.1.6.2  bouyer 	rtd		&0x4
    184  1.1.6.2  bouyer 
    185  1.1.6.2  bouyer 	global		_real_trap
    186  1.1.6.2  bouyer _real_trap:
    187  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    188  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_trap,%pc),%d0
    189  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    190  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    191  1.1.6.2  bouyer 	rtd		&0x4
    192  1.1.6.2  bouyer 
    193  1.1.6.2  bouyer 	global		_real_trace
    194  1.1.6.2  bouyer _real_trace:
    195  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    196  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_trace,%pc),%d0
    197  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    198  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    199  1.1.6.2  bouyer 	rtd		&0x4
    200  1.1.6.2  bouyer 
    201  1.1.6.2  bouyer 	global		_real_access
    202  1.1.6.2  bouyer _real_access:
    203  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    204  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_access,%pc),%d0
    205  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    206  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    207  1.1.6.2  bouyer 	rtd		&0x4
    208  1.1.6.2  bouyer 
    209  1.1.6.2  bouyer #######################################
    210  1.1.6.2  bouyer 
    211  1.1.6.2  bouyer 	global		_imem_read
    212  1.1.6.2  bouyer _imem_read:
    213  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    214  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_imr,%pc),%d0
    215  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    216  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    217  1.1.6.2  bouyer 	rtd		&0x4
    218  1.1.6.2  bouyer 
    219  1.1.6.2  bouyer 	global		_dmem_read
    220  1.1.6.2  bouyer _dmem_read:
    221  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    222  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_dmr,%pc),%d0
    223  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    224  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    225  1.1.6.2  bouyer 	rtd		&0x4
    226  1.1.6.2  bouyer 
    227  1.1.6.2  bouyer 	global		_dmem_write
    228  1.1.6.2  bouyer _dmem_write:
    229  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    230  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_dmw,%pc),%d0
    231  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    232  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    233  1.1.6.2  bouyer 	rtd		&0x4
    234  1.1.6.2  bouyer 
    235  1.1.6.2  bouyer 	global		_imem_read_word
    236  1.1.6.2  bouyer _imem_read_word:
    237  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    238  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_irw,%pc),%d0
    239  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    240  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    241  1.1.6.2  bouyer 	rtd		&0x4
    242  1.1.6.2  bouyer 
    243  1.1.6.2  bouyer 	global		_imem_read_long
    244  1.1.6.2  bouyer _imem_read_long:
    245  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    246  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_irl,%pc),%d0
    247  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    248  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    249  1.1.6.2  bouyer 	rtd		&0x4
    250  1.1.6.2  bouyer 
    251  1.1.6.2  bouyer 	global		_dmem_read_byte
    252  1.1.6.2  bouyer _dmem_read_byte:
    253  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    254  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_drb,%pc),%d0
    255  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    256  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    257  1.1.6.2  bouyer 	rtd		&0x4
    258  1.1.6.2  bouyer 
    259  1.1.6.2  bouyer 	global		_dmem_read_word
    260  1.1.6.2  bouyer _dmem_read_word:
    261  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    262  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_drw,%pc),%d0
    263  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    264  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    265  1.1.6.2  bouyer 	rtd		&0x4
    266  1.1.6.2  bouyer 
    267  1.1.6.2  bouyer 	global		_dmem_read_long
    268  1.1.6.2  bouyer _dmem_read_long:
    269  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    270  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_drl,%pc),%d0
    271  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    272  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    273  1.1.6.2  bouyer 	rtd		&0x4
    274  1.1.6.2  bouyer 
    275  1.1.6.2  bouyer 	global		_dmem_write_byte
    276  1.1.6.2  bouyer _dmem_write_byte:
    277  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    278  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_dwb,%pc),%d0
    279  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    280  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    281  1.1.6.2  bouyer 	rtd		&0x4
    282  1.1.6.2  bouyer 
    283  1.1.6.2  bouyer 	global		_dmem_write_word
    284  1.1.6.2  bouyer _dmem_write_word:
    285  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    286  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_dww,%pc),%d0
    287  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    288  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    289  1.1.6.2  bouyer 	rtd		&0x4
    290  1.1.6.2  bouyer 
    291  1.1.6.2  bouyer 	global		_dmem_write_long
    292  1.1.6.2  bouyer _dmem_write_long:
    293  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
    294  1.1.6.2  bouyer 	mov.l		(_060FPSP_TABLE-0x80+_off_dwl,%pc),%d0
    295  1.1.6.2  bouyer 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
    296  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0
    297  1.1.6.2  bouyer 	rtd		&0x4
    298  1.1.6.2  bouyer 
    299  1.1.6.2  bouyer #
    300  1.1.6.2  bouyer # This file contains a set of define statements for constants
    301  1.1.6.2  bouyer # in order to promote readability within the corecode itself.
    302  1.1.6.2  bouyer #
    303  1.1.6.2  bouyer 
    304  1.1.6.2  bouyer set LOCAL_SIZE,		192			# stack frame size(bytes)
    305  1.1.6.2  bouyer set LV,			-LOCAL_SIZE		# stack offset
    306  1.1.6.2  bouyer 
    307  1.1.6.2  bouyer set EXC_SR,		0x4			# stack status register
    308  1.1.6.2  bouyer set EXC_PC,		0x6			# stack pc
    309  1.1.6.2  bouyer set EXC_VOFF,		0xa			# stacked vector offset
    310  1.1.6.2  bouyer set EXC_EA,		0xc			# stacked <ea>
    311  1.1.6.2  bouyer 
    312  1.1.6.2  bouyer set EXC_FP,		0x0			# frame pointer
    313  1.1.6.2  bouyer 
    314  1.1.6.2  bouyer set EXC_AREGS,		-68			# offset of all address regs
    315  1.1.6.2  bouyer set EXC_DREGS,		-100			# offset of all data regs
    316  1.1.6.2  bouyer set EXC_FPREGS,		-36			# offset of all fp regs
    317  1.1.6.2  bouyer 
    318  1.1.6.2  bouyer set EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
    319  1.1.6.2  bouyer set OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
    320  1.1.6.2  bouyer set EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
    321  1.1.6.2  bouyer set EXC_A5,		EXC_AREGS+(5*4)
    322  1.1.6.2  bouyer set EXC_A4,		EXC_AREGS+(4*4)
    323  1.1.6.2  bouyer set EXC_A3,		EXC_AREGS+(3*4)
    324  1.1.6.2  bouyer set EXC_A2,		EXC_AREGS+(2*4)
    325  1.1.6.2  bouyer set EXC_A1,		EXC_AREGS+(1*4)
    326  1.1.6.2  bouyer set EXC_A0,		EXC_AREGS+(0*4)
    327  1.1.6.2  bouyer set EXC_D7,		EXC_DREGS+(7*4)
    328  1.1.6.2  bouyer set EXC_D6,		EXC_DREGS+(6*4)
    329  1.1.6.2  bouyer set EXC_D5,		EXC_DREGS+(5*4)
    330  1.1.6.2  bouyer set EXC_D4,		EXC_DREGS+(4*4)
    331  1.1.6.2  bouyer set EXC_D3,		EXC_DREGS+(3*4)
    332  1.1.6.2  bouyer set EXC_D2,		EXC_DREGS+(2*4)
    333  1.1.6.2  bouyer set EXC_D1,		EXC_DREGS+(1*4)
    334  1.1.6.2  bouyer set EXC_D0,		EXC_DREGS+(0*4)
    335  1.1.6.2  bouyer 
    336  1.1.6.2  bouyer set EXC_FP0, 		EXC_FPREGS+(0*12)	# offset of saved fp0
    337  1.1.6.2  bouyer set EXC_FP1, 		EXC_FPREGS+(1*12)	# offset of saved fp1
    338  1.1.6.2  bouyer set EXC_FP2, 		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
    339  1.1.6.2  bouyer 
    340  1.1.6.2  bouyer set FP_SCR1, 		LV+80			# fp scratch 1
    341  1.1.6.2  bouyer set FP_SCR1_EX, 	FP_SCR1+0
    342  1.1.6.2  bouyer set FP_SCR1_SGN,	FP_SCR1+2
    343  1.1.6.2  bouyer set FP_SCR1_HI, 	FP_SCR1+4
    344  1.1.6.2  bouyer set FP_SCR1_LO, 	FP_SCR1+8
    345  1.1.6.2  bouyer 
    346  1.1.6.2  bouyer set FP_SCR0, 		LV+68			# fp scratch 0
    347  1.1.6.2  bouyer set FP_SCR0_EX, 	FP_SCR0+0
    348  1.1.6.2  bouyer set FP_SCR0_SGN,	FP_SCR0+2
    349  1.1.6.2  bouyer set FP_SCR0_HI, 	FP_SCR0+4
    350  1.1.6.2  bouyer set FP_SCR0_LO, 	FP_SCR0+8
    351  1.1.6.2  bouyer 
    352  1.1.6.2  bouyer set FP_DST, 		LV+56			# fp destination operand
    353  1.1.6.2  bouyer set FP_DST_EX, 		FP_DST+0
    354  1.1.6.2  bouyer set FP_DST_SGN,		FP_DST+2
    355  1.1.6.2  bouyer set FP_DST_HI, 		FP_DST+4
    356  1.1.6.2  bouyer set FP_DST_LO, 		FP_DST+8
    357  1.1.6.2  bouyer 
    358  1.1.6.2  bouyer set FP_SRC, 		LV+44			# fp source operand
    359  1.1.6.2  bouyer set FP_SRC_EX, 		FP_SRC+0
    360  1.1.6.2  bouyer set FP_SRC_SGN,		FP_SRC+2
    361  1.1.6.2  bouyer set FP_SRC_HI, 		FP_SRC+4
    362  1.1.6.2  bouyer set FP_SRC_LO, 		FP_SRC+8
    363  1.1.6.2  bouyer 
    364  1.1.6.2  bouyer set USER_FPIAR,		LV+40			# FP instr address register
    365  1.1.6.2  bouyer 
    366  1.1.6.2  bouyer set USER_FPSR,		LV+36			# FP status register
    367  1.1.6.2  bouyer set FPSR_CC,		USER_FPSR+0		# FPSR condition codes
    368  1.1.6.2  bouyer set FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
    369  1.1.6.2  bouyer set FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
    370  1.1.6.2  bouyer set FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
    371  1.1.6.2  bouyer 
    372  1.1.6.2  bouyer set USER_FPCR,		LV+32			# FP control register
    373  1.1.6.2  bouyer set FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
    374  1.1.6.2  bouyer set FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
    375  1.1.6.2  bouyer 
    376  1.1.6.2  bouyer set L_SCR3,		LV+28			# integer scratch 3
    377  1.1.6.2  bouyer set L_SCR2,		LV+24			# integer scratch 2
    378  1.1.6.2  bouyer set L_SCR1,		LV+20			# integer scratch 1
    379  1.1.6.2  bouyer 
    380  1.1.6.2  bouyer set STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
    381  1.1.6.2  bouyer 
    382  1.1.6.2  bouyer set EXC_TEMP2,		LV+24			# temporary space
    383  1.1.6.2  bouyer set EXC_TEMP,		LV+16			# temporary space
    384  1.1.6.2  bouyer 
    385  1.1.6.2  bouyer set DTAG,		LV+15			# destination operand type
    386  1.1.6.2  bouyer set STAG, 		LV+14			# source operand type
    387  1.1.6.2  bouyer 
    388  1.1.6.2  bouyer set SPCOND_FLG,		LV+10			# flag: special case (see below)
    389  1.1.6.2  bouyer 
    390  1.1.6.2  bouyer set EXC_CC,		LV+8			# saved condition codes
    391  1.1.6.2  bouyer set EXC_EXTWPTR,	LV+4			# saved current PC (active)
    392  1.1.6.2  bouyer set EXC_EXTWORD,	LV+2			# saved extension word
    393  1.1.6.2  bouyer set EXC_CMDREG,		LV+2			# saved extension word
    394  1.1.6.2  bouyer set EXC_OPWORD,		LV+0			# saved operation word
    395  1.1.6.2  bouyer 
    396  1.1.6.2  bouyer ################################
    397  1.1.6.2  bouyer 
    398  1.1.6.2  bouyer # Helpful macros
    399  1.1.6.2  bouyer 
    400  1.1.6.2  bouyer set FTEMP,		0			# offsets within an
    401  1.1.6.2  bouyer set FTEMP_EX, 		0			# extended precision
    402  1.1.6.2  bouyer set FTEMP_SGN,		2			# value saved in memory.
    403  1.1.6.2  bouyer set FTEMP_HI, 		4
    404  1.1.6.2  bouyer set FTEMP_LO, 		8
    405  1.1.6.2  bouyer set FTEMP_GRS,		12
    406  1.1.6.2  bouyer 
    407  1.1.6.2  bouyer set LOCAL,		0			# offsets within an
    408  1.1.6.2  bouyer set LOCAL_EX, 		0			# extended precision
    409  1.1.6.2  bouyer set LOCAL_SGN,		2			# value saved in memory.
    410  1.1.6.2  bouyer set LOCAL_HI, 		4
    411  1.1.6.2  bouyer set LOCAL_LO, 		8
    412  1.1.6.2  bouyer set LOCAL_GRS,		12
    413  1.1.6.2  bouyer 
    414  1.1.6.2  bouyer set DST,		0			# offsets within an
    415  1.1.6.2  bouyer set DST_EX,		0			# extended precision
    416  1.1.6.2  bouyer set DST_HI,		4			# value saved in memory.
    417  1.1.6.2  bouyer set DST_LO,		8
    418  1.1.6.2  bouyer 
    419  1.1.6.2  bouyer set SRC,		0			# offsets within an
    420  1.1.6.2  bouyer set SRC_EX,		0			# extended precision
    421  1.1.6.2  bouyer set SRC_HI,		4			# value saved in memory.
    422  1.1.6.2  bouyer set SRC_LO,		8
    423  1.1.6.2  bouyer 
    424  1.1.6.2  bouyer set SGL_LO,		0x3f81			# min sgl prec exponent
    425  1.1.6.2  bouyer set SGL_HI,		0x407e			# max sgl prec exponent
    426  1.1.6.2  bouyer set DBL_LO,		0x3c01			# min dbl prec exponent
    427  1.1.6.2  bouyer set DBL_HI,		0x43fe			# max dbl prec exponent
    428  1.1.6.2  bouyer set EXT_LO,		0x0			# min ext prec exponent
    429  1.1.6.2  bouyer set EXT_HI,		0x7ffe			# max ext prec exponent
    430  1.1.6.2  bouyer 
    431  1.1.6.2  bouyer set EXT_BIAS,		0x3fff			# extended precision bias
    432  1.1.6.2  bouyer set SGL_BIAS,		0x007f			# single precision bias
    433  1.1.6.2  bouyer set DBL_BIAS,		0x03ff			# double precision bias
    434  1.1.6.2  bouyer 
    435  1.1.6.2  bouyer set NORM,		0x00			# operand type for STAG/DTAG
    436  1.1.6.2  bouyer set ZERO,		0x01			# operand type for STAG/DTAG
    437  1.1.6.2  bouyer set INF,		0x02			# operand type for STAG/DTAG
    438  1.1.6.2  bouyer set QNAN,		0x03			# operand type for STAG/DTAG
    439  1.1.6.2  bouyer set DENORM,		0x04			# operand type for STAG/DTAG
    440  1.1.6.2  bouyer set SNAN,		0x05			# operand type for STAG/DTAG
    441  1.1.6.2  bouyer set UNNORM,		0x06			# operand type for STAG/DTAG
    442  1.1.6.2  bouyer 
    443  1.1.6.2  bouyer ##################
    444  1.1.6.2  bouyer # FPSR/FPCR bits #
    445  1.1.6.2  bouyer ##################
    446  1.1.6.2  bouyer set neg_bit,		0x3			# negative result
    447  1.1.6.2  bouyer set z_bit,		0x2			# zero result
    448  1.1.6.2  bouyer set inf_bit,		0x1			# infinite result
    449  1.1.6.2  bouyer set nan_bit,		0x0			# NAN result
    450  1.1.6.2  bouyer 
    451  1.1.6.2  bouyer set q_sn_bit,		0x7			# sign bit of quotient byte
    452  1.1.6.2  bouyer 
    453  1.1.6.2  bouyer set bsun_bit,		7			# branch on unordered
    454  1.1.6.2  bouyer set snan_bit,		6			# signalling NAN
    455  1.1.6.2  bouyer set operr_bit,		5			# operand error
    456  1.1.6.2  bouyer set ovfl_bit,		4			# overflow
    457  1.1.6.2  bouyer set unfl_bit,		3			# underflow
    458  1.1.6.2  bouyer set dz_bit,		2			# divide by zero
    459  1.1.6.2  bouyer set inex2_bit,		1			# inexact result 2
    460  1.1.6.2  bouyer set inex1_bit,		0			# inexact result 1
    461  1.1.6.2  bouyer 
    462  1.1.6.2  bouyer set aiop_bit,		7			# accrued inexact operation bit
    463  1.1.6.2  bouyer set aovfl_bit,		6			# accrued overflow bit
    464  1.1.6.2  bouyer set aunfl_bit,		5			# accrued underflow bit
    465  1.1.6.2  bouyer set adz_bit,		4			# accrued dz bit
    466  1.1.6.2  bouyer set ainex_bit,		3			# accrued inexact bit
    467  1.1.6.2  bouyer 
    468  1.1.6.2  bouyer #############################
    469  1.1.6.2  bouyer # FPSR individual bit masks #
    470  1.1.6.2  bouyer #############################
    471  1.1.6.2  bouyer set neg_mask,		0x08000000		# negative bit mask (lw)
    472  1.1.6.2  bouyer set inf_mask,		0x02000000		# infinity bit mask (lw)
    473  1.1.6.2  bouyer set z_mask,		0x04000000		# zero bit mask (lw)
    474  1.1.6.2  bouyer set nan_mask,		0x01000000		# nan bit mask (lw)
    475  1.1.6.2  bouyer 
    476  1.1.6.2  bouyer set neg_bmask,		0x08			# negative bit mask (byte)
    477  1.1.6.2  bouyer set inf_bmask,		0x02			# infinity bit mask (byte)
    478  1.1.6.2  bouyer set z_bmask,		0x04			# zero bit mask (byte)
    479  1.1.6.2  bouyer set nan_bmask,		0x01			# nan bit mask (byte)
    480  1.1.6.2  bouyer 
    481  1.1.6.2  bouyer set bsun_mask,		0x00008000		# bsun exception mask
    482  1.1.6.2  bouyer set snan_mask,		0x00004000		# snan exception mask
    483  1.1.6.2  bouyer set operr_mask,		0x00002000		# operr exception mask
    484  1.1.6.2  bouyer set ovfl_mask,		0x00001000		# overflow exception mask
    485  1.1.6.2  bouyer set unfl_mask,		0x00000800		# underflow exception mask
    486  1.1.6.2  bouyer set dz_mask,		0x00000400		# dz exception mask
    487  1.1.6.2  bouyer set inex2_mask,		0x00000200		# inex2 exception mask
    488  1.1.6.2  bouyer set inex1_mask,		0x00000100		# inex1 exception mask
    489  1.1.6.2  bouyer 
    490  1.1.6.2  bouyer set aiop_mask,		0x00000080		# accrued illegal operation
    491  1.1.6.2  bouyer set aovfl_mask,		0x00000040		# accrued overflow
    492  1.1.6.2  bouyer set aunfl_mask,		0x00000020		# accrued underflow
    493  1.1.6.2  bouyer set adz_mask,		0x00000010		# accrued divide by zero
    494  1.1.6.2  bouyer set ainex_mask,		0x00000008		# accrued inexact
    495  1.1.6.2  bouyer 
    496  1.1.6.2  bouyer ######################################
    497  1.1.6.2  bouyer # FPSR combinations used in the FPSP #
    498  1.1.6.2  bouyer ######################################
    499  1.1.6.2  bouyer set dzinf_mask,		inf_mask+dz_mask+adz_mask
    500  1.1.6.2  bouyer set opnan_mask,		nan_mask+operr_mask+aiop_mask
    501  1.1.6.2  bouyer set nzi_mask,		0x01ffffff 		#clears N, Z, and I
    502  1.1.6.2  bouyer set unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
    503  1.1.6.2  bouyer set unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
    504  1.1.6.2  bouyer set ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
    505  1.1.6.2  bouyer set inx1a_mask,		inex1_mask+ainex_mask
    506  1.1.6.2  bouyer set inx2a_mask,		inex2_mask+ainex_mask
    507  1.1.6.2  bouyer set snaniop_mask, 	nan_mask+snan_mask+aiop_mask
    508  1.1.6.2  bouyer set snaniop2_mask,	snan_mask+aiop_mask
    509  1.1.6.2  bouyer set naniop_mask,	nan_mask+aiop_mask
    510  1.1.6.2  bouyer set neginf_mask,	neg_mask+inf_mask
    511  1.1.6.2  bouyer set infaiop_mask, 	inf_mask+aiop_mask
    512  1.1.6.2  bouyer set negz_mask,		neg_mask+z_mask
    513  1.1.6.2  bouyer set opaop_mask,		operr_mask+aiop_mask
    514  1.1.6.2  bouyer set unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
    515  1.1.6.2  bouyer set ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
    516  1.1.6.2  bouyer 
    517  1.1.6.2  bouyer #########
    518  1.1.6.2  bouyer # misc. #
    519  1.1.6.2  bouyer #########
    520  1.1.6.2  bouyer set rnd_stky_bit,	29			# stky bit pos in longword
    521  1.1.6.2  bouyer 
    522  1.1.6.2  bouyer set sign_bit,		0x7			# sign bit
    523  1.1.6.2  bouyer set signan_bit,		0x6			# signalling nan bit
    524  1.1.6.2  bouyer 
    525  1.1.6.2  bouyer set sgl_thresh,		0x3f81			# minimum sgl exponent
    526  1.1.6.2  bouyer set dbl_thresh,		0x3c01			# minimum dbl exponent
    527  1.1.6.2  bouyer 
    528  1.1.6.2  bouyer set x_mode,		0x0			# extended precision
    529  1.1.6.2  bouyer set s_mode,		0x4			# single precision
    530  1.1.6.2  bouyer set d_mode,		0x8			# double precision
    531  1.1.6.2  bouyer 
    532  1.1.6.2  bouyer set rn_mode,		0x0			# round-to-nearest
    533  1.1.6.2  bouyer set rz_mode,		0x1			# round-to-zero
    534  1.1.6.2  bouyer set rm_mode,		0x2			# round-tp-minus-infinity
    535  1.1.6.2  bouyer set rp_mode,		0x3			# round-to-plus-infinity
    536  1.1.6.2  bouyer 
    537  1.1.6.2  bouyer set mantissalen,	64			# length of mantissa in bits
    538  1.1.6.2  bouyer 
    539  1.1.6.2  bouyer set BYTE,		1			# len(byte) == 1 byte
    540  1.1.6.2  bouyer set WORD, 		2			# len(word) == 2 bytes
    541  1.1.6.2  bouyer set LONG, 		4			# len(longword) == 2 bytes
    542  1.1.6.2  bouyer 
    543  1.1.6.2  bouyer set BSUN_VEC,		0xc0			# bsun    vector offset
    544  1.1.6.2  bouyer set INEX_VEC,		0xc4			# inexact vector offset
    545  1.1.6.2  bouyer set DZ_VEC,		0xc8			# dz      vector offset
    546  1.1.6.2  bouyer set UNFL_VEC,		0xcc			# unfl    vector offset
    547  1.1.6.2  bouyer set OPERR_VEC,		0xd0			# operr   vector offset
    548  1.1.6.2  bouyer set OVFL_VEC,		0xd4			# ovfl    vector offset
    549  1.1.6.2  bouyer set SNAN_VEC,		0xd8			# snan    vector offset
    550  1.1.6.2  bouyer 
    551  1.1.6.2  bouyer ###########################
    552  1.1.6.2  bouyer # SPecial CONDition FLaGs #
    553  1.1.6.2  bouyer ###########################
    554  1.1.6.2  bouyer set ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
    555  1.1.6.2  bouyer set fbsun_flg,		0x02			# flag bit: bsun exception
    556  1.1.6.2  bouyer set mia7_flg,		0x04			# flag bit: (a7)+ <ea>
    557  1.1.6.2  bouyer set mda7_flg,		0x08			# flag bit: -(a7) <ea>
    558  1.1.6.2  bouyer set fmovm_flg,		0x40			# flag bit: fmovm instruction
    559  1.1.6.2  bouyer set immed_flg,		0x80			# flag bit: &<data> <ea>
    560  1.1.6.2  bouyer 
    561  1.1.6.2  bouyer set ftrapcc_bit,	0x0
    562  1.1.6.2  bouyer set fbsun_bit,		0x1
    563  1.1.6.2  bouyer set mia7_bit,		0x2
    564  1.1.6.2  bouyer set mda7_bit,		0x3
    565  1.1.6.2  bouyer set immed_bit,		0x7
    566  1.1.6.2  bouyer 
    567  1.1.6.2  bouyer ##################################
    568  1.1.6.2  bouyer # TRANSCENDENTAL "LAST-OP" FLAGS #
    569  1.1.6.2  bouyer ##################################
    570  1.1.6.2  bouyer set FMUL_OP,		0x0			# fmul instr performed last
    571  1.1.6.2  bouyer set FDIV_OP,		0x1			# fdiv performed last
    572  1.1.6.2  bouyer set FADD_OP,		0x2			# fadd performed last
    573  1.1.6.2  bouyer set FMOV_OP,		0x3			# fmov performed last
    574  1.1.6.2  bouyer 
    575  1.1.6.2  bouyer #############
    576  1.1.6.2  bouyer # CONSTANTS #
    577  1.1.6.2  bouyer #############
    578  1.1.6.2  bouyer T1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
    579  1.1.6.2  bouyer T2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
    580  1.1.6.2  bouyer 
    581  1.1.6.2  bouyer PI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
    582  1.1.6.2  bouyer PIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
    583  1.1.6.2  bouyer 
    584  1.1.6.2  bouyer TWOBYPI:
    585  1.1.6.2  bouyer 	long		0x3FE45F30,0x6DC9C883
    586  1.1.6.2  bouyer 
    587  1.1.6.2  bouyer #########################################################################
    588  1.1.6.2  bouyer # XDEF ****************************************************************	#
    589  1.1.6.2  bouyer #	_fpsp_ovfl(): 060FPSP entry point for FP Overflow exception.	#
    590  1.1.6.2  bouyer #									#
    591  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
    592  1.1.6.2  bouyer #	FP Overflow exception in an operating system.			#
    593  1.1.6.2  bouyer #									#
    594  1.1.6.2  bouyer # XREF ****************************************************************	#
    595  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword			#
    596  1.1.6.2  bouyer #	fix_skewed_ops() - adjust src operand in fsave frame		#
    597  1.1.6.2  bouyer #	set_tag_x() - determine optype of src/dst operands		#
    598  1.1.6.2  bouyer #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
    599  1.1.6.2  bouyer #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
    600  1.1.6.2  bouyer #	load_fpn2() - load dst operand from FP regfile			#
    601  1.1.6.2  bouyer #	fout() - emulate an opclass 3 instruction			#
    602  1.1.6.2  bouyer #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
    603  1.1.6.2  bouyer #	_fpsp_done() - "callout" for 060FPSP exit (all work done!)	#
    604  1.1.6.2  bouyer #	_real_ovfl() - "callout" for Overflow exception enabled code	#
    605  1.1.6.2  bouyer #	_real_inex() - "callout" for Inexact exception enabled code	#
    606  1.1.6.2  bouyer #	_real_trace() - "callout" for Trace exception code		#
    607  1.1.6.2  bouyer #									#
    608  1.1.6.2  bouyer # INPUT ***************************************************************	#
    609  1.1.6.2  bouyer #	- The system stack contains the FP Ovfl exception stack frame	#
    610  1.1.6.2  bouyer #	- The fsave frame contains the source operand			#
    611  1.1.6.2  bouyer # 									#
    612  1.1.6.2  bouyer # OUTPUT **************************************************************	#
    613  1.1.6.2  bouyer #	Overflow Exception enabled:					#
    614  1.1.6.2  bouyer #	- The system stack is unchanged					#
    615  1.1.6.2  bouyer #	- The fsave frame contains the adjusted src op for opclass 0,2	#
    616  1.1.6.2  bouyer #	Overflow Exception disabled:					#
    617  1.1.6.2  bouyer #	- The system stack is unchanged					#
    618  1.1.6.2  bouyer #	- The "exception present" flag in the fsave frame is cleared	#
    619  1.1.6.2  bouyer #									#
    620  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
    621  1.1.6.2  bouyer #	On the 060, if an FP overflow is present as the result of any	#
    622  1.1.6.2  bouyer # instruction, the 060 will take an overflow exception whether the 	#
    623  1.1.6.2  bouyer # exception is enabled or disabled in the FPCR. For the disabled case, 	#
    624  1.1.6.2  bouyer # This handler emulates the instruction to determine what the correct	#
    625  1.1.6.2  bouyer # default result should be for the operation. This default result is	#
    626  1.1.6.2  bouyer # then stored in either the FP regfile, data regfile, or memory. 	#
    627  1.1.6.2  bouyer # Finally, the handler exits through the "callout" _fpsp_done() 	#
    628  1.1.6.2  bouyer # denoting that no exceptional conditions exist within the machine.	#
    629  1.1.6.2  bouyer # 	If the exception is enabled, then this handler must create the	#
    630  1.1.6.2  bouyer # exceptional operand and plave it in the fsave state frame, and store	#
    631  1.1.6.2  bouyer # the default result (only if the instruction is opclass 3). For 	#
    632  1.1.6.2  bouyer # exceptions enabled, this handler must exit through the "callout" 	#
    633  1.1.6.2  bouyer # _real_ovfl() so that the operating system enabled overflow handler	#
    634  1.1.6.2  bouyer # can handle this case.							#
    635  1.1.6.2  bouyer #	Two other conditions exist. First, if overflow was disabled 	#
    636  1.1.6.2  bouyer # but the inexact exception was enabled, this handler must exit 	#
    637  1.1.6.2  bouyer # through the "callout" _real_inex() regardless of whether the result	#
    638  1.1.6.2  bouyer # was inexact.								#
    639  1.1.6.2  bouyer #	Also, in the case of an opclass three instruction where 	#
    640  1.1.6.2  bouyer # overflow was disabled and the trace exception was enabled, this	#
    641  1.1.6.2  bouyer # handler must exit through the "callout" _real_trace().		#
    642  1.1.6.2  bouyer #									#
    643  1.1.6.2  bouyer #########################################################################
    644  1.1.6.2  bouyer 
    645  1.1.6.2  bouyer 	global		_fpsp_ovfl
    646  1.1.6.2  bouyer _fpsp_ovfl:
    647  1.1.6.2  bouyer 
    648  1.1.6.2  bouyer #$#	sub.l		&24,%sp			# make room for src/dst
    649  1.1.6.2  bouyer 
    650  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
    651  1.1.6.2  bouyer 
    652  1.1.6.2  bouyer 	fsave		FP_SRC(%a6)		# grab the "busy" frame
    653  1.1.6.2  bouyer 
    654  1.1.6.2  bouyer  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    655  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
    656  1.1.6.2  bouyer  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
    657  1.1.6.2  bouyer 
    658  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction
    659  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
    660  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
    661  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
    662  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
    663  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)
    664  1.1.6.2  bouyer 
    665  1.1.6.2  bouyer ##############################################################################
    666  1.1.6.2  bouyer 
    667  1.1.6.2  bouyer 	btst		&0x5,EXC_CMDREG(%a6)	# is instr an fmove out?
    668  1.1.6.2  bouyer 	bne.w		fovfl_out
    669  1.1.6.2  bouyer 
    670  1.1.6.2  bouyer 
    671  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    672  1.1.6.2  bouyer 	bsr.l		fix_skewed_ops		# fix src op
    673  1.1.6.2  bouyer 
    674  1.1.6.2  bouyer # since, I believe, only NORMs and DENORMs can come through here,
    675  1.1.6.2  bouyer # maybe we can avoid the subroutine call.
    676  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    677  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
    678  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
    679  1.1.6.2  bouyer 
    680  1.1.6.2  bouyer # bit five of the fp extension word separates the monadic and dyadic operations
    681  1.1.6.2  bouyer # that can pass through fpsp_ovfl(). remember that fcmp, ftst, and fsincos
    682  1.1.6.2  bouyer # will never take this exception.
    683  1.1.6.2  bouyer 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
    684  1.1.6.2  bouyer 	beq.b		fovfl_extract		# monadic
    685  1.1.6.2  bouyer 
    686  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
    687  1.1.6.2  bouyer 	bsr.l		load_fpn2		# load dst into FP_DST
    688  1.1.6.2  bouyer 
    689  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
    690  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
    691  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
    692  1.1.6.2  bouyer 	bne.b		fovfl_op2_done		# no
    693  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
    694  1.1.6.2  bouyer fovfl_op2_done:
    695  1.1.6.2  bouyer 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
    696  1.1.6.2  bouyer 
    697  1.1.6.2  bouyer fovfl_extract:
    698  1.1.6.2  bouyer 
    699  1.1.6.2  bouyer #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
    700  1.1.6.2  bouyer #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
    701  1.1.6.2  bouyer #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
    702  1.1.6.2  bouyer #$#	mov.l		FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
    703  1.1.6.2  bouyer #$#	mov.l		FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
    704  1.1.6.2  bouyer #$#	mov.l		FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
    705  1.1.6.2  bouyer 
    706  1.1.6.2  bouyer 	clr.l		%d0
    707  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
    708  1.1.6.2  bouyer 
    709  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1
    710  1.1.6.2  bouyer 	andi.w		&0x007f,%d1		# extract extension
    711  1.1.6.2  bouyer 
    712  1.1.6.2  bouyer 	andi.l		&0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
    713  1.1.6.2  bouyer 
    714  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
    715  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
    716  1.1.6.2  bouyer 
    717  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
    718  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1
    719  1.1.6.2  bouyer 
    720  1.1.6.2  bouyer # maybe we can make these entry points ONLY the OVFL entry points of each routine.
    721  1.1.6.2  bouyer 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
    722  1.1.6.2  bouyer 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
    723  1.1.6.2  bouyer 
    724  1.1.6.2  bouyer # the operation has been emulated. the result is in fp0.
    725  1.1.6.2  bouyer # the EXOP, if an exception occurred, is in fp1.
    726  1.1.6.2  bouyer # we must save the default result regardless of whether
    727  1.1.6.2  bouyer # traps are enabled or disabled.
    728  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
    729  1.1.6.2  bouyer 	bsr.l		store_fpreg
    730  1.1.6.2  bouyer 
    731  1.1.6.2  bouyer # the exceptional possibilities we have left ourselves with are ONLY overflow
    732  1.1.6.2  bouyer # and inexact. and, the inexact is such that overflow occurred and was disabled
    733  1.1.6.2  bouyer # but inexact was enabled.
    734  1.1.6.2  bouyer 	btst		&ovfl_bit,FPCR_ENABLE(%a6)
    735  1.1.6.2  bouyer 	bne.b		fovfl_ovfl_on
    736  1.1.6.2  bouyer 
    737  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6)
    738  1.1.6.2  bouyer 	bne.b		fovfl_inex_on
    739  1.1.6.2  bouyer 
    740  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    741  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    742  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    743  1.1.6.2  bouyer 
    744  1.1.6.2  bouyer 	unlk		%a6
    745  1.1.6.2  bouyer #$#	add.l		&24,%sp
    746  1.1.6.2  bouyer 	bra.l		_fpsp_done
    747  1.1.6.2  bouyer 
    748  1.1.6.2  bouyer # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
    749  1.1.6.2  bouyer # in fp1. now, simply jump to _real_ovfl()!
    750  1.1.6.2  bouyer fovfl_ovfl_on:
    751  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP (fp1) to stack
    752  1.1.6.2  bouyer 
    753  1.1.6.2  bouyer 	mov.w		&0xe005,2+FP_SRC(%a6) 	# save exc status
    754  1.1.6.2  bouyer 
    755  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    756  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    757  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    758  1.1.6.2  bouyer 
    759  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
    760  1.1.6.2  bouyer 
    761  1.1.6.2  bouyer 	unlk		%a6
    762  1.1.6.2  bouyer 
    763  1.1.6.2  bouyer 	bra.l		_real_ovfl
    764  1.1.6.2  bouyer 
    765  1.1.6.2  bouyer # overflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
    766  1.1.6.2  bouyer # we must jump to real_inex().
    767  1.1.6.2  bouyer fovfl_inex_on:
    768  1.1.6.2  bouyer 
    769  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SRC(%a6) 	# save EXOP (fp1) to stack
    770  1.1.6.2  bouyer 
    771  1.1.6.2  bouyer 	mov.b		&0xc4,1+EXC_VOFF(%a6)	# vector offset = 0xc4
    772  1.1.6.2  bouyer 	mov.w		&0xe001,2+FP_SRC(%a6) 	# save exc status
    773  1.1.6.2  bouyer 
    774  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    775  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    776  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    777  1.1.6.2  bouyer 
    778  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
    779  1.1.6.2  bouyer 
    780  1.1.6.2  bouyer 	unlk		%a6
    781  1.1.6.2  bouyer 
    782  1.1.6.2  bouyer 	bra.l		_real_inex
    783  1.1.6.2  bouyer 
    784  1.1.6.2  bouyer ########################################################################
    785  1.1.6.2  bouyer fovfl_out:
    786  1.1.6.2  bouyer 
    787  1.1.6.2  bouyer 
    788  1.1.6.2  bouyer #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
    789  1.1.6.2  bouyer #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
    790  1.1.6.2  bouyer #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
    791  1.1.6.2  bouyer 
    792  1.1.6.2  bouyer # the src operand is definitely a NORM(!), so tag it as such
    793  1.1.6.2  bouyer 	mov.b		&NORM,STAG(%a6)		# set src optype tag
    794  1.1.6.2  bouyer 
    795  1.1.6.2  bouyer 	clr.l		%d0
    796  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
    797  1.1.6.2  bouyer 
    798  1.1.6.2  bouyer 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero all but accured field
    799  1.1.6.2  bouyer 
    800  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
    801  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
    802  1.1.6.2  bouyer 
    803  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
    804  1.1.6.2  bouyer 
    805  1.1.6.2  bouyer 	bsr.l		fout
    806  1.1.6.2  bouyer 
    807  1.1.6.2  bouyer 	btst		&ovfl_bit,FPCR_ENABLE(%a6)
    808  1.1.6.2  bouyer 	bne.w		fovfl_ovfl_on
    809  1.1.6.2  bouyer 
    810  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6)
    811  1.1.6.2  bouyer 	bne.w		fovfl_inex_on
    812  1.1.6.2  bouyer 
    813  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    814  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    815  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    816  1.1.6.2  bouyer 
    817  1.1.6.2  bouyer 	unlk		%a6
    818  1.1.6.2  bouyer #$#	add.l		&24,%sp
    819  1.1.6.2  bouyer 
    820  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
    821  1.1.6.2  bouyer 	beq.l		_fpsp_done		# no
    822  1.1.6.2  bouyer 
    823  1.1.6.2  bouyer 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
    824  1.1.6.2  bouyer 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
    825  1.1.6.2  bouyer 	bra.l		_real_trace
    826  1.1.6.2  bouyer 
    827  1.1.6.2  bouyer #########################################################################
    828  1.1.6.2  bouyer # XDEF ****************************************************************	#
    829  1.1.6.2  bouyer #	_fpsp_unfl(): 060FPSP entry point for FP Underflow exception.	#
    830  1.1.6.2  bouyer #									#
    831  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
    832  1.1.6.2  bouyer #	FP Underflow exception in an operating system.			#
    833  1.1.6.2  bouyer #									#
    834  1.1.6.2  bouyer # XREF ****************************************************************	#
    835  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword			#
    836  1.1.6.2  bouyer #	fix_skewed_ops() - adjust src operand in fsave frame		#
    837  1.1.6.2  bouyer #	set_tag_x() - determine optype of src/dst operands		#
    838  1.1.6.2  bouyer #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
    839  1.1.6.2  bouyer #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
    840  1.1.6.2  bouyer #	load_fpn2() - load dst operand from FP regfile			#
    841  1.1.6.2  bouyer #	fout() - emulate an opclass 3 instruction			#
    842  1.1.6.2  bouyer #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
    843  1.1.6.2  bouyer #	_fpsp_done() - "callout" for 060FPSP exit (all work done!)	#
    844  1.1.6.2  bouyer #	_real_ovfl() - "callout" for Overflow exception enabled code	#
    845  1.1.6.2  bouyer #	_real_inex() - "callout" for Inexact exception enabled code	#
    846  1.1.6.2  bouyer #	_real_trace() - "callout" for Trace exception code		#
    847  1.1.6.2  bouyer #									#
    848  1.1.6.2  bouyer # INPUT ***************************************************************	#
    849  1.1.6.2  bouyer #	- The system stack contains the FP Unfl exception stack frame	#
    850  1.1.6.2  bouyer #	- The fsave frame contains the source operand			#
    851  1.1.6.2  bouyer # 									#
    852  1.1.6.2  bouyer # OUTPUT **************************************************************	#
    853  1.1.6.2  bouyer #	Underflow Exception enabled:					#
    854  1.1.6.2  bouyer #	- The system stack is unchanged					#
    855  1.1.6.2  bouyer #	- The fsave frame contains the adjusted src op for opclass 0,2	#
    856  1.1.6.2  bouyer #	Underflow Exception disabled:					#
    857  1.1.6.2  bouyer #	- The system stack is unchanged					#
    858  1.1.6.2  bouyer #	- The "exception present" flag in the fsave frame is cleared	#
    859  1.1.6.2  bouyer #									#
    860  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
    861  1.1.6.2  bouyer #	On the 060, if an FP underflow is present as the result of any	#
    862  1.1.6.2  bouyer # instruction, the 060 will take an underflow exception whether the 	#
    863  1.1.6.2  bouyer # exception is enabled or disabled in the FPCR. For the disabled case, 	#
    864  1.1.6.2  bouyer # This handler emulates the instruction to determine what the correct	#
    865  1.1.6.2  bouyer # default result should be for the operation. This default result is	#
    866  1.1.6.2  bouyer # then stored in either the FP regfile, data regfile, or memory. 	#
    867  1.1.6.2  bouyer # Finally, the handler exits through the "callout" _fpsp_done() 	#
    868  1.1.6.2  bouyer # denoting that no exceptional conditions exist within the machine.	#
    869  1.1.6.2  bouyer # 	If the exception is enabled, then this handler must create the	#
    870  1.1.6.2  bouyer # exceptional operand and plave it in the fsave state frame, and store	#
    871  1.1.6.2  bouyer # the default result (only if the instruction is opclass 3). For 	#
    872  1.1.6.2  bouyer # exceptions enabled, this handler must exit through the "callout" 	#
    873  1.1.6.2  bouyer # _real_unfl() so that the operating system enabled overflow handler	#
    874  1.1.6.2  bouyer # can handle this case.							#
    875  1.1.6.2  bouyer #	Two other conditions exist. First, if underflow was disabled 	#
    876  1.1.6.2  bouyer # but the inexact exception was enabled and the result was inexact, 	#
    877  1.1.6.2  bouyer # this handler must exit through the "callout" _real_inex().		#
    878  1.1.6.2  bouyer # was inexact.								#
    879  1.1.6.2  bouyer #	Also, in the case of an opclass three instruction where 	#
    880  1.1.6.2  bouyer # underflow was disabled and the trace exception was enabled, this	#
    881  1.1.6.2  bouyer # handler must exit through the "callout" _real_trace().		#
    882  1.1.6.2  bouyer #									#
    883  1.1.6.2  bouyer #########################################################################
    884  1.1.6.2  bouyer 
    885  1.1.6.2  bouyer 	global		_fpsp_unfl
    886  1.1.6.2  bouyer _fpsp_unfl:
    887  1.1.6.2  bouyer 
    888  1.1.6.2  bouyer #$#	sub.l		&24,%sp			# make room for src/dst
    889  1.1.6.2  bouyer 
    890  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
    891  1.1.6.2  bouyer 
    892  1.1.6.2  bouyer 	fsave		FP_SRC(%a6)		# grab the "busy" frame
    893  1.1.6.2  bouyer 
    894  1.1.6.2  bouyer  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
    895  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
    896  1.1.6.2  bouyer  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
    897  1.1.6.2  bouyer 
    898  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction
    899  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
    900  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
    901  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
    902  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
    903  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)
    904  1.1.6.2  bouyer 
    905  1.1.6.2  bouyer ##############################################################################
    906  1.1.6.2  bouyer 
    907  1.1.6.2  bouyer 	btst		&0x5,EXC_CMDREG(%a6)	# is instr an fmove out?
    908  1.1.6.2  bouyer 	bne.w		funfl_out
    909  1.1.6.2  bouyer 
    910  1.1.6.2  bouyer 
    911  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    912  1.1.6.2  bouyer 	bsr.l		fix_skewed_ops		# fix src op
    913  1.1.6.2  bouyer 
    914  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
    915  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
    916  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
    917  1.1.6.2  bouyer 
    918  1.1.6.2  bouyer # bit five of the fp ext word separates the monadic and dyadic operations
    919  1.1.6.2  bouyer # that can pass through fpsp_unfl(). remember that fcmp, and ftst
    920  1.1.6.2  bouyer # will never take this exception.
    921  1.1.6.2  bouyer 	btst		&0x5,1+EXC_CMDREG(%a6)	# is op monadic or dyadic?
    922  1.1.6.2  bouyer 	beq.b		funfl_extract		# monadic
    923  1.1.6.2  bouyer 
    924  1.1.6.2  bouyer # now, what's left that's not dyadic is fsincos. we can distinguish it
    925  1.1.6.2  bouyer # from all dyadics by the '0110xxx pattern
    926  1.1.6.2  bouyer 	btst		&0x4,1+EXC_CMDREG(%a6)	# is op an fsincos?
    927  1.1.6.2  bouyer 	bne.b		funfl_extract		# yes
    928  1.1.6.2  bouyer 
    929  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
    930  1.1.6.2  bouyer 	bsr.l		load_fpn2		# load dst into FP_DST
    931  1.1.6.2  bouyer 
    932  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
    933  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
    934  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
    935  1.1.6.2  bouyer 	bne.b		funfl_op2_done		# no
    936  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
    937  1.1.6.2  bouyer funfl_op2_done:
    938  1.1.6.2  bouyer 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
    939  1.1.6.2  bouyer 
    940  1.1.6.2  bouyer funfl_extract:
    941  1.1.6.2  bouyer 
    942  1.1.6.2  bouyer #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
    943  1.1.6.2  bouyer #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
    944  1.1.6.2  bouyer #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
    945  1.1.6.2  bouyer #$#	mov.l		FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
    946  1.1.6.2  bouyer #$#	mov.l		FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
    947  1.1.6.2  bouyer #$#	mov.l		FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
    948  1.1.6.2  bouyer 
    949  1.1.6.2  bouyer 	clr.l		%d0
    950  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
    951  1.1.6.2  bouyer 
    952  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1
    953  1.1.6.2  bouyer 	andi.w		&0x007f,%d1		# extract extension
    954  1.1.6.2  bouyer 
    955  1.1.6.2  bouyer 	andi.l		&0x00ff01ff,USER_FPSR(%a6)
    956  1.1.6.2  bouyer 
    957  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
    958  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
    959  1.1.6.2  bouyer 
    960  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
    961  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1
    962  1.1.6.2  bouyer 
    963  1.1.6.2  bouyer # maybe we can make these entry points ONLY the OVFL entry points of each routine.
    964  1.1.6.2  bouyer 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
    965  1.1.6.2  bouyer 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
    966  1.1.6.2  bouyer 
    967  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
    968  1.1.6.2  bouyer 	bsr.l		store_fpreg
    969  1.1.6.2  bouyer 
    970  1.1.6.2  bouyer # The `060 FPU multiplier hardware is such that if the result of a
    971  1.1.6.2  bouyer # multiply operation is the smallest possible normalized number
    972  1.1.6.2  bouyer # (0x00000000_80000000_00000000), then the machine will take an
    973  1.1.6.2  bouyer # underflow exception. Since this is incorrect, we need to check
    974  1.1.6.2  bouyer # if our emulation, after re-doing the operation, decided that
    975  1.1.6.2  bouyer # no underflow was called for. We do these checks only in
    976  1.1.6.2  bouyer # funfl_{unfl,inex}_on() because w/ both exceptions disabled, this
    977  1.1.6.2  bouyer # special case will simply exit gracefully with the correct result.
    978  1.1.6.2  bouyer 
    979  1.1.6.2  bouyer # the exceptional possibilities we have left ourselves with are ONLY overflow
    980  1.1.6.2  bouyer # and inexact. and, the inexact is such that overflow occurred and was disabled
    981  1.1.6.2  bouyer # but inexact was enabled.
    982  1.1.6.2  bouyer 	btst		&unfl_bit,FPCR_ENABLE(%a6)
    983  1.1.6.2  bouyer 	bne.b		funfl_unfl_on
    984  1.1.6.2  bouyer 
    985  1.1.6.2  bouyer funfl_chkinex:
    986  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6)
    987  1.1.6.2  bouyer 	bne.b		funfl_inex_on
    988  1.1.6.2  bouyer 
    989  1.1.6.2  bouyer funfl_exit:
    990  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
    991  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
    992  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
    993  1.1.6.2  bouyer 
    994  1.1.6.2  bouyer 	unlk		%a6
    995  1.1.6.2  bouyer #$#	add.l		&24,%sp
    996  1.1.6.2  bouyer 	bra.l		_fpsp_done
    997  1.1.6.2  bouyer 
    998  1.1.6.2  bouyer # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
    999  1.1.6.2  bouyer # in fp1 (don't forget to save fp0). what to do now?
   1000  1.1.6.2  bouyer # well, we simply have to get to go to _real_unfl()!
   1001  1.1.6.2  bouyer funfl_unfl_on:
   1002  1.1.6.2  bouyer 
   1003  1.1.6.2  bouyer # The `060 FPU multiplier hardware is such that if the result of a
   1004  1.1.6.2  bouyer # multiply operation is the smallest possible normalized number
   1005  1.1.6.2  bouyer # (0x00000000_80000000_00000000), then the machine will take an
   1006  1.1.6.2  bouyer # underflow exception. Since this is incorrect, we check here to see
   1007  1.1.6.2  bouyer # if our emulation, after re-doing the operation, decided that
   1008  1.1.6.2  bouyer # no underflow was called for.
   1009  1.1.6.2  bouyer 	btst		&unfl_bit,FPSR_EXCEPT(%a6)
   1010  1.1.6.2  bouyer 	beq.w		funfl_chkinex
   1011  1.1.6.2  bouyer 
   1012  1.1.6.2  bouyer funfl_unfl_on2:
   1013  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP (fp1) to stack
   1014  1.1.6.2  bouyer 
   1015  1.1.6.2  bouyer 	mov.w		&0xe003,2+FP_SRC(%a6) 	# save exc status
   1016  1.1.6.2  bouyer 
   1017  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   1018  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1019  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1020  1.1.6.2  bouyer 
   1021  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
   1022  1.1.6.2  bouyer 
   1023  1.1.6.2  bouyer 	unlk		%a6
   1024  1.1.6.2  bouyer 
   1025  1.1.6.2  bouyer 	bra.l		_real_unfl
   1026  1.1.6.2  bouyer 
   1027  1.1.6.2  bouyer # undeflow occurred but is disabled. meanwhile, inexact is enabled. therefore,
   1028  1.1.6.2  bouyer # we must jump to real_inex().
   1029  1.1.6.2  bouyer funfl_inex_on:
   1030  1.1.6.2  bouyer 
   1031  1.1.6.2  bouyer # The `060 FPU multiplier hardware is such that if the result of a
   1032  1.1.6.2  bouyer # multiply operation is the smallest possible normalized number
   1033  1.1.6.2  bouyer # (0x00000000_80000000_00000000), then the machine will take an
   1034  1.1.6.2  bouyer # underflow exception.
   1035  1.1.6.2  bouyer # But, whether bogus or not, if inexact is enabled AND it occurred,
   1036  1.1.6.2  bouyer # then we have to branch to real_inex.
   1037  1.1.6.2  bouyer 
   1038  1.1.6.2  bouyer 	btst		&inex2_bit,FPSR_EXCEPT(%a6)
   1039  1.1.6.2  bouyer 	beq.w		funfl_exit
   1040  1.1.6.2  bouyer 
   1041  1.1.6.2  bouyer funfl_inex_on2:
   1042  1.1.6.2  bouyer 
   1043  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SRC(%a6) 	# save EXOP to stack
   1044  1.1.6.2  bouyer 
   1045  1.1.6.2  bouyer 	mov.b		&0xc4,1+EXC_VOFF(%a6)	# vector offset = 0xc4
   1046  1.1.6.2  bouyer 	mov.w		&0xe001,2+FP_SRC(%a6) 	# save exc status
   1047  1.1.6.2  bouyer 
   1048  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   1049  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1050  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1051  1.1.6.2  bouyer 
   1052  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
   1053  1.1.6.2  bouyer 
   1054  1.1.6.2  bouyer 	unlk		%a6
   1055  1.1.6.2  bouyer 
   1056  1.1.6.2  bouyer 	bra.l		_real_inex
   1057  1.1.6.2  bouyer 
   1058  1.1.6.2  bouyer #######################################################################
   1059  1.1.6.2  bouyer funfl_out:
   1060  1.1.6.2  bouyer 
   1061  1.1.6.2  bouyer 
   1062  1.1.6.2  bouyer #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
   1063  1.1.6.2  bouyer #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
   1064  1.1.6.2  bouyer #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
   1065  1.1.6.2  bouyer 
   1066  1.1.6.2  bouyer # the src operand is definitely a NORM(!), so tag it as such
   1067  1.1.6.2  bouyer 	mov.b		&NORM,STAG(%a6)		# set src optype tag
   1068  1.1.6.2  bouyer 
   1069  1.1.6.2  bouyer 	clr.l		%d0
   1070  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
   1071  1.1.6.2  bouyer 
   1072  1.1.6.2  bouyer 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero all but accured field
   1073  1.1.6.2  bouyer 
   1074  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
   1075  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   1076  1.1.6.2  bouyer 
   1077  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   1078  1.1.6.2  bouyer 
   1079  1.1.6.2  bouyer 	bsr.l		fout
   1080  1.1.6.2  bouyer 
   1081  1.1.6.2  bouyer 	btst		&unfl_bit,FPCR_ENABLE(%a6)
   1082  1.1.6.2  bouyer 	bne.w		funfl_unfl_on2
   1083  1.1.6.2  bouyer 
   1084  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6)
   1085  1.1.6.2  bouyer 	bne.w		funfl_inex_on2
   1086  1.1.6.2  bouyer 
   1087  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   1088  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1089  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1090  1.1.6.2  bouyer 
   1091  1.1.6.2  bouyer 	unlk		%a6
   1092  1.1.6.2  bouyer #$#	add.l		&24,%sp
   1093  1.1.6.2  bouyer 
   1094  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   1095  1.1.6.2  bouyer 	beq.l		_fpsp_done		# no
   1096  1.1.6.2  bouyer 
   1097  1.1.6.2  bouyer 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
   1098  1.1.6.2  bouyer 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
   1099  1.1.6.2  bouyer 	bra.l		_real_trace
   1100  1.1.6.2  bouyer 
   1101  1.1.6.2  bouyer #########################################################################
   1102  1.1.6.2  bouyer # XDEF ****************************************************************	#
   1103  1.1.6.2  bouyer #	_fpsp_unsupp(): 060FPSP entry point for FP "Unimplemented	#
   1104  1.1.6.2  bouyer #		        Data Type" exception.				#
   1105  1.1.6.2  bouyer #									#
   1106  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
   1107  1.1.6.2  bouyer #	FP Unimplemented Data Type exception in an operating system.	#
   1108  1.1.6.2  bouyer #									#
   1109  1.1.6.2  bouyer # XREF ****************************************************************	#
   1110  1.1.6.2  bouyer #	_imem_read_{word,long}() - read instruction word/longword	#
   1111  1.1.6.2  bouyer #	fix_skewed_ops() - adjust src operand in fsave frame		#
   1112  1.1.6.2  bouyer #	set_tag_x() - determine optype of src/dst operands		#
   1113  1.1.6.2  bouyer #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   1114  1.1.6.2  bouyer #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
   1115  1.1.6.2  bouyer #	load_fpn2() - load dst operand from FP regfile			#
   1116  1.1.6.2  bouyer #	load_fpn1() - load src operand from FP regfile			#
   1117  1.1.6.2  bouyer #	fout() - emulate an opclass 3 instruction			#
   1118  1.1.6.2  bouyer #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
   1119  1.1.6.2  bouyer #	_real_inex() - "callout" to operating system inexact handler	#
   1120  1.1.6.2  bouyer #	_fpsp_done() - "callout" for exit; work all done		#
   1121  1.1.6.2  bouyer #	_real_trace() - "callout" for Trace enabled exception		#
   1122  1.1.6.2  bouyer #	funimp_skew() - adjust fsave src ops to "incorrect" value	#
   1123  1.1.6.2  bouyer #	_real_snan() - "callout" for SNAN exception			#
   1124  1.1.6.2  bouyer #	_real_operr() - "callout" for OPERR exception			#
   1125  1.1.6.2  bouyer #	_real_ovfl() - "callout" for OVFL exception			#
   1126  1.1.6.2  bouyer #	_real_unfl() - "callout" for UNFL exception			#
   1127  1.1.6.2  bouyer #	get_packed() - fetch packed operand from memory			#
   1128  1.1.6.2  bouyer #									#
   1129  1.1.6.2  bouyer # INPUT ***************************************************************	#
   1130  1.1.6.2  bouyer #	- The system stack contains the "Unimp Data Type" stk frame	#
   1131  1.1.6.2  bouyer #	- The fsave frame contains the ssrc op (for UNNORM/DENORM)	#
   1132  1.1.6.2  bouyer # 									#
   1133  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   1134  1.1.6.2  bouyer #	If Inexact exception (opclass 3):				#
   1135  1.1.6.2  bouyer #	- The system stack is changed to an Inexact exception stk frame	#
   1136  1.1.6.2  bouyer #	If SNAN exception (opclass 3):					#
   1137  1.1.6.2  bouyer #	- The system stack is changed to an SNAN exception stk frame	#
   1138  1.1.6.2  bouyer #	If OPERR exception (opclass 3):					#
   1139  1.1.6.2  bouyer #	- The system stack is changed to an OPERR exception stk frame	#
   1140  1.1.6.2  bouyer #	If OVFL exception (opclass 3):					#
   1141  1.1.6.2  bouyer #	- The system stack is changed to an OVFL exception stk frame	#
   1142  1.1.6.2  bouyer #	If UNFL exception (opclass 3):					#
   1143  1.1.6.2  bouyer #	- The system stack is changed to an UNFL exception stack frame	#
   1144  1.1.6.2  bouyer #	If Trace exception enabled:					#
   1145  1.1.6.2  bouyer #	- The system stack is changed to a Trace exception stack frame	#
   1146  1.1.6.2  bouyer #	Else: (normal case)						#
   1147  1.1.6.2  bouyer #	- Correct result has been stored as appropriate			#
   1148  1.1.6.2  bouyer #									#
   1149  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   1150  1.1.6.2  bouyer #	Two main instruction types can enter here: (1) DENORM or UNNORM	#
   1151  1.1.6.2  bouyer # unimplemented data types. These can be either opclass 0,2 or 3 	#
   1152  1.1.6.2  bouyer # instructions, and (2) PACKED unimplemented data format instructions	#
   1153  1.1.6.2  bouyer # also of opclasses 0,2, or 3.						#
   1154  1.1.6.2  bouyer #	For UNNORM/DENORM opclass 0 and 2, the handler fetches the src	#
   1155  1.1.6.2  bouyer # operand from the fsave state frame and the dst operand (if dyadic)	#
   1156  1.1.6.2  bouyer # from the FP register file. The instruction is then emulated by 	#
   1157  1.1.6.2  bouyer # choosing an emulation routine from a table of routines indexed by	#
   1158  1.1.6.2  bouyer # instruction type. Once the instruction has been emulated and result	#
   1159  1.1.6.2  bouyer # saved, then we check to see if any enabled exceptions resulted from	#
   1160  1.1.6.2  bouyer # instruction emulation. If none, then we exit through the "callout"	#
   1161  1.1.6.2  bouyer # _fpsp_done(). If there is an enabled FP exception, then we insert	#
   1162  1.1.6.2  bouyer # this exception into the FPU in the fsave state frame and then exit	#
   1163  1.1.6.2  bouyer # through _fpsp_done().							#
   1164  1.1.6.2  bouyer #	PACKED opclass 0 and 2 is similar in how the instruction is	#
   1165  1.1.6.2  bouyer # emulated and exceptions handled. The differences occur in how the	#
   1166  1.1.6.2  bouyer # handler loads the packed op (by calling get_packed() routine) and	#
   1167  1.1.6.2  bouyer # by the fact that a Trace exception could be pending for PACKED ops.	#
   1168  1.1.6.2  bouyer # If a Trace exception is pending, then the current exception stack	#
   1169  1.1.6.2  bouyer # frame is changed to a Trace exception stack frame and an exit is	#
   1170  1.1.6.2  bouyer # made through _real_trace().						#
   1171  1.1.6.2  bouyer #	For UNNORM/DENORM opclass 3, the actual move out to memory is	#
   1172  1.1.6.2  bouyer # performed by calling the routine fout(). If no exception should occur	#
   1173  1.1.6.2  bouyer # as the result of emulation, then an exit either occurs through	#
   1174  1.1.6.2  bouyer # _fpsp_done() or through _real_trace() if a Trace exception is pending	#
   1175  1.1.6.2  bouyer # (a Trace stack frame must be created here, too). If an FP exception	#
   1176  1.1.6.2  bouyer # should occur, then we must create an exception stack frame of that	#
   1177  1.1.6.2  bouyer # type and jump to either _real_snan(), _real_operr(), _real_inex(),	#
   1178  1.1.6.2  bouyer # _real_unfl(), or _real_ovfl() as appropriate. PACKED opclass 3 	#
   1179  1.1.6.2  bouyer # emulation is performed in a similar manner.				#
   1180  1.1.6.2  bouyer #									#
   1181  1.1.6.2  bouyer #########################################################################
   1182  1.1.6.2  bouyer 
   1183  1.1.6.2  bouyer #
   1184  1.1.6.2  bouyer # (1) DENORM and UNNORM (unimplemented) data types:
   1185  1.1.6.2  bouyer #
   1186  1.1.6.2  bouyer #				post-instruction
   1187  1.1.6.2  bouyer #				*****************
   1188  1.1.6.2  bouyer #				*      EA	*
   1189  1.1.6.2  bouyer #	 pre-instruction	*		*
   1190  1.1.6.2  bouyer # 	*****************	*****************
   1191  1.1.6.2  bouyer #	* 0x0 *  0x0dc  *	* 0x3 *  0x0dc  *
   1192  1.1.6.2  bouyer #	*****************	*****************
   1193  1.1.6.2  bouyer #	*     Next	*	*     Next	*
   1194  1.1.6.2  bouyer #	*      PC	*	*      PC	*
   1195  1.1.6.2  bouyer #	*****************	*****************
   1196  1.1.6.2  bouyer #	*      SR	*	*      SR	*
   1197  1.1.6.2  bouyer #	*****************	*****************
   1198  1.1.6.2  bouyer #
   1199  1.1.6.2  bouyer # (2) PACKED format (unsupported) opclasses two and three:
   1200  1.1.6.2  bouyer #	*****************
   1201  1.1.6.2  bouyer #	*      EA	*
   1202  1.1.6.2  bouyer #	*		*
   1203  1.1.6.2  bouyer #	*****************
   1204  1.1.6.2  bouyer #	* 0x2 *  0x0dc	*
   1205  1.1.6.2  bouyer #	*****************
   1206  1.1.6.2  bouyer #	*     Next	*
   1207  1.1.6.2  bouyer #	*      PC	*
   1208  1.1.6.2  bouyer #	*****************
   1209  1.1.6.2  bouyer #	*      SR	*
   1210  1.1.6.2  bouyer #	*****************
   1211  1.1.6.2  bouyer #
   1212  1.1.6.2  bouyer 	global		_fpsp_unsupp
   1213  1.1.6.2  bouyer _fpsp_unsupp:
   1214  1.1.6.2  bouyer 
   1215  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   1216  1.1.6.2  bouyer 
   1217  1.1.6.2  bouyer 	fsave		FP_SRC(%a6)		# save fp state
   1218  1.1.6.2  bouyer 
   1219  1.1.6.2  bouyer  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   1220  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   1221  1.1.6.2  bouyer  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   1222  1.1.6.2  bouyer 
   1223  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode?
   1224  1.1.6.2  bouyer 	bne.b		fu_s
   1225  1.1.6.2  bouyer fu_u:
   1226  1.1.6.2  bouyer 	mov.l		%usp,%a0		# fetch user stack pointer
   1227  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)		# save on stack
   1228  1.1.6.2  bouyer 	bra.b		fu_cont
   1229  1.1.6.2  bouyer # if the exception is an opclass zero or two unimplemented data type
   1230  1.1.6.2  bouyer # exception, then the a7' calculated here is wrong since it doesn't
   1231  1.1.6.2  bouyer # stack an ea. however, we don't need an a7' for this case anyways.
   1232  1.1.6.2  bouyer fu_s:
   1233  1.1.6.2  bouyer 	lea		0x4+EXC_EA(%a6),%a0	# load old a7'
   1234  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)		# save on stack
   1235  1.1.6.2  bouyer 
   1236  1.1.6.2  bouyer fu_cont:
   1237  1.1.6.2  bouyer 
   1238  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction
   1239  1.1.6.2  bouyer # the FPIAR should be set correctly for ALL exceptions passing through
   1240  1.1.6.2  bouyer # this point.
   1241  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   1242  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   1243  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   1244  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   1245  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
   1246  1.1.6.2  bouyer 
   1247  1.1.6.2  bouyer ############################
   1248  1.1.6.2  bouyer 
   1249  1.1.6.2  bouyer 	clr.b		SPCOND_FLG(%a6)		# clear special condition flag
   1250  1.1.6.2  bouyer 
   1251  1.1.6.2  bouyer # Separate opclass three (fpn-to-mem) ops since they have a different
   1252  1.1.6.2  bouyer # stack frame and protocol.
   1253  1.1.6.2  bouyer 	btst		&0x5,EXC_CMDREG(%a6)	# is it an fmove out?
   1254  1.1.6.2  bouyer 	bne.w		fu_out			# yes
   1255  1.1.6.2  bouyer 
   1256  1.1.6.2  bouyer # Separate packed opclass two instructions.
   1257  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&0:&6},%d0
   1258  1.1.6.2  bouyer 	cmpi.b		%d0,&0x13
   1259  1.1.6.2  bouyer 	beq.w		fu_in_pack
   1260  1.1.6.2  bouyer 
   1261  1.1.6.2  bouyer 
   1262  1.1.6.2  bouyer # I'm not sure at this point what FPSR bits are valid for this instruction.
   1263  1.1.6.2  bouyer # so, since the emulation routines re-create them anyways, zero exception field
   1264  1.1.6.2  bouyer 	andi.l		&0x00ff00ff,USER_FPSR(%a6) # zero exception field
   1265  1.1.6.2  bouyer 
   1266  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
   1267  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   1268  1.1.6.2  bouyer 
   1269  1.1.6.2  bouyer # Opclass two w/ memory-to-fpn operation will have an incorrect extended
   1270  1.1.6.2  bouyer # precision format if the src format was single or double and the
   1271  1.1.6.2  bouyer # source data type was an INF, NAN, DENORM, or UNNORM
   1272  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to input
   1273  1.1.6.2  bouyer 	bsr.l		fix_skewed_ops
   1274  1.1.6.2  bouyer 
   1275  1.1.6.2  bouyer # we don't know whether the src operand or the dst operand (or both) is the
   1276  1.1.6.2  bouyer # UNNORM or DENORM. call the function that tags the operand type. if the
   1277  1.1.6.2  bouyer # input is an UNNORM, then convert it to a NORM, DENORM, or ZERO.
   1278  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   1279  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   1280  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   1281  1.1.6.2  bouyer 	bne.b		fu_op2			# no
   1282  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   1283  1.1.6.2  bouyer 
   1284  1.1.6.2  bouyer fu_op2:
   1285  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# save src optype tag
   1286  1.1.6.2  bouyer 
   1287  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1288  1.1.6.2  bouyer 
   1289  1.1.6.2  bouyer # bit five of the fp extension word separates the monadic and dyadic operations
   1290  1.1.6.2  bouyer # at this point
   1291  1.1.6.2  bouyer 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   1292  1.1.6.2  bouyer 	beq.b		fu_extract		# monadic
   1293  1.1.6.2  bouyer 	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?
   1294  1.1.6.2  bouyer 	beq.b		fu_extract		# yes, so it's monadic, too
   1295  1.1.6.2  bouyer 
   1296  1.1.6.2  bouyer 	bsr.l		load_fpn2		# load dst into FP_DST
   1297  1.1.6.2  bouyer 
   1298  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   1299  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   1300  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   1301  1.1.6.2  bouyer 	bne.b		fu_op2_done		# no
   1302  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   1303  1.1.6.2  bouyer fu_op2_done:
   1304  1.1.6.2  bouyer 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
   1305  1.1.6.2  bouyer 
   1306  1.1.6.2  bouyer fu_extract:
   1307  1.1.6.2  bouyer 	clr.l		%d0
   1308  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   1309  1.1.6.2  bouyer 
   1310  1.1.6.2  bouyer 	bfextu		1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
   1311  1.1.6.2  bouyer 
   1312  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
   1313  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1
   1314  1.1.6.2  bouyer 
   1315  1.1.6.2  bouyer 	mov.l		(tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
   1316  1.1.6.2  bouyer 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   1317  1.1.6.2  bouyer 
   1318  1.1.6.2  bouyer #
   1319  1.1.6.2  bouyer # Exceptions in order of precedence:
   1320  1.1.6.2  bouyer # 	BSUN	: none
   1321  1.1.6.2  bouyer #	SNAN	: all dyadic ops
   1322  1.1.6.2  bouyer #	OPERR	: fsqrt(-NORM)
   1323  1.1.6.2  bouyer #	OVFL	: all except ftst,fcmp
   1324  1.1.6.2  bouyer #	UNFL	: all except ftst,fcmp
   1325  1.1.6.2  bouyer #	DZ	: fdiv
   1326  1.1.6.2  bouyer # 	INEX2	: all except ftst,fcmp
   1327  1.1.6.2  bouyer #	INEX1	: none (packed doesn't go through here)
   1328  1.1.6.2  bouyer #
   1329  1.1.6.2  bouyer 
   1330  1.1.6.2  bouyer # we determine the highest priority exception(if any) set by the
   1331  1.1.6.2  bouyer # emulation routine that has also been enabled by the user.
   1332  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions set
   1333  1.1.6.2  bouyer 	bne.b		fu_in_ena		# some are enabled
   1334  1.1.6.2  bouyer 
   1335  1.1.6.2  bouyer fu_in_cont:
   1336  1.1.6.2  bouyer # fcmp and ftst do not store any result.
   1337  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension
   1338  1.1.6.2  bouyer 	andi.b		&0x38,%d0		# extract bits 3-5
   1339  1.1.6.2  bouyer 	cmpi.b		%d0,&0x38		# is instr fcmp or ftst?
   1340  1.1.6.2  bouyer 	beq.b		fu_in_exit		# yes
   1341  1.1.6.2  bouyer 
   1342  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1343  1.1.6.2  bouyer 	bsr.l		store_fpreg		# store the result
   1344  1.1.6.2  bouyer 
   1345  1.1.6.2  bouyer fu_in_exit:
   1346  1.1.6.2  bouyer 
   1347  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1348  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1349  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1350  1.1.6.2  bouyer 
   1351  1.1.6.2  bouyer 	unlk		%a6
   1352  1.1.6.2  bouyer 
   1353  1.1.6.2  bouyer 	bra.l		_fpsp_done
   1354  1.1.6.2  bouyer 
   1355  1.1.6.2  bouyer fu_in_ena:
   1356  1.1.6.2  bouyer 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
   1357  1.1.6.2  bouyer 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   1358  1.1.6.2  bouyer 	bne.b		fu_in_exc		# there is at least one set
   1359  1.1.6.2  bouyer 
   1360  1.1.6.2  bouyer #
   1361  1.1.6.2  bouyer # No exceptions occurred that were also enabled. Now:
   1362  1.1.6.2  bouyer #
   1363  1.1.6.2  bouyer #   	if (OVFL && ovfl_disabled && inexact_enabled) {
   1364  1.1.6.2  bouyer #	    branch to _real_inex() (even if the result was exact!);
   1365  1.1.6.2  bouyer #     	} else {
   1366  1.1.6.2  bouyer #	    save the result in the proper fp reg (unless the op is fcmp or ftst);
   1367  1.1.6.2  bouyer #	    return;
   1368  1.1.6.2  bouyer #     	}
   1369  1.1.6.2  bouyer #
   1370  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
   1371  1.1.6.2  bouyer 	beq.b		fu_in_cont		# no
   1372  1.1.6.2  bouyer 
   1373  1.1.6.2  bouyer fu_in_ovflchk:
   1374  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
   1375  1.1.6.2  bouyer 	beq.b		fu_in_cont		# no
   1376  1.1.6.2  bouyer 	bra.w		fu_in_exc_ovfl		# go insert overflow frame
   1377  1.1.6.2  bouyer 
   1378  1.1.6.2  bouyer #
   1379  1.1.6.2  bouyer # An exception occurred and that exception was enabled:
   1380  1.1.6.2  bouyer #
   1381  1.1.6.2  bouyer #	shift enabled exception field into lo byte of d0;
   1382  1.1.6.2  bouyer #	if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
   1383  1.1.6.2  bouyer #	    ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
   1384  1.1.6.2  bouyer #		/*
   1385  1.1.6.2  bouyer #		 * this is the case where we must call _real_inex() now or else
   1386  1.1.6.2  bouyer #		 * there will be no other way to pass it the exceptional operand
   1387  1.1.6.2  bouyer #		 */
   1388  1.1.6.2  bouyer #		call _real_inex();
   1389  1.1.6.2  bouyer #	} else {
   1390  1.1.6.2  bouyer #		restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
   1391  1.1.6.2  bouyer #	}
   1392  1.1.6.2  bouyer #
   1393  1.1.6.2  bouyer fu_in_exc:
   1394  1.1.6.2  bouyer 	subi.l		&24,%d0			# fix offset to be 0-8
   1395  1.1.6.2  bouyer 	cmpi.b		%d0,&0x6		# is exception INEX? (6)
   1396  1.1.6.2  bouyer 	bne.b		fu_in_exc_exit		# no
   1397  1.1.6.2  bouyer 
   1398  1.1.6.2  bouyer # the enabled exception was inexact
   1399  1.1.6.2  bouyer 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
   1400  1.1.6.2  bouyer 	bne.w		fu_in_exc_unfl		# yes
   1401  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
   1402  1.1.6.2  bouyer 	bne.w		fu_in_exc_ovfl		# yes
   1403  1.1.6.2  bouyer 
   1404  1.1.6.2  bouyer # here, we insert the correct fsave status value into the fsave frame for the
   1405  1.1.6.2  bouyer # corresponding exception. the operand in the fsave frame should be the original
   1406  1.1.6.2  bouyer # src operand.
   1407  1.1.6.2  bouyer fu_in_exc_exit:
   1408  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save d0
   1409  1.1.6.2  bouyer 	bsr.l		funimp_skew		# skew sgl or dbl inputs
   1410  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   1411  1.1.6.2  bouyer 
   1412  1.1.6.2  bouyer 	mov.w		(tbl_except.b,%pc,%d0.w*2),2+FP_SRC(%a6) # create exc status
   1413  1.1.6.2  bouyer 
   1414  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1415  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1416  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1417  1.1.6.2  bouyer 
   1418  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore src op
   1419  1.1.6.2  bouyer 
   1420  1.1.6.2  bouyer 	unlk		%a6
   1421  1.1.6.2  bouyer 
   1422  1.1.6.2  bouyer 	bra.l		_fpsp_done
   1423  1.1.6.2  bouyer 
   1424  1.1.6.2  bouyer tbl_except:
   1425  1.1.6.2  bouyer 	short		0xe000,0xe006,0xe004,0xe005
   1426  1.1.6.2  bouyer 	short		0xe003,0xe002,0xe001,0xe001
   1427  1.1.6.2  bouyer 
   1428  1.1.6.2  bouyer fu_in_exc_unfl:
   1429  1.1.6.2  bouyer 	mov.w		&0x4,%d0
   1430  1.1.6.2  bouyer 	bra.b		fu_in_exc_exit
   1431  1.1.6.2  bouyer fu_in_exc_ovfl:
   1432  1.1.6.2  bouyer 	mov.w		&0x03,%d0
   1433  1.1.6.2  bouyer 	bra.b		fu_in_exc_exit
   1434  1.1.6.2  bouyer 
   1435  1.1.6.2  bouyer # If the input operand to this operation was opclass two and a single
   1436  1.1.6.2  bouyer # or double precision denorm, inf, or nan, the operand needs to be
   1437  1.1.6.2  bouyer # "corrected" in order to have the proper equivalent extended precision
   1438  1.1.6.2  bouyer # number.
   1439  1.1.6.2  bouyer 	global		fix_skewed_ops
   1440  1.1.6.2  bouyer fix_skewed_ops:
   1441  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&0:&6},%d0 # extract opclass,src fmt
   1442  1.1.6.2  bouyer 	cmpi.b		%d0,&0x11		# is class = 2 & fmt = sgl?
   1443  1.1.6.2  bouyer 	beq.b		fso_sgl			# yes
   1444  1.1.6.2  bouyer 	cmpi.b		%d0,&0x15		# is class = 2 & fmt = dbl?
   1445  1.1.6.2  bouyer 	beq.b		fso_dbl			# yes
   1446  1.1.6.2  bouyer 	rts					# no
   1447  1.1.6.2  bouyer 
   1448  1.1.6.2  bouyer fso_sgl:
   1449  1.1.6.2  bouyer 	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent
   1450  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# strip sign
   1451  1.1.6.2  bouyer 	cmpi.w		%d0,&0x3f80		# is |exp| == $3f80?
   1452  1.1.6.2  bouyer 	beq.b		fso_sgl_dnrm_zero	# yes
   1453  1.1.6.2  bouyer 	cmpi.w		%d0,&0x407f		# no; is |exp| == $407f?
   1454  1.1.6.2  bouyer 	beq.b		fso_infnan		# yes
   1455  1.1.6.2  bouyer 	rts					# no
   1456  1.1.6.2  bouyer 
   1457  1.1.6.2  bouyer fso_sgl_dnrm_zero:
   1458  1.1.6.2  bouyer 	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit
   1459  1.1.6.2  bouyer 	beq.b		fso_zero		# it's a skewed zero
   1460  1.1.6.2  bouyer fso_sgl_dnrm:
   1461  1.1.6.2  bouyer # here, we count on norm not to alter a0...
   1462  1.1.6.2  bouyer 	bsr.l		norm			# normalize mantissa
   1463  1.1.6.2  bouyer 	neg.w		%d0			# -shft amt
   1464  1.1.6.2  bouyer 	addi.w		&0x3f81,%d0		# adjust new exponent
   1465  1.1.6.2  bouyer 	andi.w		&0x8000,LOCAL_EX(%a0) 	# clear old exponent
   1466  1.1.6.2  bouyer 	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent
   1467  1.1.6.2  bouyer 	rts
   1468  1.1.6.2  bouyer 
   1469  1.1.6.2  bouyer fso_zero:
   1470  1.1.6.2  bouyer 	andi.w		&0x8000,LOCAL_EX(%a0)	# clear bogus exponent
   1471  1.1.6.2  bouyer 	rts
   1472  1.1.6.2  bouyer 
   1473  1.1.6.2  bouyer fso_infnan:
   1474  1.1.6.2  bouyer 	andi.b		&0x7f,LOCAL_HI(%a0) 	# clear j-bit
   1475  1.1.6.2  bouyer 	ori.w		&0x7fff,LOCAL_EX(%a0)	# make exponent = $7fff
   1476  1.1.6.2  bouyer 	rts
   1477  1.1.6.2  bouyer 
   1478  1.1.6.2  bouyer fso_dbl:
   1479  1.1.6.2  bouyer 	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent
   1480  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# strip sign
   1481  1.1.6.2  bouyer 	cmpi.w		%d0,&0x3c00		# is |exp| == $3c00?
   1482  1.1.6.2  bouyer 	beq.b		fso_dbl_dnrm_zero	# yes
   1483  1.1.6.2  bouyer 	cmpi.w		%d0,&0x43ff		# no; is |exp| == $43ff?
   1484  1.1.6.2  bouyer 	beq.b		fso_infnan		# yes
   1485  1.1.6.2  bouyer 	rts					# no
   1486  1.1.6.2  bouyer 
   1487  1.1.6.2  bouyer fso_dbl_dnrm_zero:
   1488  1.1.6.2  bouyer 	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit
   1489  1.1.6.2  bouyer 	bne.b		fso_dbl_dnrm		# it's a skewed denorm
   1490  1.1.6.2  bouyer 	tst.l		LOCAL_LO(%a0)		# is it a zero?
   1491  1.1.6.2  bouyer 	beq.b		fso_zero		# yes
   1492  1.1.6.2  bouyer fso_dbl_dnrm:
   1493  1.1.6.2  bouyer # here, we count on norm not to alter a0...
   1494  1.1.6.2  bouyer 	bsr.l		norm			# normalize mantissa
   1495  1.1.6.2  bouyer 	neg.w		%d0			# -shft amt
   1496  1.1.6.2  bouyer 	addi.w		&0x3c01,%d0		# adjust new exponent
   1497  1.1.6.2  bouyer 	andi.w		&0x8000,LOCAL_EX(%a0) 	# clear old exponent
   1498  1.1.6.2  bouyer 	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent
   1499  1.1.6.2  bouyer 	rts
   1500  1.1.6.2  bouyer 
   1501  1.1.6.2  bouyer #################################################################
   1502  1.1.6.2  bouyer 
   1503  1.1.6.2  bouyer # fmove out took an unimplemented data type exception.
   1504  1.1.6.2  bouyer # the src operand is in FP_SRC. Call _fout() to write out the result and
   1505  1.1.6.2  bouyer # to determine which exceptions, if any, to take.
   1506  1.1.6.2  bouyer fu_out:
   1507  1.1.6.2  bouyer 
   1508  1.1.6.2  bouyer # Separate packed move outs from the UNNORM and DENORM move outs.
   1509  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&3:&3},%d0
   1510  1.1.6.2  bouyer 	cmpi.b		%d0,&0x3
   1511  1.1.6.2  bouyer 	beq.w		fu_out_pack
   1512  1.1.6.2  bouyer 	cmpi.b		%d0,&0x7
   1513  1.1.6.2  bouyer 	beq.w		fu_out_pack
   1514  1.1.6.2  bouyer 
   1515  1.1.6.2  bouyer 
   1516  1.1.6.2  bouyer # I'm not sure at this point what FPSR bits are valid for this instruction.
   1517  1.1.6.2  bouyer # so, since the emulation routines re-create them anyways, zero exception field.
   1518  1.1.6.2  bouyer # fmove out doesn't affect ccodes.
   1519  1.1.6.2  bouyer 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
   1520  1.1.6.2  bouyer 
   1521  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
   1522  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   1523  1.1.6.2  bouyer 
   1524  1.1.6.2  bouyer # the src can ONLY be a DENORM or an UNNORM! so, don't make any big subroutine
   1525  1.1.6.2  bouyer # call here. just figure out what it is...
   1526  1.1.6.2  bouyer 	mov.w		FP_SRC_EX(%a6),%d0	# get exponent
   1527  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# strip sign
   1528  1.1.6.2  bouyer 	beq.b		fu_out_denorm		# it's a DENORM
   1529  1.1.6.2  bouyer 
   1530  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
   1531  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; fix it
   1532  1.1.6.2  bouyer 
   1533  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)
   1534  1.1.6.2  bouyer 
   1535  1.1.6.2  bouyer 	bra.b		fu_out_cont
   1536  1.1.6.2  bouyer fu_out_denorm:
   1537  1.1.6.2  bouyer 	mov.b		&DENORM,STAG(%a6)
   1538  1.1.6.2  bouyer fu_out_cont:
   1539  1.1.6.2  bouyer 
   1540  1.1.6.2  bouyer 	clr.l		%d0
   1541  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   1542  1.1.6.2  bouyer 
   1543  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   1544  1.1.6.2  bouyer 
   1545  1.1.6.2  bouyer 	mov.l		(%a6),EXC_A6(%a6)	# in case a6 changes
   1546  1.1.6.2  bouyer 	bsr.l		fout			# call fmove out routine
   1547  1.1.6.2  bouyer 
   1548  1.1.6.2  bouyer # Exceptions in order of precedence:
   1549  1.1.6.2  bouyer # 	BSUN	: none
   1550  1.1.6.2  bouyer #	SNAN	: none
   1551  1.1.6.2  bouyer #	OPERR	: fmove.{b,w,l} out of large UNNORM
   1552  1.1.6.2  bouyer #	OVFL	: fmove.{s,d}
   1553  1.1.6.2  bouyer #	UNFL	: fmove.{s,d,x}
   1554  1.1.6.2  bouyer #	DZ	: none
   1555  1.1.6.2  bouyer # 	INEX2	: all
   1556  1.1.6.2  bouyer #	INEX1	: none (packed doesn't travel through here)
   1557  1.1.6.2  bouyer 
   1558  1.1.6.2  bouyer # determine the highest priority exception(if any) set by the
   1559  1.1.6.2  bouyer # emulation routine that has also been enabled by the user.
   1560  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   1561  1.1.6.2  bouyer 	bne.w		fu_out_ena		# some are enabled
   1562  1.1.6.2  bouyer 
   1563  1.1.6.2  bouyer fu_out_done:
   1564  1.1.6.2  bouyer 
   1565  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),(%a6)	# in case a6 changed
   1566  1.1.6.2  bouyer 
   1567  1.1.6.2  bouyer # on extended precision opclass three instructions using pre-decrement or
   1568  1.1.6.2  bouyer # post-increment addressing mode, the address register is not updated. is the
   1569  1.1.6.2  bouyer # address register was the stack pointer used from user mode, then let's update
   1570  1.1.6.2  bouyer # it here. if it was used from supervisor mode, then we have to handle this
   1571  1.1.6.2  bouyer # as a special case.
   1572  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)
   1573  1.1.6.2  bouyer 	bne.b		fu_out_done_s
   1574  1.1.6.2  bouyer 
   1575  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# restore a7
   1576  1.1.6.2  bouyer 	mov.l		%a0,%usp
   1577  1.1.6.2  bouyer 
   1578  1.1.6.2  bouyer fu_out_done_cont:
   1579  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1580  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1581  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1582  1.1.6.2  bouyer 
   1583  1.1.6.2  bouyer 	unlk		%a6
   1584  1.1.6.2  bouyer 
   1585  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   1586  1.1.6.2  bouyer 	bne.b		fu_out_trace		# yes
   1587  1.1.6.2  bouyer 
   1588  1.1.6.2  bouyer 	bra.l		_fpsp_done
   1589  1.1.6.2  bouyer 
   1590  1.1.6.2  bouyer # is the ea mode pre-decrement of the stack pointer from supervisor mode?
   1591  1.1.6.2  bouyer # ("fmov.x fpm,-(a7)") if so,
   1592  1.1.6.2  bouyer fu_out_done_s:
   1593  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   1594  1.1.6.2  bouyer 	bne.b		fu_out_done_cont
   1595  1.1.6.2  bouyer 
   1596  1.1.6.2  bouyer # the extended precision result is still in fp0. but, we need to save it
   1597  1.1.6.2  bouyer # somewhere on the stack until we can copy it to its final resting place.
   1598  1.1.6.2  bouyer # here, we're counting on the top of the stack to be the old place-holders
   1599  1.1.6.2  bouyer # for fp0/fp1 which have already been restored. that way, we can write
   1600  1.1.6.2  bouyer # over those destinations with the shifted stack frame.
   1601  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SRC(%a6)	# put answer on stack
   1602  1.1.6.2  bouyer 
   1603  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1604  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1605  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1606  1.1.6.2  bouyer 
   1607  1.1.6.2  bouyer 	mov.l		(%a6),%a6		# restore frame pointer
   1608  1.1.6.2  bouyer 
   1609  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   1610  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   1611  1.1.6.2  bouyer 
   1612  1.1.6.2  bouyer # now, copy the result to the proper place on the stack
   1613  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
   1614  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
   1615  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
   1616  1.1.6.2  bouyer 
   1617  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE-0x8,%sp
   1618  1.1.6.2  bouyer 
   1619  1.1.6.2  bouyer 	btst		&0x7,(%sp)
   1620  1.1.6.2  bouyer 	bne.b		fu_out_trace
   1621  1.1.6.2  bouyer 
   1622  1.1.6.2  bouyer 	bra.l		_fpsp_done
   1623  1.1.6.2  bouyer 
   1624  1.1.6.2  bouyer fu_out_ena:
   1625  1.1.6.2  bouyer 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
   1626  1.1.6.2  bouyer 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   1627  1.1.6.2  bouyer 	bne.b		fu_out_exc		# there is at least one set
   1628  1.1.6.2  bouyer 
   1629  1.1.6.2  bouyer # no exceptions were set.
   1630  1.1.6.2  bouyer # if a disabled overflow occurred and inexact was enabled but the result
   1631  1.1.6.2  bouyer # was exact, then a branch to _real_inex() is made.
   1632  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
   1633  1.1.6.2  bouyer 	beq.w		fu_out_done		# no
   1634  1.1.6.2  bouyer 
   1635  1.1.6.2  bouyer fu_out_ovflchk:
   1636  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
   1637  1.1.6.2  bouyer 	beq.w		fu_out_done		# no
   1638  1.1.6.2  bouyer 	bra.w		fu_inex			# yes
   1639  1.1.6.2  bouyer 
   1640  1.1.6.2  bouyer #
   1641  1.1.6.2  bouyer # The fp move out that took the "Unimplemented Data Type" exception was
   1642  1.1.6.2  bouyer # being traced. Since the stack frames are similar, get the "current" PC
   1643  1.1.6.2  bouyer # from FPIAR and put it in the trace stack frame then jump to _real_trace().
   1644  1.1.6.2  bouyer #
   1645  1.1.6.2  bouyer #		  UNSUPP FRAME		   TRACE FRAME
   1646  1.1.6.2  bouyer # 		*****************	*****************
   1647  1.1.6.2  bouyer #		*      EA	*	*    Current	*
   1648  1.1.6.2  bouyer #		*		*	*      PC	*
   1649  1.1.6.2  bouyer #		*****************	*****************
   1650  1.1.6.2  bouyer #		* 0x3 *  0x0dc	*	* 0x2 *  0x024	*
   1651  1.1.6.2  bouyer #		*****************	*****************
   1652  1.1.6.2  bouyer #		*     Next	*	*     Next	*
   1653  1.1.6.2  bouyer #		*      PC	*	*      PC	*
   1654  1.1.6.2  bouyer #		*****************	*****************
   1655  1.1.6.2  bouyer #		*      SR	*	*      SR	*
   1656  1.1.6.2  bouyer #		*****************	*****************
   1657  1.1.6.2  bouyer #
   1658  1.1.6.2  bouyer fu_out_trace:
   1659  1.1.6.2  bouyer 	mov.w		&0x2024,0x6(%sp)
   1660  1.1.6.2  bouyer 	fmov.l		%fpiar,0x8(%sp)
   1661  1.1.6.2  bouyer 	bra.l		_real_trace
   1662  1.1.6.2  bouyer 
   1663  1.1.6.2  bouyer # an exception occurred and that exception was enabled.
   1664  1.1.6.2  bouyer fu_out_exc:
   1665  1.1.6.2  bouyer 	subi.l		&24,%d0			# fix offset to be 0-8
   1666  1.1.6.2  bouyer 
   1667  1.1.6.2  bouyer # we don't mess with the existing fsave frame. just re-insert it and
   1668  1.1.6.2  bouyer # jump to the "_real_{}()" handler...
   1669  1.1.6.2  bouyer 	mov.w		(tbl_fu_out.b,%pc,%d0.w*2),%d0
   1670  1.1.6.2  bouyer 	jmp		(tbl_fu_out.b,%pc,%d0.w*1)
   1671  1.1.6.2  bouyer 
   1672  1.1.6.2  bouyer 	swbeg		&0x8
   1673  1.1.6.2  bouyer tbl_fu_out:
   1674  1.1.6.2  bouyer 	short		tbl_fu_out	- tbl_fu_out	# BSUN can't happen
   1675  1.1.6.2  bouyer 	short		tbl_fu_out 	- tbl_fu_out	# SNAN can't happen
   1676  1.1.6.2  bouyer 	short		fu_operr	- tbl_fu_out	# OPERR
   1677  1.1.6.2  bouyer 	short		fu_ovfl 	- tbl_fu_out	# OVFL
   1678  1.1.6.2  bouyer 	short		fu_unfl 	- tbl_fu_out	# UNFL
   1679  1.1.6.2  bouyer 	short		tbl_fu_out	- tbl_fu_out	# DZ can't happen
   1680  1.1.6.2  bouyer 	short		fu_inex 	- tbl_fu_out	# INEX2
   1681  1.1.6.2  bouyer 	short		tbl_fu_out	- tbl_fu_out	# INEX1 won't make it here
   1682  1.1.6.2  bouyer 
   1683  1.1.6.2  bouyer # for snan,operr,ovfl,unfl, src op is still in FP_SRC so just
   1684  1.1.6.2  bouyer # frestore it.
   1685  1.1.6.2  bouyer fu_snan:
   1686  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1687  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1688  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1689  1.1.6.2  bouyer 
   1690  1.1.6.2  bouyer 	mov.w		&0x30d8,EXC_VOFF(%a6)	# vector offset = 0xd8
   1691  1.1.6.2  bouyer 	mov.w		&0xe006,2+FP_SRC(%a6)
   1692  1.1.6.2  bouyer 
   1693  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)
   1694  1.1.6.2  bouyer 
   1695  1.1.6.2  bouyer 	unlk		%a6
   1696  1.1.6.2  bouyer 
   1697  1.1.6.2  bouyer 
   1698  1.1.6.2  bouyer 	bra.l		_real_snan
   1699  1.1.6.2  bouyer 
   1700  1.1.6.2  bouyer fu_operr:
   1701  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1702  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1703  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1704  1.1.6.2  bouyer 
   1705  1.1.6.2  bouyer 	mov.w		&0x30d0,EXC_VOFF(%a6)	# vector offset = 0xd0
   1706  1.1.6.2  bouyer 	mov.w		&0xe004,2+FP_SRC(%a6)
   1707  1.1.6.2  bouyer 
   1708  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)
   1709  1.1.6.2  bouyer 
   1710  1.1.6.2  bouyer 	unlk		%a6
   1711  1.1.6.2  bouyer 
   1712  1.1.6.2  bouyer 
   1713  1.1.6.2  bouyer 	bra.l		_real_operr
   1714  1.1.6.2  bouyer 
   1715  1.1.6.2  bouyer fu_ovfl:
   1716  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
   1717  1.1.6.2  bouyer 
   1718  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1719  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1720  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1721  1.1.6.2  bouyer 
   1722  1.1.6.2  bouyer 	mov.w		&0x30d4,EXC_VOFF(%a6)	# vector offset = 0xd4
   1723  1.1.6.2  bouyer 	mov.w		&0xe005,2+FP_SRC(%a6)
   1724  1.1.6.2  bouyer 
   1725  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore EXOP
   1726  1.1.6.2  bouyer 
   1727  1.1.6.2  bouyer 	unlk		%a6
   1728  1.1.6.2  bouyer 
   1729  1.1.6.2  bouyer 	bra.l		_real_ovfl
   1730  1.1.6.2  bouyer 
   1731  1.1.6.2  bouyer # underflow can happen for extended precision. extended precision opclass
   1732  1.1.6.2  bouyer # three instruction exceptions don't update the stack pointer. so, if the
   1733  1.1.6.2  bouyer # exception occurred from user mode, then simply update a7 and exit normally.
   1734  1.1.6.2  bouyer # if the exception occurred from supervisor mode, check if
   1735  1.1.6.2  bouyer fu_unfl:
   1736  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
   1737  1.1.6.2  bouyer 
   1738  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)
   1739  1.1.6.2  bouyer 	bne.w		fu_unfl_s
   1740  1.1.6.2  bouyer 
   1741  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# restore a7 whether we need
   1742  1.1.6.2  bouyer 	mov.l		%a0,%usp		# to or not...
   1743  1.1.6.2  bouyer 
   1744  1.1.6.2  bouyer fu_unfl_cont:
   1745  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
   1746  1.1.6.2  bouyer 
   1747  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1748  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1749  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1750  1.1.6.2  bouyer 
   1751  1.1.6.2  bouyer 	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc
   1752  1.1.6.2  bouyer 	mov.w		&0xe003,2+FP_SRC(%a6)
   1753  1.1.6.2  bouyer 
   1754  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore EXOP
   1755  1.1.6.2  bouyer 
   1756  1.1.6.2  bouyer 	unlk		%a6
   1757  1.1.6.2  bouyer 
   1758  1.1.6.2  bouyer 	bra.l		_real_unfl
   1759  1.1.6.2  bouyer 
   1760  1.1.6.2  bouyer fu_unfl_s:
   1761  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was the <ea> mode -(sp)?
   1762  1.1.6.2  bouyer 	bne.b		fu_unfl_cont
   1763  1.1.6.2  bouyer 
   1764  1.1.6.2  bouyer # the extended precision result is still in fp0. but, we need to save it
   1765  1.1.6.2  bouyer # somewhere on the stack until we can copy it to its final resting place
   1766  1.1.6.2  bouyer # (where the exc frame is currently). make sure it's not at the top of the
   1767  1.1.6.2  bouyer # frame or it will get overwritten when the exc stack frame is shifted "down".
   1768  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SRC(%a6)	# put answer on stack
   1769  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_DST(%a6)	# put EXOP on stack
   1770  1.1.6.2  bouyer 
   1771  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1772  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1773  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1774  1.1.6.2  bouyer 
   1775  1.1.6.2  bouyer 	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc
   1776  1.1.6.2  bouyer 	mov.w		&0xe003,2+FP_DST(%a6)
   1777  1.1.6.2  bouyer 
   1778  1.1.6.2  bouyer 	frestore	FP_DST(%a6)		# restore EXOP
   1779  1.1.6.2  bouyer 
   1780  1.1.6.2  bouyer 	mov.l		(%a6),%a6		# restore frame pointer
   1781  1.1.6.2  bouyer 
   1782  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   1783  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   1784  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   1785  1.1.6.2  bouyer 
   1786  1.1.6.2  bouyer # now, copy the result to the proper place on the stack
   1787  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
   1788  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
   1789  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
   1790  1.1.6.2  bouyer 
   1791  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE-0x8,%sp
   1792  1.1.6.2  bouyer 
   1793  1.1.6.2  bouyer 	bra.l		_real_unfl
   1794  1.1.6.2  bouyer 
   1795  1.1.6.2  bouyer # fmove in and out enter here.
   1796  1.1.6.2  bouyer fu_inex:
   1797  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
   1798  1.1.6.2  bouyer 
   1799  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1800  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1801  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1802  1.1.6.2  bouyer 
   1803  1.1.6.2  bouyer 	mov.w		&0x30c4,EXC_VOFF(%a6)	# vector offset = 0xc4
   1804  1.1.6.2  bouyer 	mov.w		&0xe001,2+FP_SRC(%a6)
   1805  1.1.6.2  bouyer 
   1806  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore EXOP
   1807  1.1.6.2  bouyer 
   1808  1.1.6.2  bouyer 	unlk		%a6
   1809  1.1.6.2  bouyer 
   1810  1.1.6.2  bouyer 
   1811  1.1.6.2  bouyer 	bra.l		_real_inex
   1812  1.1.6.2  bouyer 
   1813  1.1.6.2  bouyer #########################################################################
   1814  1.1.6.2  bouyer #########################################################################
   1815  1.1.6.2  bouyer fu_in_pack:
   1816  1.1.6.2  bouyer 
   1817  1.1.6.2  bouyer 
   1818  1.1.6.2  bouyer # I'm not sure at this point what FPSR bits are valid for this instruction.
   1819  1.1.6.2  bouyer # so, since the emulation routines re-create them anyways, zero exception field
   1820  1.1.6.2  bouyer 	andi.l		&0x0ff00ff,USER_FPSR(%a6) # zero exception field
   1821  1.1.6.2  bouyer 
   1822  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
   1823  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   1824  1.1.6.2  bouyer 
   1825  1.1.6.2  bouyer 	bsr.l		get_packed		# fetch packed src operand
   1826  1.1.6.2  bouyer 
   1827  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src
   1828  1.1.6.2  bouyer 	bsr.l		set_tag_x		# set src optype tag
   1829  1.1.6.2  bouyer 
   1830  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# save src optype tag
   1831  1.1.6.2  bouyer 
   1832  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1833  1.1.6.2  bouyer 
   1834  1.1.6.2  bouyer # bit five of the fp extension word separates the monadic and dyadic operations
   1835  1.1.6.2  bouyer # at this point
   1836  1.1.6.2  bouyer 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   1837  1.1.6.2  bouyer 	beq.b		fu_extract_p		# monadic
   1838  1.1.6.2  bouyer 	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?
   1839  1.1.6.2  bouyer 	beq.b		fu_extract_p		# yes, so it's monadic, too
   1840  1.1.6.2  bouyer 
   1841  1.1.6.2  bouyer 	bsr.l		load_fpn2		# load dst into FP_DST
   1842  1.1.6.2  bouyer 
   1843  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   1844  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   1845  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   1846  1.1.6.2  bouyer 	bne.b		fu_op2_done_p		# no
   1847  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   1848  1.1.6.2  bouyer fu_op2_done_p:
   1849  1.1.6.2  bouyer 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
   1850  1.1.6.2  bouyer 
   1851  1.1.6.2  bouyer fu_extract_p:
   1852  1.1.6.2  bouyer 	clr.l		%d0
   1853  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   1854  1.1.6.2  bouyer 
   1855  1.1.6.2  bouyer 	bfextu		1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
   1856  1.1.6.2  bouyer 
   1857  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
   1858  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1
   1859  1.1.6.2  bouyer 
   1860  1.1.6.2  bouyer 	mov.l		(tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
   1861  1.1.6.2  bouyer 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   1862  1.1.6.2  bouyer 
   1863  1.1.6.2  bouyer #
   1864  1.1.6.2  bouyer # Exceptions in order of precedence:
   1865  1.1.6.2  bouyer # 	BSUN	: none
   1866  1.1.6.2  bouyer #	SNAN	: all dyadic ops
   1867  1.1.6.2  bouyer #	OPERR	: fsqrt(-NORM)
   1868  1.1.6.2  bouyer #	OVFL	: all except ftst,fcmp
   1869  1.1.6.2  bouyer #	UNFL	: all except ftst,fcmp
   1870  1.1.6.2  bouyer #	DZ	: fdiv
   1871  1.1.6.2  bouyer # 	INEX2	: all except ftst,fcmp
   1872  1.1.6.2  bouyer #	INEX1	: all
   1873  1.1.6.2  bouyer #
   1874  1.1.6.2  bouyer 
   1875  1.1.6.2  bouyer # we determine the highest priority exception(if any) set by the
   1876  1.1.6.2  bouyer # emulation routine that has also been enabled by the user.
   1877  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   1878  1.1.6.2  bouyer 	bne.w		fu_in_ena_p		# some are enabled
   1879  1.1.6.2  bouyer 
   1880  1.1.6.2  bouyer fu_in_cont_p:
   1881  1.1.6.2  bouyer # fcmp and ftst do not store any result.
   1882  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension
   1883  1.1.6.2  bouyer 	andi.b		&0x38,%d0		# extract bits 3-5
   1884  1.1.6.2  bouyer 	cmpi.b		%d0,&0x38		# is instr fcmp or ftst?
   1885  1.1.6.2  bouyer 	beq.b		fu_in_exit_p		# yes
   1886  1.1.6.2  bouyer 
   1887  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   1888  1.1.6.2  bouyer 	bsr.l		store_fpreg		# store the result
   1889  1.1.6.2  bouyer 
   1890  1.1.6.2  bouyer fu_in_exit_p:
   1891  1.1.6.2  bouyer 
   1892  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   1893  1.1.6.2  bouyer 	bne.w		fu_in_exit_s_p		# supervisor
   1894  1.1.6.2  bouyer 
   1895  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# update user a7
   1896  1.1.6.2  bouyer 	mov.l		%a0,%usp
   1897  1.1.6.2  bouyer 
   1898  1.1.6.2  bouyer fu_in_exit_cont_p:
   1899  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1900  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1901  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1902  1.1.6.2  bouyer 
   1903  1.1.6.2  bouyer 	unlk		%a6			# unravel stack frame
   1904  1.1.6.2  bouyer 
   1905  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   1906  1.1.6.2  bouyer 	bne.w		fu_trace_p		# yes
   1907  1.1.6.2  bouyer 
   1908  1.1.6.2  bouyer 	bra.l		_fpsp_done		# exit to os
   1909  1.1.6.2  bouyer 
   1910  1.1.6.2  bouyer # the exception occurred in supervisor mode. check to see if the
   1911  1.1.6.2  bouyer # addressing mode was (a7)+. if so, we'll need to shift the
   1912  1.1.6.2  bouyer # stack frame "up".
   1913  1.1.6.2  bouyer fu_in_exit_s_p:
   1914  1.1.6.2  bouyer 	btst		&mia7_bit,SPCOND_FLG(%a6) # was ea mode (a7)+
   1915  1.1.6.2  bouyer 	beq.b		fu_in_exit_cont_p	# no
   1916  1.1.6.2  bouyer 
   1917  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1918  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   1919  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   1920  1.1.6.2  bouyer 
   1921  1.1.6.2  bouyer 	unlk		%a6			# unravel stack frame
   1922  1.1.6.2  bouyer 
   1923  1.1.6.2  bouyer # shift the stack frame "up". we don't really care about the <ea> field.
   1924  1.1.6.2  bouyer 	mov.l		0x4(%sp),0x10(%sp)
   1925  1.1.6.2  bouyer 	mov.l		0x0(%sp),0xc(%sp)
   1926  1.1.6.2  bouyer 	add.l		&0xc,%sp
   1927  1.1.6.2  bouyer 
   1928  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   1929  1.1.6.2  bouyer 	bne.w		fu_trace_p		# yes
   1930  1.1.6.2  bouyer 
   1931  1.1.6.2  bouyer 	bra.l		_fpsp_done		# exit to os
   1932  1.1.6.2  bouyer 
   1933  1.1.6.2  bouyer fu_in_ena_p:
   1934  1.1.6.2  bouyer 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled & set
   1935  1.1.6.2  bouyer 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   1936  1.1.6.2  bouyer 	bne.b		fu_in_exc_p		# at least one was set
   1937  1.1.6.2  bouyer 
   1938  1.1.6.2  bouyer #
   1939  1.1.6.2  bouyer # No exceptions occurred that were also enabled. Now:
   1940  1.1.6.2  bouyer #
   1941  1.1.6.2  bouyer #   	if (OVFL && ovfl_disabled && inexact_enabled) {
   1942  1.1.6.2  bouyer #	    branch to _real_inex() (even if the result was exact!);
   1943  1.1.6.2  bouyer #     	} else {
   1944  1.1.6.2  bouyer #	    save the result in the proper fp reg (unless the op is fcmp or ftst);
   1945  1.1.6.2  bouyer #	    return;
   1946  1.1.6.2  bouyer #     	}
   1947  1.1.6.2  bouyer #
   1948  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
   1949  1.1.6.2  bouyer 	beq.w		fu_in_cont_p		# no
   1950  1.1.6.2  bouyer 
   1951  1.1.6.2  bouyer fu_in_ovflchk_p:
   1952  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
   1953  1.1.6.2  bouyer 	beq.w		fu_in_cont_p		# no
   1954  1.1.6.2  bouyer 	bra.w		fu_in_exc_ovfl_p	# do _real_inex() now
   1955  1.1.6.2  bouyer 
   1956  1.1.6.2  bouyer #
   1957  1.1.6.2  bouyer # An exception occurred and that exception was enabled:
   1958  1.1.6.2  bouyer #
   1959  1.1.6.2  bouyer #	shift enabled exception field into lo byte of d0;
   1960  1.1.6.2  bouyer #	if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
   1961  1.1.6.2  bouyer #	    ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
   1962  1.1.6.2  bouyer #		/*
   1963  1.1.6.2  bouyer #		 * this is the case where we must call _real_inex() now or else
   1964  1.1.6.2  bouyer #		 * there will be no other way to pass it the exceptional operand
   1965  1.1.6.2  bouyer #		 */
   1966  1.1.6.2  bouyer #		call _real_inex();
   1967  1.1.6.2  bouyer #	} else {
   1968  1.1.6.2  bouyer #		restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
   1969  1.1.6.2  bouyer #	}
   1970  1.1.6.2  bouyer #
   1971  1.1.6.2  bouyer fu_in_exc_p:
   1972  1.1.6.2  bouyer 	subi.l		&24,%d0			# fix offset to be 0-8
   1973  1.1.6.2  bouyer 	cmpi.b		%d0,&0x6		# is exception INEX? (6 or 7)
   1974  1.1.6.2  bouyer 	blt.b		fu_in_exc_exit_p	# no
   1975  1.1.6.2  bouyer 
   1976  1.1.6.2  bouyer # the enabled exception was inexact
   1977  1.1.6.2  bouyer 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
   1978  1.1.6.2  bouyer 	bne.w		fu_in_exc_unfl_p	# yes
   1979  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
   1980  1.1.6.2  bouyer 	bne.w		fu_in_exc_ovfl_p	# yes
   1981  1.1.6.2  bouyer 
   1982  1.1.6.2  bouyer # here, we insert the correct fsave status value into the fsave frame for the
   1983  1.1.6.2  bouyer # corresponding exception. the operand in the fsave frame should be the original
   1984  1.1.6.2  bouyer # src operand.
   1985  1.1.6.2  bouyer # as a reminder for future predicted pain and agony, we are passing in fsave the
   1986  1.1.6.2  bouyer # "non-skewed" operand for cases of sgl and dbl src INFs,NANs, and DENORMs.
   1987  1.1.6.2  bouyer # this is INCORRECT for enabled SNAN which would give to the user the skewed SNAN!!!
   1988  1.1.6.2  bouyer fu_in_exc_exit_p:
   1989  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   1990  1.1.6.2  bouyer 	bne.w		fu_in_exc_exit_s_p	# supervisor
   1991  1.1.6.2  bouyer 
   1992  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# update user a7
   1993  1.1.6.2  bouyer 	mov.l		%a0,%usp
   1994  1.1.6.2  bouyer 
   1995  1.1.6.2  bouyer fu_in_exc_exit_cont_p:
   1996  1.1.6.2  bouyer 	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   1997  1.1.6.2  bouyer 
   1998  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   1999  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2000  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2001  1.1.6.2  bouyer 
   2002  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore src op
   2003  1.1.6.2  bouyer 
   2004  1.1.6.2  bouyer 	unlk		%a6
   2005  1.1.6.2  bouyer 
   2006  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace enabled?
   2007  1.1.6.2  bouyer 	bne.w		fu_trace_p		# yes
   2008  1.1.6.2  bouyer 
   2009  1.1.6.2  bouyer 	bra.l		_fpsp_done
   2010  1.1.6.2  bouyer 
   2011  1.1.6.2  bouyer tbl_except_p:
   2012  1.1.6.2  bouyer 	short		0xe000,0xe006,0xe004,0xe005
   2013  1.1.6.2  bouyer 	short		0xe003,0xe002,0xe001,0xe001
   2014  1.1.6.2  bouyer 
   2015  1.1.6.2  bouyer fu_in_exc_ovfl_p:
   2016  1.1.6.2  bouyer 	mov.w		&0x3,%d0
   2017  1.1.6.2  bouyer 	bra.w		fu_in_exc_exit_p
   2018  1.1.6.2  bouyer 
   2019  1.1.6.2  bouyer fu_in_exc_unfl_p:
   2020  1.1.6.2  bouyer 	mov.w		&0x4,%d0
   2021  1.1.6.2  bouyer 	bra.w		fu_in_exc_exit_p
   2022  1.1.6.2  bouyer 
   2023  1.1.6.2  bouyer fu_in_exc_exit_s_p:
   2024  1.1.6.2  bouyer 	btst		&mia7_bit,SPCOND_FLG(%a6)
   2025  1.1.6.2  bouyer 	beq.b		fu_in_exc_exit_cont_p
   2026  1.1.6.2  bouyer 
   2027  1.1.6.2  bouyer 	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   2028  1.1.6.2  bouyer 
   2029  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2030  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2031  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2032  1.1.6.2  bouyer 
   2033  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore src op
   2034  1.1.6.2  bouyer 
   2035  1.1.6.2  bouyer 	unlk		%a6			# unravel stack frame
   2036  1.1.6.2  bouyer 
   2037  1.1.6.2  bouyer # shift stack frame "up". who cares about <ea> field.
   2038  1.1.6.2  bouyer 	mov.l		0x4(%sp),0x10(%sp)
   2039  1.1.6.2  bouyer 	mov.l		0x0(%sp),0xc(%sp)
   2040  1.1.6.2  bouyer 	add.l		&0xc,%sp
   2041  1.1.6.2  bouyer 
   2042  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   2043  1.1.6.2  bouyer 	bne.b		fu_trace_p		# yes
   2044  1.1.6.2  bouyer 
   2045  1.1.6.2  bouyer 	bra.l		_fpsp_done		# exit to os
   2046  1.1.6.2  bouyer 
   2047  1.1.6.2  bouyer #
   2048  1.1.6.2  bouyer # The opclass two PACKED instruction that took an "Unimplemented Data Type"
   2049  1.1.6.2  bouyer # exception was being traced. Make the "current" PC the FPIAR and put it in the
   2050  1.1.6.2  bouyer # trace stack frame then jump to _real_trace().
   2051  1.1.6.2  bouyer #
   2052  1.1.6.2  bouyer #		  UNSUPP FRAME		   TRACE FRAME
   2053  1.1.6.2  bouyer #		*****************	*****************
   2054  1.1.6.2  bouyer #		*      EA	*	*    Current	*
   2055  1.1.6.2  bouyer #		*		*	*      PC	*
   2056  1.1.6.2  bouyer #		*****************	*****************
   2057  1.1.6.2  bouyer #		* 0x2 *	0x0dc	* 	* 0x2 *  0x024	*
   2058  1.1.6.2  bouyer #		*****************	*****************
   2059  1.1.6.2  bouyer #		*     Next	*	*     Next	*
   2060  1.1.6.2  bouyer #		*      PC	*      	*      PC	*
   2061  1.1.6.2  bouyer #		*****************	*****************
   2062  1.1.6.2  bouyer #		*      SR	*	*      SR	*
   2063  1.1.6.2  bouyer #		*****************	*****************
   2064  1.1.6.2  bouyer fu_trace_p:
   2065  1.1.6.2  bouyer 	mov.w		&0x2024,0x6(%sp)
   2066  1.1.6.2  bouyer 	fmov.l		%fpiar,0x8(%sp)
   2067  1.1.6.2  bouyer 
   2068  1.1.6.2  bouyer 	bra.l		_real_trace
   2069  1.1.6.2  bouyer 
   2070  1.1.6.2  bouyer #########################################################
   2071  1.1.6.2  bouyer #########################################################
   2072  1.1.6.2  bouyer fu_out_pack:
   2073  1.1.6.2  bouyer 
   2074  1.1.6.2  bouyer 
   2075  1.1.6.2  bouyer # I'm not sure at this point what FPSR bits are valid for this instruction.
   2076  1.1.6.2  bouyer # so, since the emulation routines re-create them anyways, zero exception field.
   2077  1.1.6.2  bouyer # fmove out doesn't affect ccodes.
   2078  1.1.6.2  bouyer 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
   2079  1.1.6.2  bouyer 
   2080  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
   2081  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   2082  1.1.6.2  bouyer 
   2083  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
   2084  1.1.6.2  bouyer 	bsr.l		load_fpn1
   2085  1.1.6.2  bouyer 
   2086  1.1.6.2  bouyer # unlike other opclass 3, unimplemented data type exceptions, packed must be
   2087  1.1.6.2  bouyer # able to detect all operand types.
   2088  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
   2089  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   2090  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   2091  1.1.6.2  bouyer 	bne.b		fu_op2_p		# no
   2092  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   2093  1.1.6.2  bouyer 
   2094  1.1.6.2  bouyer fu_op2_p:
   2095  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# save src optype tag
   2096  1.1.6.2  bouyer 
   2097  1.1.6.2  bouyer 	clr.l		%d0
   2098  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
   2099  1.1.6.2  bouyer 
   2100  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   2101  1.1.6.2  bouyer 
   2102  1.1.6.2  bouyer 	mov.l		(%a6),EXC_A6(%a6)	# in case a6 changes
   2103  1.1.6.2  bouyer 	bsr.l		fout			# call fmove out routine
   2104  1.1.6.2  bouyer 
   2105  1.1.6.2  bouyer # Exceptions in order of precedence:
   2106  1.1.6.2  bouyer # 	BSUN	: no
   2107  1.1.6.2  bouyer #	SNAN	: yes
   2108  1.1.6.2  bouyer #	OPERR	: if ((k_factor > +17) || (dec. exp exceeds 3 digits))
   2109  1.1.6.2  bouyer #	OVFL	: no
   2110  1.1.6.2  bouyer #	UNFL	: no
   2111  1.1.6.2  bouyer #	DZ	: no
   2112  1.1.6.2  bouyer # 	INEX2	: yes
   2113  1.1.6.2  bouyer #	INEX1	: no
   2114  1.1.6.2  bouyer 
   2115  1.1.6.2  bouyer # determine the highest priority exception(if any) set by the
   2116  1.1.6.2  bouyer # emulation routine that has also been enabled by the user.
   2117  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   2118  1.1.6.2  bouyer 	bne.w		fu_out_ena_p		# some are enabled
   2119  1.1.6.2  bouyer 
   2120  1.1.6.2  bouyer fu_out_exit_p:
   2121  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
   2122  1.1.6.2  bouyer 
   2123  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   2124  1.1.6.2  bouyer 	bne.b		fu_out_exit_s_p		# supervisor
   2125  1.1.6.2  bouyer 
   2126  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# update user a7
   2127  1.1.6.2  bouyer 	mov.l		%a0,%usp
   2128  1.1.6.2  bouyer 
   2129  1.1.6.2  bouyer fu_out_exit_cont_p:
   2130  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2131  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2132  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2133  1.1.6.2  bouyer 
   2134  1.1.6.2  bouyer 	unlk		%a6			# unravel stack frame
   2135  1.1.6.2  bouyer 
   2136  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   2137  1.1.6.2  bouyer 	bne.w		fu_trace_p		# yes
   2138  1.1.6.2  bouyer 
   2139  1.1.6.2  bouyer 	bra.l		_fpsp_done		# exit to os
   2140  1.1.6.2  bouyer 
   2141  1.1.6.2  bouyer # the exception occurred in supervisor mode. check to see if the
   2142  1.1.6.2  bouyer # addressing mode was -(a7). if so, we'll need to shift the
   2143  1.1.6.2  bouyer # stack frame "down".
   2144  1.1.6.2  bouyer fu_out_exit_s_p:
   2145  1.1.6.2  bouyer 	btst		&mda7_bit,SPCOND_FLG(%a6) # was ea mode -(a7)
   2146  1.1.6.2  bouyer 	beq.b		fu_out_exit_cont_p	# no
   2147  1.1.6.2  bouyer 
   2148  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2149  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2150  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2151  1.1.6.2  bouyer 
   2152  1.1.6.2  bouyer 	mov.l		(%a6),%a6		# restore frame pointer
   2153  1.1.6.2  bouyer 
   2154  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2155  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2156  1.1.6.2  bouyer 
   2157  1.1.6.2  bouyer # now, copy the result to the proper place on the stack
   2158  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
   2159  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
   2160  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
   2161  1.1.6.2  bouyer 
   2162  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE-0x8,%sp
   2163  1.1.6.2  bouyer 
   2164  1.1.6.2  bouyer 	btst		&0x7,(%sp)
   2165  1.1.6.2  bouyer 	bne.w		fu_trace_p
   2166  1.1.6.2  bouyer 
   2167  1.1.6.2  bouyer 	bra.l		_fpsp_done
   2168  1.1.6.2  bouyer 
   2169  1.1.6.2  bouyer fu_out_ena_p:
   2170  1.1.6.2  bouyer 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
   2171  1.1.6.2  bouyer 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   2172  1.1.6.2  bouyer 	beq.w		fu_out_exit_p
   2173  1.1.6.2  bouyer 
   2174  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
   2175  1.1.6.2  bouyer 
   2176  1.1.6.2  bouyer # an exception occurred and that exception was enabled.
   2177  1.1.6.2  bouyer # the only exception possible on packed move out are INEX, OPERR, and SNAN.
   2178  1.1.6.2  bouyer fu_out_exc_p:
   2179  1.1.6.2  bouyer 	cmpi.b		%d0,&0x1a
   2180  1.1.6.2  bouyer 	bgt.w		fu_inex_p2
   2181  1.1.6.2  bouyer 	beq.w		fu_operr_p
   2182  1.1.6.2  bouyer 
   2183  1.1.6.2  bouyer fu_snan_p:
   2184  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)
   2185  1.1.6.2  bouyer 	bne.b		fu_snan_s_p
   2186  1.1.6.2  bouyer 
   2187  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0
   2188  1.1.6.2  bouyer 	mov.l		%a0,%usp
   2189  1.1.6.2  bouyer 	bra.w		fu_snan
   2190  1.1.6.2  bouyer 
   2191  1.1.6.2  bouyer fu_snan_s_p:
   2192  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2193  1.1.6.2  bouyer 	bne.w		fu_snan
   2194  1.1.6.2  bouyer 
   2195  1.1.6.2  bouyer # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
   2196  1.1.6.2  bouyer # the strategy is to move the exception frame "down" 12 bytes. then, we
   2197  1.1.6.2  bouyer # can store the default result where the exception frame was.
   2198  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2199  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2200  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2201  1.1.6.2  bouyer 
   2202  1.1.6.2  bouyer 	mov.w		&0x30d8,EXC_VOFF(%a6)	# vector offset = 0xd0
   2203  1.1.6.2  bouyer 	mov.w		&0xe006,2+FP_SRC(%a6) 	# set fsave status
   2204  1.1.6.2  bouyer 
   2205  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore src operand
   2206  1.1.6.2  bouyer 
   2207  1.1.6.2  bouyer 	mov.l		(%a6),%a6		# restore frame pointer
   2208  1.1.6.2  bouyer 
   2209  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2210  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2211  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   2212  1.1.6.2  bouyer 
   2213  1.1.6.2  bouyer # now, we copy the default result to it's proper location
   2214  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
   2215  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
   2216  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
   2217  1.1.6.2  bouyer 
   2218  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE-0x8,%sp
   2219  1.1.6.2  bouyer 
   2220  1.1.6.2  bouyer 
   2221  1.1.6.2  bouyer 	bra.l		_real_snan
   2222  1.1.6.2  bouyer 
   2223  1.1.6.2  bouyer fu_operr_p:
   2224  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)
   2225  1.1.6.2  bouyer 	bne.w		fu_operr_p_s
   2226  1.1.6.2  bouyer 
   2227  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0
   2228  1.1.6.2  bouyer 	mov.l		%a0,%usp
   2229  1.1.6.2  bouyer 	bra.w		fu_operr
   2230  1.1.6.2  bouyer 
   2231  1.1.6.2  bouyer fu_operr_p_s:
   2232  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2233  1.1.6.2  bouyer 	bne.w		fu_operr
   2234  1.1.6.2  bouyer 
   2235  1.1.6.2  bouyer # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
   2236  1.1.6.2  bouyer # the strategy is to move the exception frame "down" 12 bytes. then, we
   2237  1.1.6.2  bouyer # can store the default result where the exception frame was.
   2238  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2239  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2240  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2241  1.1.6.2  bouyer 
   2242  1.1.6.2  bouyer 	mov.w		&0x30d0,EXC_VOFF(%a6)	# vector offset = 0xd0
   2243  1.1.6.2  bouyer 	mov.w		&0xe004,2+FP_SRC(%a6) 	# set fsave status
   2244  1.1.6.2  bouyer 
   2245  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore src operand
   2246  1.1.6.2  bouyer 
   2247  1.1.6.2  bouyer 	mov.l		(%a6),%a6		# restore frame pointer
   2248  1.1.6.2  bouyer 
   2249  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2250  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2251  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   2252  1.1.6.2  bouyer 
   2253  1.1.6.2  bouyer # now, we copy the default result to it's proper location
   2254  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
   2255  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
   2256  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
   2257  1.1.6.2  bouyer 
   2258  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE-0x8,%sp
   2259  1.1.6.2  bouyer 
   2260  1.1.6.2  bouyer 
   2261  1.1.6.2  bouyer 	bra.l		_real_operr
   2262  1.1.6.2  bouyer 
   2263  1.1.6.2  bouyer fu_inex_p2:
   2264  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)
   2265  1.1.6.2  bouyer 	bne.w		fu_inex_s_p2
   2266  1.1.6.2  bouyer 
   2267  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0
   2268  1.1.6.2  bouyer 	mov.l		%a0,%usp
   2269  1.1.6.2  bouyer 	bra.w		fu_inex
   2270  1.1.6.2  bouyer 
   2271  1.1.6.2  bouyer fu_inex_s_p2:
   2272  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2273  1.1.6.2  bouyer 	bne.w		fu_inex
   2274  1.1.6.2  bouyer 
   2275  1.1.6.2  bouyer # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
   2276  1.1.6.2  bouyer # the strategy is to move the exception frame "down" 12 bytes. then, we
   2277  1.1.6.2  bouyer # can store the default result where the exception frame was.
   2278  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
   2279  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2280  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2281  1.1.6.2  bouyer 
   2282  1.1.6.2  bouyer 	mov.w		&0x30c4,EXC_VOFF(%a6) 	# vector offset = 0xc4
   2283  1.1.6.2  bouyer 	mov.w		&0xe001,2+FP_SRC(%a6) 	# set fsave status
   2284  1.1.6.2  bouyer 
   2285  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore src operand
   2286  1.1.6.2  bouyer 
   2287  1.1.6.2  bouyer 	mov.l		(%a6),%a6		# restore frame pointer
   2288  1.1.6.2  bouyer 
   2289  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   2290  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
   2291  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   2292  1.1.6.2  bouyer 
   2293  1.1.6.2  bouyer # now, we copy the default result to it's proper location
   2294  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
   2295  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
   2296  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
   2297  1.1.6.2  bouyer 
   2298  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE-0x8,%sp
   2299  1.1.6.2  bouyer 
   2300  1.1.6.2  bouyer 
   2301  1.1.6.2  bouyer 	bra.l		_real_inex
   2302  1.1.6.2  bouyer 
   2303  1.1.6.2  bouyer #########################################################################
   2304  1.1.6.2  bouyer 
   2305  1.1.6.2  bouyer #
   2306  1.1.6.2  bouyer # if we're stuffing a source operand back into an fsave frame then we
   2307  1.1.6.2  bouyer # have to make sure that for single or double source operands that the
   2308  1.1.6.2  bouyer # format stuffed is as weird as the hardware usually makes it.
   2309  1.1.6.2  bouyer #
   2310  1.1.6.2  bouyer 	global		funimp_skew
   2311  1.1.6.2  bouyer funimp_skew:
   2312  1.1.6.2  bouyer 	bfextu		EXC_EXTWORD(%a6){&3:&3},%d0 # extract src specifier
   2313  1.1.6.2  bouyer 	cmpi.b		%d0,&0x1		# was src sgl?
   2314  1.1.6.2  bouyer 	beq.b		funimp_skew_sgl		# yes
   2315  1.1.6.2  bouyer 	cmpi.b		%d0,&0x5		# was src dbl?
   2316  1.1.6.2  bouyer 	beq.b		funimp_skew_dbl		# yes
   2317  1.1.6.2  bouyer 	rts
   2318  1.1.6.2  bouyer 
   2319  1.1.6.2  bouyer funimp_skew_sgl:
   2320  1.1.6.2  bouyer 	mov.w		FP_SRC_EX(%a6),%d0	# fetch DENORM exponent
   2321  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# strip sign
   2322  1.1.6.2  bouyer 	beq.b		funimp_skew_sgl_not
   2323  1.1.6.2  bouyer 	cmpi.w		%d0,&0x3f80
   2324  1.1.6.2  bouyer 	bgt.b		funimp_skew_sgl_not
   2325  1.1.6.2  bouyer 	neg.w		%d0			# make exponent negative
   2326  1.1.6.2  bouyer 	addi.w		&0x3f81,%d0		# find amt to shift
   2327  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d1	# fetch DENORM hi(man)
   2328  1.1.6.2  bouyer 	lsr.l		%d0,%d1			# shift it
   2329  1.1.6.2  bouyer 	bset		&31,%d1			# set j-bit
   2330  1.1.6.2  bouyer 	mov.l		%d1,FP_SRC_HI(%a6)	# insert new hi(man)
   2331  1.1.6.2  bouyer 	andi.w		&0x8000,FP_SRC_EX(%a6)	# clear old exponent
   2332  1.1.6.2  bouyer 	ori.w		&0x3f80,FP_SRC_EX(%a6)	# insert new "skewed" exponent
   2333  1.1.6.2  bouyer funimp_skew_sgl_not:
   2334  1.1.6.2  bouyer 	rts
   2335  1.1.6.2  bouyer 
   2336  1.1.6.2  bouyer funimp_skew_dbl:
   2337  1.1.6.2  bouyer 	mov.w		FP_SRC_EX(%a6),%d0	# fetch DENORM exponent
   2338  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# strip sign
   2339  1.1.6.2  bouyer 	beq.b		funimp_skew_dbl_not
   2340  1.1.6.2  bouyer 	cmpi.w		%d0,&0x3c00
   2341  1.1.6.2  bouyer 	bgt.b		funimp_skew_dbl_not
   2342  1.1.6.2  bouyer 
   2343  1.1.6.2  bouyer 	tst.b		FP_SRC_EX(%a6)		# make "internal format"
   2344  1.1.6.2  bouyer 	smi.b		0x2+FP_SRC(%a6)
   2345  1.1.6.2  bouyer 	mov.w		%d0,FP_SRC_EX(%a6)	# insert exponent with cleared sign
   2346  1.1.6.2  bouyer 	clr.l		%d0			# clear g,r,s
   2347  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src op
   2348  1.1.6.2  bouyer 	mov.w		&0x3c01,%d1		# pass denorm threshold
   2349  1.1.6.2  bouyer 	bsr.l		dnrm_lp			# denorm it
   2350  1.1.6.2  bouyer 	mov.w		&0x3c00,%d0		# new exponent
   2351  1.1.6.2  bouyer 	tst.b		0x2+FP_SRC(%a6)		# is sign set?
   2352  1.1.6.2  bouyer 	beq.b		fss_dbl_denorm_done	# no
   2353  1.1.6.2  bouyer 	bset		&15,%d0			# set sign
   2354  1.1.6.2  bouyer fss_dbl_denorm_done:
   2355  1.1.6.2  bouyer 	bset		&0x7,FP_SRC_HI(%a6)	# set j-bit
   2356  1.1.6.2  bouyer 	mov.w		%d0,FP_SRC_EX(%a6)	# insert new exponent
   2357  1.1.6.2  bouyer funimp_skew_dbl_not:
   2358  1.1.6.2  bouyer 	rts
   2359  1.1.6.2  bouyer 
   2360  1.1.6.2  bouyer #########################################################################
   2361  1.1.6.2  bouyer 	global		_mem_write2
   2362  1.1.6.2  bouyer _mem_write2:
   2363  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)
   2364  1.1.6.2  bouyer 	beq.l		_dmem_write
   2365  1.1.6.2  bouyer 	mov.l		0x0(%a0),FP_DST_EX(%a6)
   2366  1.1.6.2  bouyer 	mov.l		0x4(%a0),FP_DST_HI(%a6)
   2367  1.1.6.2  bouyer 	mov.l		0x8(%a0),FP_DST_LO(%a6)
   2368  1.1.6.2  bouyer 	clr.l		%d1
   2369  1.1.6.2  bouyer 	rts
   2370  1.1.6.2  bouyer 
   2371  1.1.6.2  bouyer #########################################################################
   2372  1.1.6.2  bouyer # XDEF ****************************************************************	#
   2373  1.1.6.2  bouyer #	_fpsp_effadd(): 060FPSP entry point for FP "Unimplemented	#
   2374  1.1.6.2  bouyer #		     	effective address" exception.			#
   2375  1.1.6.2  bouyer #									#
   2376  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
   2377  1.1.6.2  bouyer #	FP Unimplemented Effective Address exception in an operating	#
   2378  1.1.6.2  bouyer #	system.								#
   2379  1.1.6.2  bouyer #									#
   2380  1.1.6.2  bouyer # XREF ****************************************************************	#
   2381  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword			#
   2382  1.1.6.2  bouyer #	fix_skewed_ops() - adjust src operand in fsave frame		#
   2383  1.1.6.2  bouyer #	set_tag_x() - determine optype of src/dst operands		#
   2384  1.1.6.2  bouyer #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   2385  1.1.6.2  bouyer #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
   2386  1.1.6.2  bouyer #	load_fpn2() - load dst operand from FP regfile			#
   2387  1.1.6.2  bouyer #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
   2388  1.1.6.2  bouyer #	decbin() - convert packed data to FP binary data		#
   2389  1.1.6.2  bouyer #	_real_fpu_disabled() - "callout" for "FPU disabled" exception	#
   2390  1.1.6.2  bouyer #	_real_access() - "callout" for access error exception		#
   2391  1.1.6.2  bouyer #	_mem_read() - read extended immediate operand from memory	#
   2392  1.1.6.2  bouyer #	_fpsp_done() - "callout" for exit; work all done		#
   2393  1.1.6.2  bouyer #	_real_trace() - "callout" for Trace enabled exception		#
   2394  1.1.6.2  bouyer #	fmovm_dynamic() - emulate dynamic fmovm instruction		#
   2395  1.1.6.2  bouyer #	fmovm_ctrl() - emulate fmovm control instruction		#
   2396  1.1.6.2  bouyer #									#
   2397  1.1.6.2  bouyer # INPUT ***************************************************************	#
   2398  1.1.6.2  bouyer #	- The system stack contains the "Unimplemented <ea>" stk frame	#
   2399  1.1.6.2  bouyer # 									#
   2400  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   2401  1.1.6.2  bouyer #	If access error:						#
   2402  1.1.6.2  bouyer #	- The system stack is changed to an access error stack frame	#
   2403  1.1.6.2  bouyer #	If FPU disabled:						#
   2404  1.1.6.2  bouyer #	- The system stack is changed to an FPU disabled stack frame	#
   2405  1.1.6.2  bouyer #	If Trace exception enabled:					#
   2406  1.1.6.2  bouyer #	- The system stack is changed to a Trace exception stack frame	#
   2407  1.1.6.2  bouyer #	Else: (normal case)						#
   2408  1.1.6.2  bouyer #	- None (correct result has been stored as appropriate)		#
   2409  1.1.6.2  bouyer #									#
   2410  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   2411  1.1.6.2  bouyer #	This exception handles 3 types of operations:			#
   2412  1.1.6.2  bouyer # (1) FP Instructions using extended precision or packed immediate	#
   2413  1.1.6.2  bouyer #     addressing mode.							#
   2414  1.1.6.2  bouyer # (2) The "fmovm.x" instruction w/ dynamic register specification.	#
   2415  1.1.6.2  bouyer # (3) The "fmovm.l" instruction w/ 2 or 3 control registers.		#
   2416  1.1.6.2  bouyer #									#
   2417  1.1.6.2  bouyer #	For immediate data operations, the data is read in w/ a		#
   2418  1.1.6.2  bouyer # _mem_read() "callout", converted to FP binary (if packed), and used	#
   2419  1.1.6.2  bouyer # as the source operand to the instruction specified by the instruction	#
   2420  1.1.6.2  bouyer # word. If no FP exception should be reported ads a result of the 	#
   2421  1.1.6.2  bouyer # emulation, then the result is stored to the destination register and	#
   2422  1.1.6.2  bouyer # the handler exits through _fpsp_done(). If an enabled exc has been	#
   2423  1.1.6.2  bouyer # signalled as a result of emulation, then an fsave state frame		#
   2424  1.1.6.2  bouyer # corresponding to the FP exception type must be entered into the 060	#
   2425  1.1.6.2  bouyer # FPU before exiting. In either the enabled or disabled cases, we 	#
   2426  1.1.6.2  bouyer # must also check if a Trace exception is pending, in which case, we	#
   2427  1.1.6.2  bouyer # must create a Trace exception stack frame from the current exception	#
   2428  1.1.6.2  bouyer # stack frame. If no Trace is pending, we simply exit through		#
   2429  1.1.6.2  bouyer # _fpsp_done().								#
   2430  1.1.6.2  bouyer #	For "fmovm.x", call the routine fmovm_dynamic() which will 	#
   2431  1.1.6.2  bouyer # decode and emulate the instruction. No FP exceptions can be pending	#
   2432  1.1.6.2  bouyer # as a result of this operation emulation. A Trace exception can be	#
   2433  1.1.6.2  bouyer # pending, though, which means the current stack frame must be changed	#
   2434  1.1.6.2  bouyer # to a Trace stack frame and an exit made through _real_trace().	#
   2435  1.1.6.2  bouyer # For the case of "fmovm.x Dn,-(a7)", where the offending instruction	#
   2436  1.1.6.2  bouyer # was executed from supervisor mode, this handler must store the FP	#
   2437  1.1.6.2  bouyer # register file values to the system stack by itself since		#
   2438  1.1.6.2  bouyer # fmovm_dynamic() can't handle this. A normal exit is made through	#
   2439  1.1.6.2  bouyer # fpsp_done().								#
   2440  1.1.6.2  bouyer #	For "fmovm.l", fmovm_ctrl() is used to emulate the instruction.	#
   2441  1.1.6.2  bouyer # Again, a Trace exception may be pending and an exit made through	#
   2442  1.1.6.2  bouyer # _real_trace(). Else, a normal exit is made through _fpsp_done().	#
   2443  1.1.6.2  bouyer #									#
   2444  1.1.6.2  bouyer #	Before any of the above is attempted, it must be checked to	#
   2445  1.1.6.2  bouyer # see if the FPU is disabled. Since the "Unimp <ea>" exception is taken	#
   2446  1.1.6.2  bouyer # before the "FPU disabled" exception, but the "FPU disabled" exception	#
   2447  1.1.6.2  bouyer # has higher priority, we check the disabled bit in the PCR. If set,	#
   2448  1.1.6.2  bouyer # then we must create an 8 word "FPU disabled" exception stack frame	#
   2449  1.1.6.2  bouyer # from the current 4 word exception stack frame. This includes 		#
   2450  1.1.6.2  bouyer # reproducing the effective address of the instruction to put on the 	#
   2451  1.1.6.2  bouyer # new stack frame.							#
   2452  1.1.6.2  bouyer #									#
   2453  1.1.6.2  bouyer # 	In the process of all emulation work, if a _mem_read()		#
   2454  1.1.6.2  bouyer # "callout" returns a failing result indicating an access error, then	#
   2455  1.1.6.2  bouyer # we must create an access error stack frame from the current stack	#
   2456  1.1.6.2  bouyer # frame. This information includes a faulting address and a fault-	#
   2457  1.1.6.2  bouyer # status-longword. These are created within this handler.		#
   2458  1.1.6.2  bouyer #									#
   2459  1.1.6.2  bouyer #########################################################################
   2460  1.1.6.2  bouyer 
   2461  1.1.6.2  bouyer 	global		_fpsp_effadd
   2462  1.1.6.2  bouyer _fpsp_effadd:
   2463  1.1.6.2  bouyer 
   2464  1.1.6.2  bouyer # This exception type takes priority over the "Line F Emulator"
   2465  1.1.6.2  bouyer # exception. Therefore, the FPU could be disabled when entering here.
   2466  1.1.6.2  bouyer # So, we must check to see if it's disabled and handle that case separately.
   2467  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save d0
   2468  1.1.6.2  bouyer 	movc		%pcr,%d0		# load proc cr
   2469  1.1.6.2  bouyer 	btst		&0x1,%d0		# is FPU disabled?
   2470  1.1.6.2  bouyer 	bne.w		iea_disabled		# yes
   2471  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   2472  1.1.6.2  bouyer 
   2473  1.1.6.2  bouyer 	link		%a6,&-LOCAL_SIZE	# init stack frame
   2474  1.1.6.2  bouyer 
   2475  1.1.6.2  bouyer 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2476  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   2477  1.1.6.2  bouyer 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   2478  1.1.6.2  bouyer 
   2479  1.1.6.2  bouyer # PC of instruction that took the exception is the PC in the frame
   2480  1.1.6.2  bouyer 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
   2481  1.1.6.2  bouyer 
   2482  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   2483  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   2484  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   2485  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
   2486  1.1.6.2  bouyer 
   2487  1.1.6.2  bouyer #########################################################################
   2488  1.1.6.2  bouyer 
   2489  1.1.6.2  bouyer 	tst.w		%d0			# is operation fmovem?
   2490  1.1.6.2  bouyer 	bmi.w		iea_fmovm		# yes
   2491  1.1.6.2  bouyer 
   2492  1.1.6.2  bouyer #
   2493  1.1.6.2  bouyer # here, we will have:
   2494  1.1.6.2  bouyer # 	fabs	fdabs	fsabs		facos		fmod
   2495  1.1.6.2  bouyer #	fadd	fdadd	fsadd		fasin		frem
   2496  1.1.6.2  bouyer # 	fcmp				fatan		fscale
   2497  1.1.6.2  bouyer #	fdiv	fddiv	fsdiv		fatanh		fsin
   2498  1.1.6.2  bouyer #	fint				fcos		fsincos
   2499  1.1.6.2  bouyer #	fintrz				fcosh		fsinh
   2500  1.1.6.2  bouyer #	fmove	fdmove	fsmove		fetox		ftan
   2501  1.1.6.2  bouyer # 	fmul	fdmul	fsmul		fetoxm1		ftanh
   2502  1.1.6.2  bouyer #	fneg	fdneg	fsneg		fgetexp		ftentox
   2503  1.1.6.2  bouyer #	fsgldiv				fgetman		ftwotox
   2504  1.1.6.2  bouyer # 	fsglmul				flog10
   2505  1.1.6.2  bouyer # 	fsqrt				flog2
   2506  1.1.6.2  bouyer #	fsub	fdsub	fssub		flogn
   2507  1.1.6.2  bouyer #	ftst				flognp1
   2508  1.1.6.2  bouyer # which can all use f<op>.{x,p}
   2509  1.1.6.2  bouyer # so, now it's immediate data extended precision AND PACKED FORMAT!
   2510  1.1.6.2  bouyer #
   2511  1.1.6.2  bouyer iea_op:
   2512  1.1.6.2  bouyer 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   2513  1.1.6.2  bouyer 
   2514  1.1.6.2  bouyer 	btst		&0xa,%d0		# is src fmt x or p?
   2515  1.1.6.2  bouyer 	bne.b		iea_op_pack		# packed
   2516  1.1.6.2  bouyer 
   2517  1.1.6.2  bouyer 
   2518  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# pass: ptr to #<data>
   2519  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a1		# pass: ptr to super addr
   2520  1.1.6.2  bouyer 	mov.l		&0xc,%d0		# pass: 12 bytes
   2521  1.1.6.2  bouyer 	bsr.l		_imem_read		# read extended immediate
   2522  1.1.6.2  bouyer 
   2523  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   2524  1.1.6.2  bouyer 	bne.w		iea_iacc		# yes
   2525  1.1.6.2  bouyer 
   2526  1.1.6.2  bouyer 	bra.b		iea_op_setsrc
   2527  1.1.6.2  bouyer 
   2528  1.1.6.2  bouyer iea_op_pack:
   2529  1.1.6.2  bouyer 
   2530  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# pass: ptr to #<data>
   2531  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a1		# pass: ptr to super dst
   2532  1.1.6.2  bouyer 	mov.l		&0xc,%d0		# pass: 12 bytes
   2533  1.1.6.2  bouyer 	bsr.l		_imem_read		# read packed operand
   2534  1.1.6.2  bouyer 
   2535  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   2536  1.1.6.2  bouyer 	bne.w		iea_iacc		# yes
   2537  1.1.6.2  bouyer 
   2538  1.1.6.2  bouyer # The packed operand is an INF or a NAN if the exponent field is all ones.
   2539  1.1.6.2  bouyer 	bfextu		FP_SRC(%a6){&1:&15},%d0	# get exp
   2540  1.1.6.2  bouyer 	cmpi.w		%d0,&0x7fff		# INF or NAN?
   2541  1.1.6.2  bouyer 	beq.b		iea_op_setsrc		# operand is an INF or NAN
   2542  1.1.6.2  bouyer 
   2543  1.1.6.2  bouyer # The packed operand is a zero if the mantissa is all zero, else it's
   2544  1.1.6.2  bouyer # a normal packed op.
   2545  1.1.6.2  bouyer 	mov.b		3+FP_SRC(%a6),%d0	# get byte 4
   2546  1.1.6.2  bouyer 	andi.b		&0x0f,%d0		# clear all but last nybble
   2547  1.1.6.2  bouyer 	bne.b		iea_op_gp_not_spec	# not a zero
   2548  1.1.6.2  bouyer 	tst.l		FP_SRC_HI(%a6)		# is lw 2 zero?
   2549  1.1.6.2  bouyer 	bne.b		iea_op_gp_not_spec	# not a zero
   2550  1.1.6.2  bouyer 	tst.l		FP_SRC_LO(%a6)		# is lw 3 zero?
   2551  1.1.6.2  bouyer 	beq.b		iea_op_setsrc		# operand is a ZERO
   2552  1.1.6.2  bouyer iea_op_gp_not_spec:
   2553  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to packed op
   2554  1.1.6.2  bouyer 	bsr.l		decbin			# convert to extended
   2555  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SRC(%a6)	# make this the srcop
   2556  1.1.6.2  bouyer 
   2557  1.1.6.2  bouyer iea_op_setsrc:
   2558  1.1.6.2  bouyer 	addi.l		&0xc,EXC_EXTWPTR(%a6)	# update extension word pointer
   2559  1.1.6.2  bouyer 
   2560  1.1.6.2  bouyer # FP_SRC now holds the src operand.
   2561  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   2562  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   2563  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# could be ANYTHING!!!
   2564  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   2565  1.1.6.2  bouyer 	bne.b		iea_op_getdst		# no
   2566  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM/DENORM/ZERO
   2567  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# set new optype tag
   2568  1.1.6.2  bouyer iea_op_getdst:
   2569  1.1.6.2  bouyer 	clr.b		STORE_FLG(%a6)		# clear "store result" boolean
   2570  1.1.6.2  bouyer 
   2571  1.1.6.2  bouyer 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   2572  1.1.6.2  bouyer 	beq.b		iea_op_extract		# monadic
   2573  1.1.6.2  bouyer 	btst		&0x4,1+EXC_CMDREG(%a6)	# is operation fsincos,ftst,fcmp?
   2574  1.1.6.2  bouyer 	bne.b		iea_op_spec		# yes
   2575  1.1.6.2  bouyer 
   2576  1.1.6.2  bouyer iea_op_loaddst:
   2577  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
   2578  1.1.6.2  bouyer 	bsr.l		load_fpn2		# load dst operand
   2579  1.1.6.2  bouyer 
   2580  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   2581  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   2582  1.1.6.2  bouyer 	mov.b		%d0,DTAG(%a6)		# could be ANYTHING!!!
   2583  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   2584  1.1.6.2  bouyer 	bne.b		iea_op_extract		# no
   2585  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM/DENORM/ZERO
   2586  1.1.6.2  bouyer 	mov.b		%d0,DTAG(%a6)		# set new optype tag
   2587  1.1.6.2  bouyer 	bra.b		iea_op_extract
   2588  1.1.6.2  bouyer 
   2589  1.1.6.2  bouyer # the operation is fsincos, ftst, or fcmp. only fcmp is dyadic
   2590  1.1.6.2  bouyer iea_op_spec:
   2591  1.1.6.2  bouyer 	btst		&0x3,1+EXC_CMDREG(%a6)	# is operation fsincos?
   2592  1.1.6.2  bouyer 	beq.b		iea_op_extract		# yes
   2593  1.1.6.2  bouyer # now, we're left with ftst and fcmp. so, first let's tag them so that they don't
   2594  1.1.6.2  bouyer # store a result. then, only fcmp will branch back and pick up a dst operand.
   2595  1.1.6.2  bouyer 	st		STORE_FLG(%a6)		# don't store a final result
   2596  1.1.6.2  bouyer 	btst		&0x1,1+EXC_CMDREG(%a6)	# is operation fcmp?
   2597  1.1.6.2  bouyer 	beq.b		iea_op_loaddst		# yes
   2598  1.1.6.2  bouyer 
   2599  1.1.6.2  bouyer iea_op_extract:
   2600  1.1.6.2  bouyer 	clr.l		%d0
   2601  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass: rnd mode,prec
   2602  1.1.6.2  bouyer 
   2603  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1
   2604  1.1.6.2  bouyer 	andi.w		&0x007f,%d1		# extract extension
   2605  1.1.6.2  bouyer 
   2606  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr
   2607  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   2608  1.1.6.2  bouyer 
   2609  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
   2610  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1
   2611  1.1.6.2  bouyer 
   2612  1.1.6.2  bouyer 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
   2613  1.1.6.2  bouyer 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   2614  1.1.6.2  bouyer 
   2615  1.1.6.2  bouyer #
   2616  1.1.6.2  bouyer # Exceptions in order of precedence:
   2617  1.1.6.2  bouyer #	BSUN	: none
   2618  1.1.6.2  bouyer #	SNAN	: all operations
   2619  1.1.6.2  bouyer #	OPERR	: all reg-reg or mem-reg operations that can normally operr
   2620  1.1.6.2  bouyer #	OVFL	: same as OPERR
   2621  1.1.6.2  bouyer #	UNFL	: same as OPERR
   2622  1.1.6.2  bouyer #	DZ	: same as OPERR
   2623  1.1.6.2  bouyer #	INEX2	: same as OPERR
   2624  1.1.6.2  bouyer #	INEX1	: all packed immediate operations
   2625  1.1.6.2  bouyer #
   2626  1.1.6.2  bouyer 
   2627  1.1.6.2  bouyer # we determine the highest priority exception(if any) set by the
   2628  1.1.6.2  bouyer # emulation routine that has also been enabled by the user.
   2629  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   2630  1.1.6.2  bouyer 	bne.b		iea_op_ena		# some are enabled
   2631  1.1.6.2  bouyer 
   2632  1.1.6.2  bouyer # now, we save the result, unless, of course, the operation was ftst or fcmp.
   2633  1.1.6.2  bouyer # these don't save results.
   2634  1.1.6.2  bouyer iea_op_save:
   2635  1.1.6.2  bouyer 	tst.b		STORE_FLG(%a6)		# does this op store a result?
   2636  1.1.6.2  bouyer 	bne.b		iea_op_exit1		# exit with no frestore
   2637  1.1.6.2  bouyer 
   2638  1.1.6.2  bouyer iea_op_store:
   2639  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
   2640  1.1.6.2  bouyer 	bsr.l		store_fpreg		# store the result
   2641  1.1.6.2  bouyer 
   2642  1.1.6.2  bouyer iea_op_exit1:
   2643  1.1.6.2  bouyer 	mov.l		EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
   2644  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
   2645  1.1.6.2  bouyer 
   2646  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   2647  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2648  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2649  1.1.6.2  bouyer 
   2650  1.1.6.2  bouyer 	unlk		%a6			# unravel the frame
   2651  1.1.6.2  bouyer 
   2652  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   2653  1.1.6.2  bouyer 	bne.w		iea_op_trace		# yes
   2654  1.1.6.2  bouyer 
   2655  1.1.6.2  bouyer 	bra.l		_fpsp_done		# exit to os
   2656  1.1.6.2  bouyer 
   2657  1.1.6.2  bouyer iea_op_ena:
   2658  1.1.6.2  bouyer 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enable and set
   2659  1.1.6.2  bouyer 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   2660  1.1.6.2  bouyer 	bne.b		iea_op_exc		# at least one was set
   2661  1.1.6.2  bouyer 
   2662  1.1.6.2  bouyer # no exception occurred. now, did a disabled, exact overflow occur with inexact
   2663  1.1.6.2  bouyer # enabled? if so, then we have to stuff an overflow frame into the FPU.
   2664  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   2665  1.1.6.2  bouyer 	beq.b		iea_op_save
   2666  1.1.6.2  bouyer 
   2667  1.1.6.2  bouyer iea_op_ovfl:
   2668  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
   2669  1.1.6.2  bouyer 	beq.b		iea_op_store		# no
   2670  1.1.6.2  bouyer 	bra.b		iea_op_exc_ovfl		# yes
   2671  1.1.6.2  bouyer 
   2672  1.1.6.2  bouyer # an enabled exception occurred. we have to insert the exception type back into
   2673  1.1.6.2  bouyer # the machine.
   2674  1.1.6.2  bouyer iea_op_exc:
   2675  1.1.6.2  bouyer 	subi.l		&24,%d0			# fix offset to be 0-8
   2676  1.1.6.2  bouyer 	cmpi.b		%d0,&0x6		# is exception INEX?
   2677  1.1.6.2  bouyer 	bne.b		iea_op_exc_force	# no
   2678  1.1.6.2  bouyer 
   2679  1.1.6.2  bouyer # the enabled exception was inexact. so, if it occurs with an overflow
   2680  1.1.6.2  bouyer # or underflow that was disabled, then we have to force an overflow or
   2681  1.1.6.2  bouyer # underflow frame.
   2682  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   2683  1.1.6.2  bouyer 	bne.b		iea_op_exc_ovfl		# yes
   2684  1.1.6.2  bouyer 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur?
   2685  1.1.6.2  bouyer 	bne.b		iea_op_exc_unfl		# yes
   2686  1.1.6.2  bouyer 
   2687  1.1.6.2  bouyer iea_op_exc_force:
   2688  1.1.6.2  bouyer 	mov.w		(tbl_iea_except.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   2689  1.1.6.2  bouyer 	bra.b		iea_op_exit2		# exit with frestore
   2690  1.1.6.2  bouyer 
   2691  1.1.6.2  bouyer tbl_iea_except:
   2692  1.1.6.2  bouyer 	short		0xe002, 0xe006, 0xe004, 0xe005
   2693  1.1.6.2  bouyer 	short		0xe003, 0xe002, 0xe001, 0xe001
   2694  1.1.6.2  bouyer 
   2695  1.1.6.2  bouyer iea_op_exc_ovfl:
   2696  1.1.6.2  bouyer 	mov.w		&0xe005,2+FP_SRC(%a6)
   2697  1.1.6.2  bouyer 	bra.b		iea_op_exit2
   2698  1.1.6.2  bouyer 
   2699  1.1.6.2  bouyer iea_op_exc_unfl:
   2700  1.1.6.2  bouyer 	mov.w		&0xe003,2+FP_SRC(%a6)
   2701  1.1.6.2  bouyer 
   2702  1.1.6.2  bouyer iea_op_exit2:
   2703  1.1.6.2  bouyer 	mov.l		EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
   2704  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
   2705  1.1.6.2  bouyer 
   2706  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   2707  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2708  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2709  1.1.6.2  bouyer 
   2710  1.1.6.2  bouyer 	frestore 	FP_SRC(%a6)		# restore exceptional state
   2711  1.1.6.2  bouyer 
   2712  1.1.6.2  bouyer 	unlk		%a6			# unravel the frame
   2713  1.1.6.2  bouyer 
   2714  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   2715  1.1.6.2  bouyer 	bne.b		iea_op_trace		# yes
   2716  1.1.6.2  bouyer 
   2717  1.1.6.2  bouyer 	bra.l		_fpsp_done		# exit to os
   2718  1.1.6.2  bouyer 
   2719  1.1.6.2  bouyer #
   2720  1.1.6.2  bouyer # The opclass two instruction that took an "Unimplemented Effective Address"
   2721  1.1.6.2  bouyer # exception was being traced. Make the "current" PC the FPIAR and put it in
   2722  1.1.6.2  bouyer # the trace stack frame then jump to _real_trace().
   2723  1.1.6.2  bouyer #
   2724  1.1.6.2  bouyer #		 UNIMP EA FRAME		   TRACE FRAME
   2725  1.1.6.2  bouyer #		*****************	*****************
   2726  1.1.6.2  bouyer #		* 0x0 *  0x0f0	*	*    Current	*
   2727  1.1.6.2  bouyer #		*****************	*      PC	*
   2728  1.1.6.2  bouyer #		*    Current	*	*****************
   2729  1.1.6.2  bouyer #		*      PC	*	* 0x2 *  0x024	*
   2730  1.1.6.2  bouyer #		*****************	*****************
   2731  1.1.6.2  bouyer #		*      SR	*	*     Next	*
   2732  1.1.6.2  bouyer #		*****************	*      PC	*
   2733  1.1.6.2  bouyer #					*****************
   2734  1.1.6.2  bouyer #					*      SR	*
   2735  1.1.6.2  bouyer #					*****************
   2736  1.1.6.2  bouyer iea_op_trace:
   2737  1.1.6.2  bouyer 	mov.l		(%sp),-(%sp)		# shift stack frame "down"
   2738  1.1.6.2  bouyer 	mov.w		0x8(%sp),0x4(%sp)
   2739  1.1.6.2  bouyer 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
   2740  1.1.6.2  bouyer 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
   2741  1.1.6.2  bouyer 
   2742  1.1.6.2  bouyer 	bra.l		_real_trace
   2743  1.1.6.2  bouyer 
   2744  1.1.6.2  bouyer #########################################################################
   2745  1.1.6.2  bouyer iea_fmovm:
   2746  1.1.6.2  bouyer 	btst		&14,%d0			# ctrl or data reg
   2747  1.1.6.2  bouyer 	beq.w		iea_fmovm_ctrl
   2748  1.1.6.2  bouyer 
   2749  1.1.6.2  bouyer iea_fmovm_data:
   2750  1.1.6.2  bouyer 
   2751  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode
   2752  1.1.6.2  bouyer 	bne.b		iea_fmovm_data_s
   2753  1.1.6.2  bouyer 
   2754  1.1.6.2  bouyer iea_fmovm_data_u:
   2755  1.1.6.2  bouyer 	mov.l		%usp,%a0
   2756  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)		# store current a7
   2757  1.1.6.2  bouyer 	bsr.l		fmovm_dynamic		# do dynamic fmovm
   2758  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# load possibly new a7
   2759  1.1.6.2  bouyer 	mov.l		%a0,%usp		# update usp
   2760  1.1.6.2  bouyer 	bra.w		iea_fmovm_exit
   2761  1.1.6.2  bouyer 
   2762  1.1.6.2  bouyer iea_fmovm_data_s:
   2763  1.1.6.2  bouyer 	clr.b		SPCOND_FLG(%a6)
   2764  1.1.6.2  bouyer 	lea		0x2+EXC_VOFF(%a6),%a0
   2765  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)
   2766  1.1.6.2  bouyer 	bsr.l		fmovm_dynamic		# do dynamic fmovm
   2767  1.1.6.2  bouyer 
   2768  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   2769  1.1.6.2  bouyer 	beq.w		iea_fmovm_data_predec
   2770  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mia7_flg
   2771  1.1.6.2  bouyer 	bne.w		iea_fmovm_exit
   2772  1.1.6.2  bouyer 
   2773  1.1.6.2  bouyer # right now, d0 = the size.
   2774  1.1.6.2  bouyer # the data has been fetched from the supervisor stack, but we have not
   2775  1.1.6.2  bouyer # incremented the stack pointer by the appropriate number of bytes.
   2776  1.1.6.2  bouyer # do it here.
   2777  1.1.6.2  bouyer iea_fmovm_data_postinc:
   2778  1.1.6.2  bouyer 	btst		&0x7,EXC_SR(%a6)
   2779  1.1.6.2  bouyer 	bne.b		iea_fmovm_data_pi_trace
   2780  1.1.6.2  bouyer 
   2781  1.1.6.2  bouyer 	mov.w		EXC_SR(%a6),(EXC_SR,%a6,%d0)
   2782  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),(EXC_PC,%a6,%d0)
   2783  1.1.6.2  bouyer 	mov.w		&0x00f0,(EXC_VOFF,%a6,%d0)
   2784  1.1.6.2  bouyer 
   2785  1.1.6.2  bouyer 	lea		(EXC_SR,%a6,%d0),%a0
   2786  1.1.6.2  bouyer 	mov.l		%a0,EXC_SR(%a6)
   2787  1.1.6.2  bouyer 
   2788  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   2789  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2790  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   2791  1.1.6.2  bouyer 
   2792  1.1.6.2  bouyer 	unlk		%a6
   2793  1.1.6.2  bouyer 	mov.l		(%sp)+,%sp
   2794  1.1.6.2  bouyer 	bra.l		_fpsp_done
   2795  1.1.6.2  bouyer 
   2796  1.1.6.2  bouyer iea_fmovm_data_pi_trace:
   2797  1.1.6.2  bouyer 	mov.w		EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
   2798  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),(EXC_PC-0x4,%a6,%d0)
   2799  1.1.6.2  bouyer 	mov.w		&0x2024,(EXC_VOFF-0x4,%a6,%d0)
   2800  1.1.6.2  bouyer 	mov.l		EXC_PC(%a6),(EXC_VOFF+0x2-0x4,%a6,%d0)
   2801  1.1.6.2  bouyer 
   2802  1.1.6.2  bouyer 	lea		(EXC_SR-0x4,%a6,%d0),%a0
   2803  1.1.6.2  bouyer 	mov.l		%a0,EXC_SR(%a6)
   2804  1.1.6.2  bouyer 
   2805  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   2806  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2807  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   2808  1.1.6.2  bouyer 
   2809  1.1.6.2  bouyer 	unlk		%a6
   2810  1.1.6.2  bouyer 	mov.l		(%sp)+,%sp
   2811  1.1.6.2  bouyer 	bra.l		_real_trace
   2812  1.1.6.2  bouyer 
   2813  1.1.6.2  bouyer # right now, d1 = size and d0 = the strg.
   2814  1.1.6.2  bouyer iea_fmovm_data_predec:
   2815  1.1.6.2  bouyer 	mov.b		%d1,EXC_VOFF(%a6)	# store strg
   2816  1.1.6.2  bouyer 	mov.b		%d0,0x1+EXC_VOFF(%a6)	# store size
   2817  1.1.6.2  bouyer 
   2818  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   2819  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2820  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   2821  1.1.6.2  bouyer 
   2822  1.1.6.2  bouyer 	mov.l		(%a6),-(%sp)		# make a copy of a6
   2823  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save d0
   2824  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# save d1
   2825  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),-(%sp)	# make a copy of Next PC
   2826  1.1.6.2  bouyer 
   2827  1.1.6.2  bouyer 	clr.l		%d0
   2828  1.1.6.2  bouyer 	mov.b		0x1+EXC_VOFF(%a6),%d0	# fetch size
   2829  1.1.6.2  bouyer 	neg.l		%d0			# get negative of size
   2830  1.1.6.2  bouyer 
   2831  1.1.6.2  bouyer 	btst		&0x7,EXC_SR(%a6)	# is trace enabled?
   2832  1.1.6.2  bouyer 	beq.b		iea_fmovm_data_p2
   2833  1.1.6.2  bouyer 
   2834  1.1.6.2  bouyer 	mov.w		EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
   2835  1.1.6.2  bouyer 	mov.l		EXC_PC(%a6),(EXC_VOFF-0x2,%a6,%d0)
   2836  1.1.6.2  bouyer 	mov.l		(%sp)+,(EXC_PC-0x4,%a6,%d0)
   2837  1.1.6.2  bouyer 	mov.w		&0x2024,(EXC_VOFF-0x4,%a6,%d0)
   2838  1.1.6.2  bouyer 
   2839  1.1.6.2  bouyer 	pea		(%a6,%d0)		# create final sp
   2840  1.1.6.2  bouyer 	bra.b		iea_fmovm_data_p3
   2841  1.1.6.2  bouyer 
   2842  1.1.6.2  bouyer iea_fmovm_data_p2:
   2843  1.1.6.2  bouyer 	mov.w		EXC_SR(%a6),(EXC_SR,%a6,%d0)
   2844  1.1.6.2  bouyer 	mov.l		(%sp)+,(EXC_PC,%a6,%d0)
   2845  1.1.6.2  bouyer 	mov.w		&0x00f0,(EXC_VOFF,%a6,%d0)
   2846  1.1.6.2  bouyer 
   2847  1.1.6.2  bouyer 	pea		(0x4,%a6,%d0)		# create final sp
   2848  1.1.6.2  bouyer 
   2849  1.1.6.2  bouyer iea_fmovm_data_p3:
   2850  1.1.6.2  bouyer 	clr.l		%d1
   2851  1.1.6.2  bouyer 	mov.b		EXC_VOFF(%a6),%d1	# fetch strg
   2852  1.1.6.2  bouyer 
   2853  1.1.6.2  bouyer 	tst.b		%d1
   2854  1.1.6.2  bouyer 	bpl.b		fm_1
   2855  1.1.6.2  bouyer 	fmovm.x		&0x80,(0x4+0x8,%a6,%d0)
   2856  1.1.6.2  bouyer 	addi.l		&0xc,%d0
   2857  1.1.6.2  bouyer fm_1:
   2858  1.1.6.2  bouyer 	lsl.b		&0x1,%d1
   2859  1.1.6.2  bouyer 	bpl.b		fm_2
   2860  1.1.6.2  bouyer 	fmovm.x		&0x40,(0x4+0x8,%a6,%d0)
   2861  1.1.6.2  bouyer 	addi.l		&0xc,%d0
   2862  1.1.6.2  bouyer fm_2:
   2863  1.1.6.2  bouyer 	lsl.b		&0x1,%d1
   2864  1.1.6.2  bouyer 	bpl.b		fm_3
   2865  1.1.6.2  bouyer 	fmovm.x		&0x20,(0x4+0x8,%a6,%d0)
   2866  1.1.6.2  bouyer 	addi.l		&0xc,%d0
   2867  1.1.6.2  bouyer fm_3:
   2868  1.1.6.2  bouyer 	lsl.b		&0x1,%d1
   2869  1.1.6.2  bouyer 	bpl.b		fm_4
   2870  1.1.6.2  bouyer 	fmovm.x		&0x10,(0x4+0x8,%a6,%d0)
   2871  1.1.6.2  bouyer 	addi.l		&0xc,%d0
   2872  1.1.6.2  bouyer fm_4:
   2873  1.1.6.2  bouyer 	lsl.b		&0x1,%d1
   2874  1.1.6.2  bouyer 	bpl.b		fm_5
   2875  1.1.6.2  bouyer 	fmovm.x		&0x08,(0x4+0x8,%a6,%d0)
   2876  1.1.6.2  bouyer 	addi.l		&0xc,%d0
   2877  1.1.6.2  bouyer fm_5:
   2878  1.1.6.2  bouyer 	lsl.b		&0x1,%d1
   2879  1.1.6.2  bouyer 	bpl.b		fm_6
   2880  1.1.6.2  bouyer 	fmovm.x		&0x04,(0x4+0x8,%a6,%d0)
   2881  1.1.6.2  bouyer 	addi.l		&0xc,%d0
   2882  1.1.6.2  bouyer fm_6:
   2883  1.1.6.2  bouyer 	lsl.b		&0x1,%d1
   2884  1.1.6.2  bouyer 	bpl.b		fm_7
   2885  1.1.6.2  bouyer 	fmovm.x		&0x02,(0x4+0x8,%a6,%d0)
   2886  1.1.6.2  bouyer 	addi.l		&0xc,%d0
   2887  1.1.6.2  bouyer fm_7:
   2888  1.1.6.2  bouyer 	lsl.b		&0x1,%d1
   2889  1.1.6.2  bouyer 	bpl.b		fm_end
   2890  1.1.6.2  bouyer 	fmovm.x		&0x01,(0x4+0x8,%a6,%d0)
   2891  1.1.6.2  bouyer fm_end:
   2892  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d1
   2893  1.1.6.2  bouyer 	mov.l		0x8(%sp),%d0
   2894  1.1.6.2  bouyer 	mov.l		0xc(%sp),%a6
   2895  1.1.6.2  bouyer 	mov.l		(%sp)+,%sp
   2896  1.1.6.2  bouyer 
   2897  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace enabled?
   2898  1.1.6.2  bouyer 	beq.l		_fpsp_done
   2899  1.1.6.2  bouyer 	bra.l		_real_trace
   2900  1.1.6.2  bouyer 
   2901  1.1.6.2  bouyer #########################################################################
   2902  1.1.6.2  bouyer iea_fmovm_ctrl:
   2903  1.1.6.2  bouyer 
   2904  1.1.6.2  bouyer 	bsr.l		fmovm_ctrl		# load ctrl regs
   2905  1.1.6.2  bouyer 
   2906  1.1.6.2  bouyer iea_fmovm_exit:
   2907  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   2908  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   2909  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   2910  1.1.6.2  bouyer 
   2911  1.1.6.2  bouyer 	btst		&0x7,EXC_SR(%a6)	# is trace on?
   2912  1.1.6.2  bouyer 	bne.b		iea_fmovm_trace		# yes
   2913  1.1.6.2  bouyer 
   2914  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set Next PC
   2915  1.1.6.2  bouyer 
   2916  1.1.6.2  bouyer 	unlk		%a6			# unravel the frame
   2917  1.1.6.2  bouyer 
   2918  1.1.6.2  bouyer 	bra.l		_fpsp_done		# exit to os
   2919  1.1.6.2  bouyer 
   2920  1.1.6.2  bouyer #
   2921  1.1.6.2  bouyer # The control reg instruction that took an "Unimplemented Effective Address"
   2922  1.1.6.2  bouyer # exception was being traced. The "Current PC" for the trace frame is the
   2923  1.1.6.2  bouyer # PC stacked for Unimp EA. The "Next PC" is in EXC_EXTWPTR.
   2924  1.1.6.2  bouyer # After fixing the stack frame, jump to _real_trace().
   2925  1.1.6.2  bouyer #
   2926  1.1.6.2  bouyer #		 UNIMP EA FRAME		   TRACE FRAME
   2927  1.1.6.2  bouyer #		*****************	*****************
   2928  1.1.6.2  bouyer #		* 0x0 *  0x0f0	*	*    Current	*
   2929  1.1.6.2  bouyer #		*****************	*      PC	*
   2930  1.1.6.2  bouyer #		*    Current	*	*****************
   2931  1.1.6.2  bouyer #		*      PC	*	* 0x2 *  0x024	*
   2932  1.1.6.2  bouyer #		*****************	*****************
   2933  1.1.6.2  bouyer #		*      SR	*	*     Next	*
   2934  1.1.6.2  bouyer #		*****************	*      PC	*
   2935  1.1.6.2  bouyer #					*****************
   2936  1.1.6.2  bouyer #					*      SR	*
   2937  1.1.6.2  bouyer #					*****************
   2938  1.1.6.2  bouyer # this ain't a pretty solution, but it works:
   2939  1.1.6.2  bouyer # -restore a6 (not with unlk)
   2940  1.1.6.2  bouyer # -shift stack frame down over where old a6 used to be
   2941  1.1.6.2  bouyer # -add LOCAL_SIZE to stack pointer
   2942  1.1.6.2  bouyer iea_fmovm_trace:
   2943  1.1.6.2  bouyer 	mov.l		(%a6),%a6		# restore frame pointer
   2944  1.1.6.2  bouyer 	mov.w		EXC_SR+LOCAL_SIZE(%sp),0x0+LOCAL_SIZE(%sp)
   2945  1.1.6.2  bouyer 	mov.l		EXC_PC+LOCAL_SIZE(%sp),0x8+LOCAL_SIZE(%sp)
   2946  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR+LOCAL_SIZE(%sp),0x2+LOCAL_SIZE(%sp)
   2947  1.1.6.2  bouyer 	mov.w		&0x2024,0x6+LOCAL_SIZE(%sp) # stk fmt = 0x2; voff = 0x024
   2948  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE,%sp		# clear stack frame
   2949  1.1.6.2  bouyer 
   2950  1.1.6.2  bouyer 	bra.l		_real_trace
   2951  1.1.6.2  bouyer 
   2952  1.1.6.2  bouyer #########################################################################
   2953  1.1.6.2  bouyer # The FPU is disabled and so we should really have taken the "Line
   2954  1.1.6.2  bouyer # F Emulator" exception. So, here we create an 8-word stack frame
   2955  1.1.6.2  bouyer # from our 4-word stack frame. This means we must calculate the length
   2956  1.1.6.2  bouyer # of the faulting instruction to get the "next PC". This is trivial for
   2957  1.1.6.2  bouyer # immediate operands but requires some extra work for fmovm dynamic
   2958  1.1.6.2  bouyer # which can use most addressing modes.
   2959  1.1.6.2  bouyer iea_disabled:
   2960  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   2961  1.1.6.2  bouyer 
   2962  1.1.6.2  bouyer 	link		%a6,&-LOCAL_SIZE	# init stack frame
   2963  1.1.6.2  bouyer 
   2964  1.1.6.2  bouyer 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   2965  1.1.6.2  bouyer 
   2966  1.1.6.2  bouyer # PC of instruction that took the exception is the PC in the frame
   2967  1.1.6.2  bouyer 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
   2968  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   2969  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   2970  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   2971  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
   2972  1.1.6.2  bouyer 
   2973  1.1.6.2  bouyer 	tst.w		%d0			# is instr fmovm?
   2974  1.1.6.2  bouyer 	bmi.b		iea_dis_fmovm		# yes
   2975  1.1.6.2  bouyer # instruction is using an extended precision immediate operand. therefore,
   2976  1.1.6.2  bouyer # the total instruction length is 16 bytes.
   2977  1.1.6.2  bouyer iea_dis_immed:
   2978  1.1.6.2  bouyer 	mov.l		&0x10,%d0		# 16 bytes of instruction
   2979  1.1.6.2  bouyer 	bra.b		iea_dis_cont
   2980  1.1.6.2  bouyer iea_dis_fmovm:
   2981  1.1.6.2  bouyer 	btst		&0xe,%d0		# is instr fmovm ctrl
   2982  1.1.6.2  bouyer 	bne.b		iea_dis_fmovm_data	# no
   2983  1.1.6.2  bouyer # the instruction is a fmovm.l with 2 or 3 registers.
   2984  1.1.6.2  bouyer 	bfextu		%d0{&19:&3},%d1
   2985  1.1.6.2  bouyer 	mov.l		&0xc,%d0
   2986  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# move all regs?
   2987  1.1.6.2  bouyer 	bne.b		iea_dis_cont
   2988  1.1.6.2  bouyer 	addq.l		&0x4,%d0
   2989  1.1.6.2  bouyer 	bra.b		iea_dis_cont
   2990  1.1.6.2  bouyer # the instruction is an fmovm.x dynamic which can use many addressing
   2991  1.1.6.2  bouyer # modes and thus can have several different total instruction lengths.
   2992  1.1.6.2  bouyer # call fmovm_calc_ea which will go through the ea calc process and,
   2993  1.1.6.2  bouyer # as a by-product, will tell us how long the instruction is.
   2994  1.1.6.2  bouyer iea_dis_fmovm_data:
   2995  1.1.6.2  bouyer 	clr.l		%d0
   2996  1.1.6.2  bouyer 	bsr.l		fmovm_calc_ea
   2997  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%d0
   2998  1.1.6.2  bouyer 	sub.l		EXC_PC(%a6),%d0
   2999  1.1.6.2  bouyer iea_dis_cont:
   3000  1.1.6.2  bouyer 	mov.w		%d0,EXC_VOFF(%a6)	# store stack shift value
   3001  1.1.6.2  bouyer 
   3002  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3003  1.1.6.2  bouyer 
   3004  1.1.6.2  bouyer 	unlk		%a6
   3005  1.1.6.2  bouyer 
   3006  1.1.6.2  bouyer # here, we actually create the 8-word frame from the 4-word frame,
   3007  1.1.6.2  bouyer # with the "next PC" as additional info.
   3008  1.1.6.2  bouyer # the <ea> field is let as undefined.
   3009  1.1.6.2  bouyer 	subq.l		&0x8,%sp		# make room for new stack
   3010  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save d0
   3011  1.1.6.2  bouyer 	mov.w		0xc(%sp),0x4(%sp)	# move SR
   3012  1.1.6.2  bouyer 	mov.l		0xe(%sp),0x6(%sp)	# move Current PC
   3013  1.1.6.2  bouyer 	clr.l		%d0
   3014  1.1.6.2  bouyer 	mov.w		0x12(%sp),%d0
   3015  1.1.6.2  bouyer 	mov.l		0x6(%sp),0x10(%sp)	# move Current PC
   3016  1.1.6.2  bouyer 	add.l		%d0,0x6(%sp)		# make Next PC
   3017  1.1.6.2  bouyer 	mov.w		&0x402c,0xa(%sp)	# insert offset,frame format
   3018  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   3019  1.1.6.2  bouyer 
   3020  1.1.6.2  bouyer 	bra.l		_real_fpu_disabled
   3021  1.1.6.2  bouyer 
   3022  1.1.6.2  bouyer ##########
   3023  1.1.6.2  bouyer 
   3024  1.1.6.2  bouyer iea_iacc:
   3025  1.1.6.2  bouyer 	movc		%pcr,%d0
   3026  1.1.6.2  bouyer 	btst		&0x1,%d0
   3027  1.1.6.2  bouyer 	bne.b		iea_iacc_cont
   3028  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3029  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1 on stack
   3030  1.1.6.2  bouyer iea_iacc_cont:
   3031  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3032  1.1.6.2  bouyer 
   3033  1.1.6.2  bouyer 	unlk		%a6
   3034  1.1.6.2  bouyer 
   3035  1.1.6.2  bouyer 	subq.w		&0x8,%sp		# make stack frame bigger
   3036  1.1.6.2  bouyer 	mov.l		0x8(%sp),(%sp)		# store SR,hi(PC)
   3037  1.1.6.2  bouyer 	mov.w		0xc(%sp),0x4(%sp)	# store lo(PC)
   3038  1.1.6.2  bouyer 	mov.w		&0x4008,0x6(%sp)	# store voff
   3039  1.1.6.2  bouyer 	mov.l		0x2(%sp),0x8(%sp)	# store ea
   3040  1.1.6.2  bouyer 	mov.l		&0x09428001,0xc(%sp)	# store fslw
   3041  1.1.6.2  bouyer 
   3042  1.1.6.2  bouyer iea_acc_done:
   3043  1.1.6.2  bouyer 	btst		&0x5,(%sp)		# user or supervisor mode?
   3044  1.1.6.2  bouyer 	beq.b		iea_acc_done2		# user
   3045  1.1.6.2  bouyer 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
   3046  1.1.6.2  bouyer 
   3047  1.1.6.2  bouyer iea_acc_done2:
   3048  1.1.6.2  bouyer 	bra.l		_real_access
   3049  1.1.6.2  bouyer 
   3050  1.1.6.2  bouyer iea_dacc:
   3051  1.1.6.2  bouyer 	lea		-LOCAL_SIZE(%a6),%sp
   3052  1.1.6.2  bouyer 
   3053  1.1.6.2  bouyer 	movc		%pcr,%d1
   3054  1.1.6.2  bouyer 	btst		&0x1,%d1
   3055  1.1.6.2  bouyer 	bne.b		iea_dacc_cont
   3056  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1 on stack
   3057  1.1.6.2  bouyer 	fmovm.l		LOCAL_SIZE+USER_FPCR(%sp),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3058  1.1.6.2  bouyer iea_dacc_cont:
   3059  1.1.6.2  bouyer 	mov.l		(%a6),%a6
   3060  1.1.6.2  bouyer 
   3061  1.1.6.2  bouyer 	mov.l		0x4+LOCAL_SIZE(%sp),-0x8+0x4+LOCAL_SIZE(%sp)
   3062  1.1.6.2  bouyer 	mov.w		0x8+LOCAL_SIZE(%sp),-0x8+0x8+LOCAL_SIZE(%sp)
   3063  1.1.6.2  bouyer 	mov.w		&0x4008,-0x8+0xa+LOCAL_SIZE(%sp)
   3064  1.1.6.2  bouyer 	mov.l		%a0,-0x8+0xc+LOCAL_SIZE(%sp)
   3065  1.1.6.2  bouyer 	mov.w		%d0,-0x8+0x10+LOCAL_SIZE(%sp)
   3066  1.1.6.2  bouyer 	mov.w		&0x0001,-0x8+0x12+LOCAL_SIZE(%sp)
   3067  1.1.6.2  bouyer 
   3068  1.1.6.2  bouyer 	movm.l		LOCAL_SIZE+EXC_DREGS(%sp),&0x0303 # restore d0-d1/a0-a1
   3069  1.1.6.2  bouyer 	add.w		&LOCAL_SIZE-0x4,%sp
   3070  1.1.6.2  bouyer 
   3071  1.1.6.2  bouyer 	bra.b		iea_acc_done
   3072  1.1.6.2  bouyer 
   3073  1.1.6.2  bouyer #########################################################################
   3074  1.1.6.2  bouyer # XDEF ****************************************************************	#
   3075  1.1.6.2  bouyer #	_fpsp_operr(): 060FPSP entry point for FP Operr exception.	#
   3076  1.1.6.2  bouyer #									#
   3077  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
   3078  1.1.6.2  bouyer # 	FP Operand Error exception in an operating system.		#
   3079  1.1.6.2  bouyer #									#
   3080  1.1.6.2  bouyer # XREF ****************************************************************	#
   3081  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword			#
   3082  1.1.6.2  bouyer #	fix_skewed_ops() - adjust src operand in fsave frame		#
   3083  1.1.6.2  bouyer #	_real_operr() - "callout" to operating system operr handler	#
   3084  1.1.6.2  bouyer #	_dmem_write_{byte,word,long}() - store data to mem (opclass 3)	#
   3085  1.1.6.2  bouyer #	store_dreg_{b,w,l}() - store data to data regfile (opclass 3)	#
   3086  1.1.6.2  bouyer #	facc_out_{b,w,l}() - store to memory took access error (opcl 3)	#
   3087  1.1.6.2  bouyer #									#
   3088  1.1.6.2  bouyer # INPUT ***************************************************************	#
   3089  1.1.6.2  bouyer #	- The system stack contains the FP Operr exception frame	#
   3090  1.1.6.2  bouyer #	- The fsave frame contains the source operand			#
   3091  1.1.6.2  bouyer # 									#
   3092  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   3093  1.1.6.2  bouyer #	No access error:						#
   3094  1.1.6.2  bouyer #	- The system stack is unchanged					#
   3095  1.1.6.2  bouyer #	- The fsave frame contains the adjusted src op for opclass 0,2	#
   3096  1.1.6.2  bouyer #									#
   3097  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   3098  1.1.6.2  bouyer #	In a system where the FP Operr exception is enabled, the goal	#
   3099  1.1.6.2  bouyer # is to get to the handler specified at _real_operr(). But, on the 060,	#
   3100  1.1.6.2  bouyer # for opclass zero and two instruction taking this exception, the 	#
   3101  1.1.6.2  bouyer # input operand in the fsave frame may be incorrect for some cases	#
   3102  1.1.6.2  bouyer # and needs to be corrected. This handler calls fix_skewed_ops() to	#
   3103  1.1.6.2  bouyer # do just this and then exits through _real_operr().			#
   3104  1.1.6.2  bouyer #	For opclass 3 instructions, the 060 doesn't store the default	#
   3105  1.1.6.2  bouyer # operr result out to memory or data register file as it should.	#
   3106  1.1.6.2  bouyer # This code must emulate the move out before finally exiting through	#
   3107  1.1.6.2  bouyer # _real_inex(). The move out, if to memory, is performed using 		#
   3108  1.1.6.2  bouyer # _mem_write() "callout" routines that may return a failing result.	#
   3109  1.1.6.2  bouyer # In this special case, the handler must exit through facc_out() 	#
   3110  1.1.6.2  bouyer # which creates an access error stack frame from the current operr	#
   3111  1.1.6.2  bouyer # stack frame.								#
   3112  1.1.6.2  bouyer #									#
   3113  1.1.6.2  bouyer #########################################################################
   3114  1.1.6.2  bouyer 
   3115  1.1.6.2  bouyer 	global		_fpsp_operr
   3116  1.1.6.2  bouyer _fpsp_operr:
   3117  1.1.6.2  bouyer 
   3118  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3119  1.1.6.2  bouyer 
   3120  1.1.6.2  bouyer 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3121  1.1.6.2  bouyer 
   3122  1.1.6.2  bouyer  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3123  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3124  1.1.6.2  bouyer  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3125  1.1.6.2  bouyer 
   3126  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction
   3127  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3128  1.1.6.2  bouyer 
   3129  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3130  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3131  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   3132  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)
   3133  1.1.6.2  bouyer 
   3134  1.1.6.2  bouyer ##############################################################################
   3135  1.1.6.2  bouyer 
   3136  1.1.6.2  bouyer 	btst		&13,%d0			# is instr an fmove out?
   3137  1.1.6.2  bouyer 	bne.b		foperr_out		# fmove out
   3138  1.1.6.2  bouyer 
   3139  1.1.6.2  bouyer 
   3140  1.1.6.2  bouyer # here, we simply see if the operand in the fsave frame needs to be "unskewed".
   3141  1.1.6.2  bouyer # this would be the case for opclass two operations with a source infinity or
   3142  1.1.6.2  bouyer # denorm operand in the sgl or dbl format. NANs also become skewed, but can't
   3143  1.1.6.2  bouyer # cause an operr so we don't need to check for them here.
   3144  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3145  1.1.6.2  bouyer 	bsr.l		fix_skewed_ops		# fix src op
   3146  1.1.6.2  bouyer 
   3147  1.1.6.2  bouyer foperr_exit:
   3148  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3149  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3150  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3151  1.1.6.2  bouyer 
   3152  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)
   3153  1.1.6.2  bouyer 
   3154  1.1.6.2  bouyer 	unlk		%a6
   3155  1.1.6.2  bouyer 	bra.l		_real_operr
   3156  1.1.6.2  bouyer 
   3157  1.1.6.2  bouyer ########################################################################
   3158  1.1.6.2  bouyer 
   3159  1.1.6.2  bouyer #
   3160  1.1.6.2  bouyer # the hardware does not save the default result to memory on enabled
   3161  1.1.6.2  bouyer # operand error exceptions. we do this here before passing control to
   3162  1.1.6.2  bouyer # the user operand error handler.
   3163  1.1.6.2  bouyer #
   3164  1.1.6.2  bouyer # byte, word, and long destination format operations can pass
   3165  1.1.6.2  bouyer # through here. we simply need to test the sign of the src
   3166  1.1.6.2  bouyer # operand and save the appropriate minimum or maximum integer value
   3167  1.1.6.2  bouyer # to the effective address as pointed to by the stacked effective address.
   3168  1.1.6.2  bouyer #
   3169  1.1.6.2  bouyer # although packed opclass three operations can take operand error
   3170  1.1.6.2  bouyer # exceptions, they won't pass through here since they are caught
   3171  1.1.6.2  bouyer # first by the unsupported data format exception handler. that handler
   3172  1.1.6.2  bouyer # sends them directly to _real_operr() if necessary.
   3173  1.1.6.2  bouyer #
   3174  1.1.6.2  bouyer foperr_out:
   3175  1.1.6.2  bouyer 
   3176  1.1.6.2  bouyer 	mov.w		FP_SRC_EX(%a6),%d1	# fetch exponent
   3177  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   3178  1.1.6.2  bouyer 	cmpi.w		%d1,&0x7fff
   3179  1.1.6.2  bouyer 	bne.b		foperr_out_not_qnan
   3180  1.1.6.2  bouyer # the operand is either an infinity or a QNAN.
   3181  1.1.6.2  bouyer 	tst.l		FP_SRC_LO(%a6)
   3182  1.1.6.2  bouyer 	bne.b		foperr_out_qnan
   3183  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d1
   3184  1.1.6.2  bouyer 	andi.l		&0x7fffffff,%d1
   3185  1.1.6.2  bouyer 	beq.b		foperr_out_not_qnan
   3186  1.1.6.2  bouyer foperr_out_qnan:
   3187  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),L_SCR1(%a6)
   3188  1.1.6.2  bouyer 	bra.b		foperr_out_jmp
   3189  1.1.6.2  bouyer 
   3190  1.1.6.2  bouyer foperr_out_not_qnan:
   3191  1.1.6.2  bouyer 	mov.l		&0x7fffffff,%d1
   3192  1.1.6.2  bouyer 	tst.b		FP_SRC_EX(%a6)
   3193  1.1.6.2  bouyer 	bpl.b		foperr_out_not_qnan2
   3194  1.1.6.2  bouyer 	addq.l		&0x1,%d1
   3195  1.1.6.2  bouyer foperr_out_not_qnan2:
   3196  1.1.6.2  bouyer 	mov.l		%d1,L_SCR1(%a6)
   3197  1.1.6.2  bouyer 
   3198  1.1.6.2  bouyer foperr_out_jmp:
   3199  1.1.6.2  bouyer 	bfextu		%d0{&19:&3},%d0		# extract dst format field
   3200  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract <ea> mode,reg
   3201  1.1.6.2  bouyer 	mov.w		(tbl_operr.b,%pc,%d0.w*2),%a0
   3202  1.1.6.2  bouyer 	jmp		(tbl_operr.b,%pc,%a0)
   3203  1.1.6.2  bouyer 
   3204  1.1.6.2  bouyer tbl_operr:
   3205  1.1.6.2  bouyer 	short		foperr_out_l - tbl_operr # long word integer
   3206  1.1.6.2  bouyer 	short		tbl_operr    - tbl_operr # sgl prec shouldn't happen
   3207  1.1.6.2  bouyer 	short		tbl_operr    - tbl_operr # ext prec shouldn't happen
   3208  1.1.6.2  bouyer 	short		foperr_exit  - tbl_operr # packed won't enter here
   3209  1.1.6.2  bouyer 	short		foperr_out_w - tbl_operr # word integer
   3210  1.1.6.2  bouyer 	short		tbl_operr    - tbl_operr # dbl prec shouldn't happen
   3211  1.1.6.2  bouyer 	short		foperr_out_b - tbl_operr # byte integer
   3212  1.1.6.2  bouyer 	short		tbl_operr    - tbl_operr # packed won't enter here
   3213  1.1.6.2  bouyer 
   3214  1.1.6.2  bouyer foperr_out_b:
   3215  1.1.6.2  bouyer 	mov.b		L_SCR1(%a6),%d0		# load positive default result
   3216  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3217  1.1.6.2  bouyer 	ble.b		foperr_out_b_save_dn	# yes
   3218  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3219  1.1.6.2  bouyer 	bsr.l		_dmem_write_byte	# write the default result
   3220  1.1.6.2  bouyer 
   3221  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3222  1.1.6.2  bouyer 	bne.l		facc_out_b		# yes
   3223  1.1.6.2  bouyer 
   3224  1.1.6.2  bouyer 	bra.w		foperr_exit
   3225  1.1.6.2  bouyer foperr_out_b_save_dn:
   3226  1.1.6.2  bouyer 	andi.w		&0x0007,%d1
   3227  1.1.6.2  bouyer 	bsr.l		store_dreg_b		# store result to regfile
   3228  1.1.6.2  bouyer 	bra.w		foperr_exit
   3229  1.1.6.2  bouyer 
   3230  1.1.6.2  bouyer foperr_out_w:
   3231  1.1.6.2  bouyer 	mov.w		L_SCR1(%a6),%d0		# load positive default result
   3232  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3233  1.1.6.2  bouyer 	ble.b		foperr_out_w_save_dn	# yes
   3234  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3235  1.1.6.2  bouyer 	bsr.l		_dmem_write_word	# write the default result
   3236  1.1.6.2  bouyer 
   3237  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3238  1.1.6.2  bouyer 	bne.l		facc_out_w		# yes
   3239  1.1.6.2  bouyer 
   3240  1.1.6.2  bouyer 	bra.w		foperr_exit
   3241  1.1.6.2  bouyer foperr_out_w_save_dn:
   3242  1.1.6.2  bouyer 	andi.w		&0x0007,%d1
   3243  1.1.6.2  bouyer 	bsr.l		store_dreg_w		# store result to regfile
   3244  1.1.6.2  bouyer 	bra.w		foperr_exit
   3245  1.1.6.2  bouyer 
   3246  1.1.6.2  bouyer foperr_out_l:
   3247  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d0		# load positive default result
   3248  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3249  1.1.6.2  bouyer 	ble.b		foperr_out_l_save_dn	# yes
   3250  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3251  1.1.6.2  bouyer 	bsr.l		_dmem_write_long	# write the default result
   3252  1.1.6.2  bouyer 
   3253  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3254  1.1.6.2  bouyer 	bne.l		facc_out_l		# yes
   3255  1.1.6.2  bouyer 
   3256  1.1.6.2  bouyer 	bra.w		foperr_exit
   3257  1.1.6.2  bouyer foperr_out_l_save_dn:
   3258  1.1.6.2  bouyer 	andi.w		&0x0007,%d1
   3259  1.1.6.2  bouyer 	bsr.l		store_dreg_l		# store result to regfile
   3260  1.1.6.2  bouyer 	bra.w		foperr_exit
   3261  1.1.6.2  bouyer 
   3262  1.1.6.2  bouyer #########################################################################
   3263  1.1.6.2  bouyer # XDEF ****************************************************************	#
   3264  1.1.6.2  bouyer #	_fpsp_snan(): 060FPSP entry point for FP SNAN exception.	#
   3265  1.1.6.2  bouyer #									#
   3266  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
   3267  1.1.6.2  bouyer # 	FP Signalling NAN exception in an operating system.		#
   3268  1.1.6.2  bouyer #									#
   3269  1.1.6.2  bouyer # XREF ****************************************************************	#
   3270  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword			#
   3271  1.1.6.2  bouyer #	fix_skewed_ops() - adjust src operand in fsave frame		#
   3272  1.1.6.2  bouyer #	_real_snan() - "callout" to operating system SNAN handler	#
   3273  1.1.6.2  bouyer #	_dmem_write_{byte,word,long}() - store data to mem (opclass 3)	#
   3274  1.1.6.2  bouyer #	store_dreg_{b,w,l}() - store data to data regfile (opclass 3)	#
   3275  1.1.6.2  bouyer #	facc_out_{b,w,l,d,x}() - store to mem took acc error (opcl 3)	#
   3276  1.1.6.2  bouyer #	_calc_ea_fout() - fix An if <ea> is -() or ()+; also get <ea>	#
   3277  1.1.6.2  bouyer #									#
   3278  1.1.6.2  bouyer # INPUT ***************************************************************	#
   3279  1.1.6.2  bouyer #	- The system stack contains the FP SNAN exception frame		#
   3280  1.1.6.2  bouyer #	- The fsave frame contains the source operand			#
   3281  1.1.6.2  bouyer # 									#
   3282  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   3283  1.1.6.2  bouyer #	No access error:						#
   3284  1.1.6.2  bouyer #	- The system stack is unchanged					#
   3285  1.1.6.2  bouyer #	- The fsave frame contains the adjusted src op for opclass 0,2	#
   3286  1.1.6.2  bouyer #									#
   3287  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   3288  1.1.6.2  bouyer #	In a system where the FP SNAN exception is enabled, the goal	#
   3289  1.1.6.2  bouyer # is to get to the handler specified at _real_snan(). But, on the 060,	#
   3290  1.1.6.2  bouyer # for opclass zero and two instructions taking this exception, the 	#
   3291  1.1.6.2  bouyer # input operand in the fsave frame may be incorrect for some cases	#
   3292  1.1.6.2  bouyer # and needs to be corrected. This handler calls fix_skewed_ops() to	#
   3293  1.1.6.2  bouyer # do just this and then exits through _real_snan().			#
   3294  1.1.6.2  bouyer #	For opclass 3 instructions, the 060 doesn't store the default	#
   3295  1.1.6.2  bouyer # SNAN result out to memory or data register file as it should.		#
   3296  1.1.6.2  bouyer # This code must emulate the move out before finally exiting through	#
   3297  1.1.6.2  bouyer # _real_snan(). The move out, if to memory, is performed using 		#
   3298  1.1.6.2  bouyer # _mem_write() "callout" routines that may return a failing result.	#
   3299  1.1.6.2  bouyer # In this special case, the handler must exit through facc_out() 	#
   3300  1.1.6.2  bouyer # which creates an access error stack frame from the current SNAN	#
   3301  1.1.6.2  bouyer # stack frame.								#
   3302  1.1.6.2  bouyer #	For the case of an extended precision opclass 3 instruction,	#
   3303  1.1.6.2  bouyer # if the effective addressing mode was -() or ()+, then the address	#
   3304  1.1.6.2  bouyer # register must get updated by calling _calc_ea_fout(). If the <ea>	#
   3305  1.1.6.2  bouyer # was -(a7) from supervisor mode, then the exception frame currently	#
   3306  1.1.6.2  bouyer # on the system stack must be carefully moved "down" to make room	#
   3307  1.1.6.2  bouyer # for the operand being moved.						#
   3308  1.1.6.2  bouyer #									#
   3309  1.1.6.2  bouyer #########################################################################
   3310  1.1.6.2  bouyer 
   3311  1.1.6.2  bouyer 	global		_fpsp_snan
   3312  1.1.6.2  bouyer _fpsp_snan:
   3313  1.1.6.2  bouyer 
   3314  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3315  1.1.6.2  bouyer 
   3316  1.1.6.2  bouyer 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3317  1.1.6.2  bouyer 
   3318  1.1.6.2  bouyer  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3319  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3320  1.1.6.2  bouyer  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3321  1.1.6.2  bouyer 
   3322  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction
   3323  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3324  1.1.6.2  bouyer 
   3325  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3326  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3327  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   3328  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)
   3329  1.1.6.2  bouyer 
   3330  1.1.6.2  bouyer ##############################################################################
   3331  1.1.6.2  bouyer 
   3332  1.1.6.2  bouyer 	btst		&13,%d0			# is instr an fmove out?
   3333  1.1.6.2  bouyer 	bne.w		fsnan_out		# fmove out
   3334  1.1.6.2  bouyer 
   3335  1.1.6.2  bouyer 
   3336  1.1.6.2  bouyer # here, we simply see if the operand in the fsave frame needs to be "unskewed".
   3337  1.1.6.2  bouyer # this would be the case for opclass two operations with a source infinity or
   3338  1.1.6.2  bouyer # denorm operand in the sgl or dbl format. NANs also become skewed and must be
   3339  1.1.6.2  bouyer # fixed here.
   3340  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3341  1.1.6.2  bouyer 	bsr.l		fix_skewed_ops		# fix src op
   3342  1.1.6.2  bouyer 
   3343  1.1.6.2  bouyer fsnan_exit:
   3344  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3345  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3346  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3347  1.1.6.2  bouyer 
   3348  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)
   3349  1.1.6.2  bouyer 
   3350  1.1.6.2  bouyer 	unlk		%a6
   3351  1.1.6.2  bouyer 	bra.l		_real_snan
   3352  1.1.6.2  bouyer 
   3353  1.1.6.2  bouyer ########################################################################
   3354  1.1.6.2  bouyer 
   3355  1.1.6.2  bouyer #
   3356  1.1.6.2  bouyer # the hardware does not save the default result to memory on enabled
   3357  1.1.6.2  bouyer # snan exceptions. we do this here before passing control to
   3358  1.1.6.2  bouyer # the user snan handler.
   3359  1.1.6.2  bouyer #
   3360  1.1.6.2  bouyer # byte, word, long, and packed destination format operations can pass
   3361  1.1.6.2  bouyer # through here. since packed format operations already were handled by
   3362  1.1.6.2  bouyer # fpsp_unsupp(), then we need to do nothing else for them here.
   3363  1.1.6.2  bouyer # for byte, word, and long, we simply need to test the sign of the src
   3364  1.1.6.2  bouyer # operand and save the appropriate minimum or maximum integer value
   3365  1.1.6.2  bouyer # to the effective address as pointed to by the stacked effective address.
   3366  1.1.6.2  bouyer #
   3367  1.1.6.2  bouyer fsnan_out:
   3368  1.1.6.2  bouyer 
   3369  1.1.6.2  bouyer 	bfextu		%d0{&19:&3},%d0		# extract dst format field
   3370  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract <ea> mode,reg
   3371  1.1.6.2  bouyer 	mov.w		(tbl_snan.b,%pc,%d0.w*2),%a0
   3372  1.1.6.2  bouyer 	jmp		(tbl_snan.b,%pc,%a0)
   3373  1.1.6.2  bouyer 
   3374  1.1.6.2  bouyer tbl_snan:
   3375  1.1.6.2  bouyer 	short		fsnan_out_l - tbl_snan # long word integer
   3376  1.1.6.2  bouyer 	short		fsnan_out_s - tbl_snan # sgl prec shouldn't happen
   3377  1.1.6.2  bouyer 	short		fsnan_out_x - tbl_snan # ext prec shouldn't happen
   3378  1.1.6.2  bouyer 	short		tbl_snan    - tbl_snan # packed needs no help
   3379  1.1.6.2  bouyer 	short		fsnan_out_w - tbl_snan # word integer
   3380  1.1.6.2  bouyer 	short		fsnan_out_d - tbl_snan # dbl prec shouldn't happen
   3381  1.1.6.2  bouyer 	short		fsnan_out_b - tbl_snan # byte integer
   3382  1.1.6.2  bouyer 	short		tbl_snan    - tbl_snan # packed needs no help
   3383  1.1.6.2  bouyer 
   3384  1.1.6.2  bouyer fsnan_out_b:
   3385  1.1.6.2  bouyer 	mov.b		FP_SRC_HI(%a6),%d0	# load upper byte of SNAN
   3386  1.1.6.2  bouyer 	bset		&6,%d0			# set SNAN bit
   3387  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3388  1.1.6.2  bouyer 	ble.b		fsnan_out_b_dn		# yes
   3389  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3390  1.1.6.2  bouyer 	bsr.l		_dmem_write_byte	# write the default result
   3391  1.1.6.2  bouyer 
   3392  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3393  1.1.6.2  bouyer 	bne.l		facc_out_b		# yes
   3394  1.1.6.2  bouyer 
   3395  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3396  1.1.6.2  bouyer fsnan_out_b_dn:
   3397  1.1.6.2  bouyer 	andi.w		&0x0007,%d1
   3398  1.1.6.2  bouyer 	bsr.l		store_dreg_b		# store result to regfile
   3399  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3400  1.1.6.2  bouyer 
   3401  1.1.6.2  bouyer fsnan_out_w:
   3402  1.1.6.2  bouyer 	mov.w		FP_SRC_HI(%a6),%d0	# load upper word of SNAN
   3403  1.1.6.2  bouyer 	bset		&14,%d0			# set SNAN bit
   3404  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3405  1.1.6.2  bouyer 	ble.b		fsnan_out_w_dn		# yes
   3406  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3407  1.1.6.2  bouyer 	bsr.l		_dmem_write_word	# write the default result
   3408  1.1.6.2  bouyer 
   3409  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3410  1.1.6.2  bouyer 	bne.l		facc_out_w		# yes
   3411  1.1.6.2  bouyer 
   3412  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3413  1.1.6.2  bouyer fsnan_out_w_dn:
   3414  1.1.6.2  bouyer 	andi.w		&0x0007,%d1
   3415  1.1.6.2  bouyer 	bsr.l		store_dreg_w		# store result to regfile
   3416  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3417  1.1.6.2  bouyer 
   3418  1.1.6.2  bouyer fsnan_out_l:
   3419  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d0	# load upper longword of SNAN
   3420  1.1.6.2  bouyer 	bset		&30,%d0			# set SNAN bit
   3421  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3422  1.1.6.2  bouyer 	ble.b		fsnan_out_l_dn		# yes
   3423  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3424  1.1.6.2  bouyer 	bsr.l		_dmem_write_long	# write the default result
   3425  1.1.6.2  bouyer 
   3426  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3427  1.1.6.2  bouyer 	bne.l		facc_out_l		# yes
   3428  1.1.6.2  bouyer 
   3429  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3430  1.1.6.2  bouyer fsnan_out_l_dn:
   3431  1.1.6.2  bouyer 	andi.w		&0x0007,%d1
   3432  1.1.6.2  bouyer 	bsr.l		store_dreg_l		# store result to regfile
   3433  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3434  1.1.6.2  bouyer 
   3435  1.1.6.2  bouyer fsnan_out_s:
   3436  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
   3437  1.1.6.2  bouyer 	ble.b		fsnan_out_d_dn		# yes
   3438  1.1.6.2  bouyer 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
   3439  1.1.6.2  bouyer 	andi.l		&0x80000000,%d0		# keep sign
   3440  1.1.6.2  bouyer 	ori.l		&0x7fc00000,%d0		# insert new exponent,SNAN bit
   3441  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d1	# load mantissa
   3442  1.1.6.2  bouyer 	lsr.l		&0x8,%d1		# shift mantissa for sgl
   3443  1.1.6.2  bouyer 	or.l		%d1,%d0			# create sgl SNAN
   3444  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
   3445  1.1.6.2  bouyer 	bsr.l		_dmem_write_long	# write the default result
   3446  1.1.6.2  bouyer 
   3447  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3448  1.1.6.2  bouyer 	bne.l		facc_out_l		# yes
   3449  1.1.6.2  bouyer 
   3450  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3451  1.1.6.2  bouyer fsnan_out_d_dn:
   3452  1.1.6.2  bouyer 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
   3453  1.1.6.2  bouyer 	andi.l		&0x80000000,%d0		# keep sign
   3454  1.1.6.2  bouyer 	ori.l		&0x7fc00000,%d0		# insert new exponent,SNAN bit
   3455  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)
   3456  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d1	# load mantissa
   3457  1.1.6.2  bouyer 	lsr.l		&0x8,%d1		# shift mantissa for sgl
   3458  1.1.6.2  bouyer 	or.l		%d1,%d0			# create sgl SNAN
   3459  1.1.6.2  bouyer 	mov.l		(%sp)+,%d1
   3460  1.1.6.2  bouyer 	andi.w		&0x0007,%d1
   3461  1.1.6.2  bouyer 	bsr.l		store_dreg_l		# store result to regfile
   3462  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3463  1.1.6.2  bouyer 
   3464  1.1.6.2  bouyer fsnan_out_d:
   3465  1.1.6.2  bouyer 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
   3466  1.1.6.2  bouyer 	andi.l		&0x80000000,%d0		# keep sign
   3467  1.1.6.2  bouyer 	ori.l		&0x7ff80000,%d0		# insert new exponent,SNAN bit
   3468  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d1	# load hi mantissa
   3469  1.1.6.2  bouyer 	mov.l		%d0,FP_SCR0_EX(%a6)	# store to temp space
   3470  1.1.6.2  bouyer 	mov.l		&11,%d0			# load shift amt
   3471  1.1.6.2  bouyer 	lsr.l		%d0,%d1
   3472  1.1.6.2  bouyer 	or.l		%d1,FP_SCR0_EX(%a6)	# create dbl hi
   3473  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d1	# load hi mantissa
   3474  1.1.6.2  bouyer 	andi.l		&0x000007ff,%d1
   3475  1.1.6.2  bouyer 	ror.l		%d0,%d1
   3476  1.1.6.2  bouyer 	mov.l		%d1,FP_SCR0_HI(%a6)	# store to temp space
   3477  1.1.6.2  bouyer 	mov.l		FP_SRC_LO(%a6),%d1	# load lo mantissa
   3478  1.1.6.2  bouyer 	lsr.l		%d0,%d1
   3479  1.1.6.2  bouyer 	or.l		%d1,FP_SCR0_HI(%a6)	# create dbl lo
   3480  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   3481  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   3482  1.1.6.2  bouyer 	movq.l		&0x8,%d0		# pass: size of 8 bytes
   3483  1.1.6.2  bouyer 	bsr.l		_dmem_write		# write the default result
   3484  1.1.6.2  bouyer 
   3485  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3486  1.1.6.2  bouyer 	bne.l		facc_out_d		# yes
   3487  1.1.6.2  bouyer 
   3488  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3489  1.1.6.2  bouyer 
   3490  1.1.6.2  bouyer # for extended precision, if the addressing mode is pre-decrement or
   3491  1.1.6.2  bouyer # post-increment, then the address register did not get updated.
   3492  1.1.6.2  bouyer # in addition, for pre-decrement, the stacked <ea> is incorrect.
   3493  1.1.6.2  bouyer fsnan_out_x:
   3494  1.1.6.2  bouyer 	clr.b		SPCOND_FLG(%a6)		# clear special case flag
   3495  1.1.6.2  bouyer 
   3496  1.1.6.2  bouyer 	mov.w		FP_SRC_EX(%a6),FP_SCR0_EX(%a6)
   3497  1.1.6.2  bouyer 	clr.w		2+FP_SCR0(%a6)
   3498  1.1.6.2  bouyer 	mov.l		FP_SRC_HI(%a6),%d0
   3499  1.1.6.2  bouyer 	bset		&30,%d0
   3500  1.1.6.2  bouyer 	mov.l		%d0,FP_SCR0_HI(%a6)
   3501  1.1.6.2  bouyer 	mov.l		FP_SRC_LO(%a6),FP_SCR0_LO(%a6)
   3502  1.1.6.2  bouyer 
   3503  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# supervisor mode exception?
   3504  1.1.6.2  bouyer 	bne.b		fsnan_out_x_s		# yes
   3505  1.1.6.2  bouyer 
   3506  1.1.6.2  bouyer 	mov.l		%usp,%a0		# fetch user stack pointer
   3507  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)		# save on stack for calc_ea()
   3508  1.1.6.2  bouyer 	mov.l		(%a6),EXC_A6(%a6)
   3509  1.1.6.2  bouyer 
   3510  1.1.6.2  bouyer 	bsr.l		_calc_ea_fout		# find the correct ea,update An
   3511  1.1.6.2  bouyer 	mov.l		%a0,%a1
   3512  1.1.6.2  bouyer 	mov.l		%a0,EXC_EA(%a6)		# stack correct <ea>
   3513  1.1.6.2  bouyer 
   3514  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0
   3515  1.1.6.2  bouyer 	mov.l		%a0,%usp		# restore user stack pointer
   3516  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),(%a6)
   3517  1.1.6.2  bouyer 
   3518  1.1.6.2  bouyer fsnan_out_x_save:
   3519  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   3520  1.1.6.2  bouyer 	movq.l		&0xc,%d0		# pass: size of extended
   3521  1.1.6.2  bouyer 	bsr.l		_dmem_write		# write the default result
   3522  1.1.6.2  bouyer 
   3523  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   3524  1.1.6.2  bouyer 	bne.l		facc_out_x		# yes
   3525  1.1.6.2  bouyer 
   3526  1.1.6.2  bouyer 	bra.w		fsnan_exit
   3527  1.1.6.2  bouyer 
   3528  1.1.6.2  bouyer fsnan_out_x_s:
   3529  1.1.6.2  bouyer 	mov.l		(%a6),EXC_A6(%a6)
   3530  1.1.6.2  bouyer 
   3531  1.1.6.2  bouyer 	bsr.l		_calc_ea_fout		# find the correct ea,update An
   3532  1.1.6.2  bouyer 	mov.l		%a0,%a1
   3533  1.1.6.2  bouyer 	mov.l		%a0,EXC_EA(%a6)		# stack correct <ea>
   3534  1.1.6.2  bouyer 
   3535  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),(%a6)
   3536  1.1.6.2  bouyer 
   3537  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
   3538  1.1.6.2  bouyer 	bne.b		fsnan_out_x_save	# no
   3539  1.1.6.2  bouyer 
   3540  1.1.6.2  bouyer # the operation was "fmove.x SNAN,-(a7)" from supervisor mode.
   3541  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3542  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3543  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3544  1.1.6.2  bouyer 
   3545  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)
   3546  1.1.6.2  bouyer 
   3547  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),%a6		# restore frame pointer
   3548  1.1.6.2  bouyer 
   3549  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
   3550  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_PC+0x2(%sp),LOCAL_SIZE+EXC_PC+0x2-0xc(%sp)
   3551  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
   3552  1.1.6.2  bouyer 
   3553  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SCR0_EX(%sp),LOCAL_SIZE+EXC_SR(%sp)
   3554  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SCR0_HI(%sp),LOCAL_SIZE+EXC_PC+0x2(%sp)
   3555  1.1.6.2  bouyer 	mov.l		LOCAL_SIZE+FP_SCR0_LO(%sp),LOCAL_SIZE+EXC_EA(%sp)
   3556  1.1.6.2  bouyer 
   3557  1.1.6.2  bouyer 	add.l		&LOCAL_SIZE-0x8,%sp
   3558  1.1.6.2  bouyer 
   3559  1.1.6.2  bouyer 	bra.l		_real_snan
   3560  1.1.6.2  bouyer 
   3561  1.1.6.2  bouyer #########################################################################
   3562  1.1.6.2  bouyer # XDEF ****************************************************************	#
   3563  1.1.6.2  bouyer #	_fpsp_inex(): 060FPSP entry point for FP Inexact exception.	#
   3564  1.1.6.2  bouyer #									#
   3565  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
   3566  1.1.6.2  bouyer # 	FP Inexact exception in an operating system.			#
   3567  1.1.6.2  bouyer #									#
   3568  1.1.6.2  bouyer # XREF ****************************************************************	#
   3569  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword			#
   3570  1.1.6.2  bouyer #	fix_skewed_ops() - adjust src operand in fsave frame		#
   3571  1.1.6.2  bouyer #	set_tag_x() - determine optype of src/dst operands		#
   3572  1.1.6.2  bouyer #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   3573  1.1.6.2  bouyer #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
   3574  1.1.6.2  bouyer #	load_fpn2() - load dst operand from FP regfile			#
   3575  1.1.6.2  bouyer #	smovcr() - emulate an "fmovcr" instruction			#
   3576  1.1.6.2  bouyer #	fout() - emulate an opclass 3 instruction			#
   3577  1.1.6.2  bouyer #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
   3578  1.1.6.2  bouyer #	_real_inex() - "callout" to operating system inexact handler	#
   3579  1.1.6.2  bouyer #									#
   3580  1.1.6.2  bouyer # INPUT ***************************************************************	#
   3581  1.1.6.2  bouyer #	- The system stack contains the FP Inexact exception frame	#
   3582  1.1.6.2  bouyer #	- The fsave frame contains the source operand			#
   3583  1.1.6.2  bouyer # 									#
   3584  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   3585  1.1.6.2  bouyer #	- The system stack is unchanged					#
   3586  1.1.6.2  bouyer #	- The fsave frame contains the adjusted src op for opclass 0,2	#
   3587  1.1.6.2  bouyer #									#
   3588  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   3589  1.1.6.2  bouyer #	In a system where the FP Inexact exception is enabled, the goal	#
   3590  1.1.6.2  bouyer # is to get to the handler specified at _real_inex(). But, on the 060,	#
   3591  1.1.6.2  bouyer # for opclass zero and two instruction taking this exception, the 	#
   3592  1.1.6.2  bouyer # hardware doesn't store the correct result to the destination FP	#
   3593  1.1.6.2  bouyer # register as did the '040 and '881/2. This handler must emulate the 	#
   3594  1.1.6.2  bouyer # instruction in order to get this value and then store it to the 	#
   3595  1.1.6.2  bouyer # correct register before calling _real_inex().				#
   3596  1.1.6.2  bouyer #	For opclass 3 instructions, the 060 doesn't store the default	#
   3597  1.1.6.2  bouyer # inexact result out to memory or data register file as it should.	#
   3598  1.1.6.2  bouyer # This code must emulate the move out by calling fout() before finally	#
   3599  1.1.6.2  bouyer # exiting through _real_inex().						#
   3600  1.1.6.2  bouyer #									#
   3601  1.1.6.2  bouyer #########################################################################
   3602  1.1.6.2  bouyer 
   3603  1.1.6.2  bouyer 	global		_fpsp_inex
   3604  1.1.6.2  bouyer _fpsp_inex:
   3605  1.1.6.2  bouyer 
   3606  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3607  1.1.6.2  bouyer 
   3608  1.1.6.2  bouyer 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3609  1.1.6.2  bouyer 
   3610  1.1.6.2  bouyer  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3611  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3612  1.1.6.2  bouyer  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3613  1.1.6.2  bouyer 
   3614  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction
   3615  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3616  1.1.6.2  bouyer 
   3617  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3618  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3619  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   3620  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)
   3621  1.1.6.2  bouyer 
   3622  1.1.6.2  bouyer ##############################################################################
   3623  1.1.6.2  bouyer 
   3624  1.1.6.2  bouyer 	btst		&13,%d0			# is instr an fmove out?
   3625  1.1.6.2  bouyer 	bne.w		finex_out		# fmove out
   3626  1.1.6.2  bouyer 
   3627  1.1.6.2  bouyer 
   3628  1.1.6.2  bouyer # the hardware, for "fabs" and "fneg" w/ a long source format, puts the
   3629  1.1.6.2  bouyer # longword integer directly into the upper longword of the mantissa along
   3630  1.1.6.2  bouyer # w/ an exponent value of 0x401e. we convert this to extended precision here.
   3631  1.1.6.2  bouyer 	bfextu		%d0{&19:&3},%d0		# fetch instr size
   3632  1.1.6.2  bouyer 	bne.b		finex_cont		# instr size is not long
   3633  1.1.6.2  bouyer 	cmpi.w		FP_SRC_EX(%a6),&0x401e	# is exponent 0x401e?
   3634  1.1.6.2  bouyer 	bne.b		finex_cont		# no
   3635  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr
   3636  1.1.6.2  bouyer 	fmov.l		FP_SRC_HI(%a6),%fp0	# load integer src
   3637  1.1.6.2  bouyer 	fmov.x		%fp0,FP_SRC(%a6)	# store integer as extended precision
   3638  1.1.6.2  bouyer 	mov.w		&0xe001,0x2+FP_SRC(%a6)
   3639  1.1.6.2  bouyer 
   3640  1.1.6.2  bouyer finex_cont:
   3641  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3642  1.1.6.2  bouyer 	bsr.l		fix_skewed_ops		# fix src op
   3643  1.1.6.2  bouyer 
   3644  1.1.6.2  bouyer # Here, we zero the ccode and exception byte field since we're going to
   3645  1.1.6.2  bouyer # emulate the whole instruction. Notice, though, that we don't kill the
   3646  1.1.6.2  bouyer # INEX1 bit. This is because a packed op has long since been converted
   3647  1.1.6.2  bouyer # to extended before arriving here. Therefore, we need to retain the
   3648  1.1.6.2  bouyer # INEX1 bit from when the operand was first converted.
   3649  1.1.6.2  bouyer 	andi.l		&0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
   3650  1.1.6.2  bouyer 
   3651  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# zero current control regs
   3652  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   3653  1.1.6.2  bouyer 
   3654  1.1.6.2  bouyer 	bfextu		EXC_EXTWORD(%a6){&0:&6},%d1 # extract upper 6 of cmdreg
   3655  1.1.6.2  bouyer 	cmpi.b		%d1,&0x17		# is op an fmovecr?
   3656  1.1.6.2  bouyer 	beq.w		finex_fmovcr		# yes
   3657  1.1.6.2  bouyer 
   3658  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3659  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   3660  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
   3661  1.1.6.2  bouyer 
   3662  1.1.6.2  bouyer # bits four and five of the fp extension word separate the monadic and dyadic
   3663  1.1.6.2  bouyer # operations that can pass through fpsp_inex(). remember that fcmp and ftst
   3664  1.1.6.2  bouyer # will never take this exception, but fsincos will.
   3665  1.1.6.2  bouyer 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
   3666  1.1.6.2  bouyer 	beq.b		finex_extract		# monadic
   3667  1.1.6.2  bouyer 
   3668  1.1.6.2  bouyer 	btst		&0x4,1+EXC_CMDREG(%a6)	# is operation an fsincos?
   3669  1.1.6.2  bouyer 	bne.b		finex_extract		# yes
   3670  1.1.6.2  bouyer 
   3671  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
   3672  1.1.6.2  bouyer 	bsr.l		load_fpn2		# load dst into FP_DST
   3673  1.1.6.2  bouyer 
   3674  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
   3675  1.1.6.2  bouyer 	bsr.l		set_tag_x		# tag the operand type
   3676  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
   3677  1.1.6.2  bouyer 	bne.b		finex_op2_done		# no
   3678  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
   3679  1.1.6.2  bouyer finex_op2_done:
   3680  1.1.6.2  bouyer 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
   3681  1.1.6.2  bouyer 
   3682  1.1.6.2  bouyer finex_extract:
   3683  1.1.6.2  bouyer 	clr.l		%d0
   3684  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
   3685  1.1.6.2  bouyer 
   3686  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1
   3687  1.1.6.2  bouyer 	andi.w		&0x007f,%d1		# extract extension
   3688  1.1.6.2  bouyer 
   3689  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
   3690  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1
   3691  1.1.6.2  bouyer 
   3692  1.1.6.2  bouyer 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
   3693  1.1.6.2  bouyer 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
   3694  1.1.6.2  bouyer 
   3695  1.1.6.2  bouyer # the operation has been emulated. the result is in fp0.
   3696  1.1.6.2  bouyer finex_save:
   3697  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
   3698  1.1.6.2  bouyer 	bsr.l		store_fpreg
   3699  1.1.6.2  bouyer 
   3700  1.1.6.2  bouyer finex_exit:
   3701  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3702  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3703  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3704  1.1.6.2  bouyer 
   3705  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)
   3706  1.1.6.2  bouyer 
   3707  1.1.6.2  bouyer 	unlk		%a6
   3708  1.1.6.2  bouyer 	bra.l		_real_inex
   3709  1.1.6.2  bouyer 
   3710  1.1.6.2  bouyer finex_fmovcr:
   3711  1.1.6.2  bouyer 	clr.l		%d0
   3712  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec,mode
   3713  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1
   3714  1.1.6.2  bouyer 	andi.l		&0x0000007f,%d1		# pass rom offset
   3715  1.1.6.2  bouyer 	bsr.l		smovcr
   3716  1.1.6.2  bouyer 	bra.b		finex_save
   3717  1.1.6.2  bouyer 
   3718  1.1.6.2  bouyer ########################################################################
   3719  1.1.6.2  bouyer 
   3720  1.1.6.2  bouyer #
   3721  1.1.6.2  bouyer # the hardware does not save the default result to memory on enabled
   3722  1.1.6.2  bouyer # inexact exceptions. we do this here before passing control to
   3723  1.1.6.2  bouyer # the user inexact handler.
   3724  1.1.6.2  bouyer #
   3725  1.1.6.2  bouyer # byte, word, and long destination format operations can pass
   3726  1.1.6.2  bouyer # through here. so can double and single precision.
   3727  1.1.6.2  bouyer # although packed opclass three operations can take inexact
   3728  1.1.6.2  bouyer # exceptions, they won't pass through here since they are caught
   3729  1.1.6.2  bouyer # first by the unsupported data format exception handler. that handler
   3730  1.1.6.2  bouyer # sends them directly to _real_inex() if necessary.
   3731  1.1.6.2  bouyer #
   3732  1.1.6.2  bouyer finex_out:
   3733  1.1.6.2  bouyer 
   3734  1.1.6.2  bouyer 	mov.b		&NORM,STAG(%a6)		# src is a NORM
   3735  1.1.6.2  bouyer 
   3736  1.1.6.2  bouyer 	clr.l		%d0
   3737  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec,mode
   3738  1.1.6.2  bouyer 
   3739  1.1.6.2  bouyer 	andi.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
   3740  1.1.6.2  bouyer 
   3741  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
   3742  1.1.6.2  bouyer 
   3743  1.1.6.2  bouyer 	bsr.l		fout			# store the default result
   3744  1.1.6.2  bouyer 
   3745  1.1.6.2  bouyer 	bra.b		finex_exit
   3746  1.1.6.2  bouyer 
   3747  1.1.6.2  bouyer #########################################################################
   3748  1.1.6.2  bouyer # XDEF ****************************************************************	#
   3749  1.1.6.2  bouyer #	_fpsp_dz(): 060FPSP entry point for FP DZ exception.		#
   3750  1.1.6.2  bouyer #									#
   3751  1.1.6.2  bouyer #	This handler should be the first code executed upon taking	#
   3752  1.1.6.2  bouyer #	the FP DZ exception in an operating system.			#
   3753  1.1.6.2  bouyer #									#
   3754  1.1.6.2  bouyer # XREF ****************************************************************	#
   3755  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword from memory	#
   3756  1.1.6.2  bouyer #	fix_skewed_ops() - adjust fsave operand				#
   3757  1.1.6.2  bouyer #	_real_dz() - "callout" exit point from FP DZ handler		#
   3758  1.1.6.2  bouyer #									#
   3759  1.1.6.2  bouyer # INPUT ***************************************************************	#
   3760  1.1.6.2  bouyer #	- The system stack contains the FP DZ exception stack.		#
   3761  1.1.6.2  bouyer #	- The fsave frame contains the source operand.			#
   3762  1.1.6.2  bouyer # 									#
   3763  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   3764  1.1.6.2  bouyer #	- The system stack contains the FP DZ exception stack.		#
   3765  1.1.6.2  bouyer #	- The fsave frame contains the adjusted source operand.		#
   3766  1.1.6.2  bouyer #									#
   3767  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   3768  1.1.6.2  bouyer #	In a system where the DZ exception is enabled, the goal is to	#
   3769  1.1.6.2  bouyer # get to the handler specified at _real_dz(). But, on the 060, when the	#
   3770  1.1.6.2  bouyer # exception is taken, the input operand in the fsave state frame may	#
   3771  1.1.6.2  bouyer # be incorrect for some cases and need to be adjusted. So, this package	#
   3772  1.1.6.2  bouyer # adjusts the operand using fix_skewed_ops() and then branches to	#
   3773  1.1.6.2  bouyer # _real_dz(). 								#
   3774  1.1.6.2  bouyer #									#
   3775  1.1.6.2  bouyer #########################################################################
   3776  1.1.6.2  bouyer 
   3777  1.1.6.2  bouyer 	global		_fpsp_dz
   3778  1.1.6.2  bouyer _fpsp_dz:
   3779  1.1.6.2  bouyer 
   3780  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3781  1.1.6.2  bouyer 
   3782  1.1.6.2  bouyer 	fsave		FP_SRC(%a6)		# grab the "busy" frame
   3783  1.1.6.2  bouyer 
   3784  1.1.6.2  bouyer  	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3785  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   3786  1.1.6.2  bouyer  	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
   3787  1.1.6.2  bouyer 
   3788  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction
   3789  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   3790  1.1.6.2  bouyer 
   3791  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3792  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3793  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   3794  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)
   3795  1.1.6.2  bouyer 
   3796  1.1.6.2  bouyer ##############################################################################
   3797  1.1.6.2  bouyer 
   3798  1.1.6.2  bouyer 
   3799  1.1.6.2  bouyer # here, we simply see if the operand in the fsave frame needs to be "unskewed".
   3800  1.1.6.2  bouyer # this would be the case for opclass two operations with a source zero
   3801  1.1.6.2  bouyer # in the sgl or dbl format.
   3802  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
   3803  1.1.6.2  bouyer 	bsr.l		fix_skewed_ops		# fix src op
   3804  1.1.6.2  bouyer 
   3805  1.1.6.2  bouyer fdz_exit:
   3806  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   3807  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   3808  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3809  1.1.6.2  bouyer 
   3810  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)
   3811  1.1.6.2  bouyer 
   3812  1.1.6.2  bouyer 	unlk		%a6
   3813  1.1.6.2  bouyer 	bra.l		_real_dz
   3814  1.1.6.2  bouyer 
   3815  1.1.6.2  bouyer #########################################################################
   3816  1.1.6.2  bouyer # XDEF ****************************************************************	#
   3817  1.1.6.2  bouyer #	_fpsp_fline(): 060FPSP entry point for "Line F emulator" exc.	#
   3818  1.1.6.2  bouyer #									#
   3819  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
   3820  1.1.6.2  bouyer #	"Line F Emulator" exception in an operating system.		#
   3821  1.1.6.2  bouyer #									#
   3822  1.1.6.2  bouyer # XREF ****************************************************************	#
   3823  1.1.6.2  bouyer #	_fpsp_unimp() - handle "FP Unimplemented" exceptions		#
   3824  1.1.6.2  bouyer #	_real_fpu_disabled() - handle "FPU disabled" exceptions		#
   3825  1.1.6.2  bouyer #	_real_fline() - handle "FLINE" exceptions			#
   3826  1.1.6.2  bouyer #	_imem_read_long() - read instruction longword			#
   3827  1.1.6.2  bouyer #									#
   3828  1.1.6.2  bouyer # INPUT ***************************************************************	#
   3829  1.1.6.2  bouyer #	- The system stack contains a "Line F Emulator" exception	#
   3830  1.1.6.2  bouyer #	  stack frame.							#
   3831  1.1.6.2  bouyer # 									#
   3832  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   3833  1.1.6.2  bouyer #	- The system stack is unchanged					#
   3834  1.1.6.2  bouyer #									#
   3835  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   3836  1.1.6.2  bouyer #	When a "Line F Emulator" exception occurs, there are 3 possible	#
   3837  1.1.6.2  bouyer # exception types, denoted by the exception stack frame format number:	#
   3838  1.1.6.2  bouyer #	(1) FPU unimplemented instruction (6 word stack frame)		#
   3839  1.1.6.2  bouyer #	(2) FPU disabled (8 word stack frame)				#
   3840  1.1.6.2  bouyer #	(3) Line F (4 word stack frame)					#
   3841  1.1.6.2  bouyer #									#
   3842  1.1.6.2  bouyer #	This module determines which and forks the flow off to the 	#
   3843  1.1.6.2  bouyer # appropriate "callout" (for "disabled" and "Line F") or to the		#
   3844  1.1.6.2  bouyer # correct emulation code (for "FPU unimplemented").			#
   3845  1.1.6.2  bouyer #	This code also must check for "fmovecr" instructions w/ a	#
   3846  1.1.6.2  bouyer # non-zero <ea> field. These may get flagged as "Line F" but should	#
   3847  1.1.6.2  bouyer # really be flagged as "FPU Unimplemented". (This is a "feature" on	#
   3848  1.1.6.2  bouyer # the '060.								#
   3849  1.1.6.2  bouyer #									#
   3850  1.1.6.2  bouyer #########################################################################
   3851  1.1.6.2  bouyer 
   3852  1.1.6.2  bouyer 	global		_fpsp_fline
   3853  1.1.6.2  bouyer _fpsp_fline:
   3854  1.1.6.2  bouyer 
   3855  1.1.6.2  bouyer # check to see if this exception is a "FP Unimplemented Instruction"
   3856  1.1.6.2  bouyer # exception. if so, branch directly to that handler's entry point.
   3857  1.1.6.2  bouyer 	cmpi.w		0x6(%sp),&0x202c
   3858  1.1.6.2  bouyer 	beq.l		_fpsp_unimp
   3859  1.1.6.2  bouyer 
   3860  1.1.6.2  bouyer # check to see if the FPU is disabled. if so, jump to the OS entry
   3861  1.1.6.2  bouyer # point for that condition.
   3862  1.1.6.2  bouyer 	cmpi.w		0x6(%sp),&0x402c
   3863  1.1.6.2  bouyer 	beq.l		_real_fpu_disabled
   3864  1.1.6.2  bouyer 
   3865  1.1.6.2  bouyer # the exception was an "F-Line Illegal" exception. we check to see
   3866  1.1.6.2  bouyer # if the F-Line instruction is an "fmovecr" w/ a non-zero <ea>. if
   3867  1.1.6.2  bouyer # so, convert the F-Line exception stack frame to an FP Unimplemented
   3868  1.1.6.2  bouyer # Instruction exception stack frame else branch to the OS entry
   3869  1.1.6.2  bouyer # point for the F-Line exception handler.
   3870  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   3871  1.1.6.2  bouyer 
   3872  1.1.6.2  bouyer 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   3873  1.1.6.2  bouyer 
   3874  1.1.6.2  bouyer 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
   3875  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   3876  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   3877  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch instruction words
   3878  1.1.6.2  bouyer 
   3879  1.1.6.2  bouyer 	bfextu		%d0{&0:&10},%d1		# is it an fmovecr?
   3880  1.1.6.2  bouyer 	cmpi.w		%d1,&0x03c8
   3881  1.1.6.2  bouyer 	bne.b		fline_fline		# no
   3882  1.1.6.2  bouyer 
   3883  1.1.6.2  bouyer 	bfextu		%d0{&16:&6},%d1		# is it an fmovecr?
   3884  1.1.6.2  bouyer 	cmpi.b		%d1,&0x17
   3885  1.1.6.2  bouyer 	bne.b		fline_fline		# no
   3886  1.1.6.2  bouyer 
   3887  1.1.6.2  bouyer # it's an fmovecr w/ a non-zero <ea> that has entered through
   3888  1.1.6.2  bouyer # the F-Line Illegal exception.
   3889  1.1.6.2  bouyer # so, we need to convert the F-Line exception stack frame into an
   3890  1.1.6.2  bouyer # FP Unimplemented Instruction stack frame and jump to that entry
   3891  1.1.6.2  bouyer # point.
   3892  1.1.6.2  bouyer #
   3893  1.1.6.2  bouyer # but, if the FPU is disabled, then we need to jump to the FPU diabled
   3894  1.1.6.2  bouyer # entry point.
   3895  1.1.6.2  bouyer 	movc		%pcr,%d0
   3896  1.1.6.2  bouyer 	btst		&0x1,%d0
   3897  1.1.6.2  bouyer 	beq.b		fline_fmovcr
   3898  1.1.6.2  bouyer 
   3899  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3900  1.1.6.2  bouyer 
   3901  1.1.6.2  bouyer 	unlk		%a6
   3902  1.1.6.2  bouyer 
   3903  1.1.6.2  bouyer 	sub.l		&0x8,%sp		# make room for "Next PC", <ea>
   3904  1.1.6.2  bouyer 	mov.w		0x8(%sp),(%sp)
   3905  1.1.6.2  bouyer 	mov.l		0xa(%sp),0x2(%sp)	# move "Current PC"
   3906  1.1.6.2  bouyer 	mov.w		&0x402c,0x6(%sp)
   3907  1.1.6.2  bouyer 	mov.l		0x2(%sp),0xc(%sp)
   3908  1.1.6.2  bouyer 	addq.l		&0x4,0x2(%sp)		# set "Next PC"
   3909  1.1.6.2  bouyer 
   3910  1.1.6.2  bouyer 	bra.l		_real_fpu_disabled
   3911  1.1.6.2  bouyer 
   3912  1.1.6.2  bouyer fline_fmovcr:
   3913  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3914  1.1.6.2  bouyer 
   3915  1.1.6.2  bouyer 	unlk		%a6
   3916  1.1.6.2  bouyer 
   3917  1.1.6.2  bouyer 	fmov.l		0x2(%sp),%fpiar		# set current PC
   3918  1.1.6.2  bouyer 	addq.l		&0x4,0x2(%sp)		# set Next PC
   3919  1.1.6.2  bouyer 
   3920  1.1.6.2  bouyer 	mov.l		(%sp),-(%sp)
   3921  1.1.6.2  bouyer 	mov.l		0x8(%sp),0x4(%sp)
   3922  1.1.6.2  bouyer 	mov.b		&0x20,0x6(%sp)
   3923  1.1.6.2  bouyer 
   3924  1.1.6.2  bouyer 	bra.l		_fpsp_unimp
   3925  1.1.6.2  bouyer 
   3926  1.1.6.2  bouyer fline_fline:
   3927  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   3928  1.1.6.2  bouyer 
   3929  1.1.6.2  bouyer 	unlk		%a6
   3930  1.1.6.2  bouyer 
   3931  1.1.6.2  bouyer 	bra.l		_real_fline
   3932  1.1.6.2  bouyer 
   3933  1.1.6.2  bouyer #########################################################################
   3934  1.1.6.2  bouyer # XDEF ****************************************************************	#
   3935  1.1.6.2  bouyer #	_fpsp_unimp(): 060FPSP entry point for FP "Unimplemented	#
   3936  1.1.6.2  bouyer #		       Instruction" exception.				#
   3937  1.1.6.2  bouyer #									#
   3938  1.1.6.2  bouyer #	This handler should be the first code executed upon taking the	#
   3939  1.1.6.2  bouyer #	FP Unimplemented Instruction exception in an operating system.	#
   3940  1.1.6.2  bouyer #									#
   3941  1.1.6.2  bouyer # XREF ****************************************************************	#
   3942  1.1.6.2  bouyer #	_imem_read_{word,long}() - read instruction word/longword	#
   3943  1.1.6.2  bouyer #	load_fop() - load src/dst ops from memory and/or FP regfile	#
   3944  1.1.6.2  bouyer #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
   3945  1.1.6.2  bouyer #	tbl_trans - addr of table of emulation routines for trnscndls	#
   3946  1.1.6.2  bouyer #	_real_access() - "callout" for access error exception		#
   3947  1.1.6.2  bouyer #	_fpsp_done() - "callout" for exit; work all done		#
   3948  1.1.6.2  bouyer #	_real_trace() - "callout" for Trace enabled exception		#
   3949  1.1.6.2  bouyer #	smovcr() - emulate "fmovecr" instruction			#
   3950  1.1.6.2  bouyer #	funimp_skew() - adjust fsave src ops to "incorrect" value	#
   3951  1.1.6.2  bouyer #	_ftrapcc() - emulate an "ftrapcc" instruction			#
   3952  1.1.6.2  bouyer #	_fdbcc() - emulate an "fdbcc" instruction			#
   3953  1.1.6.2  bouyer #	_fscc() - emulate an "fscc" instruction				#
   3954  1.1.6.2  bouyer #	_real_trap() - "callout" for Trap exception			#
   3955  1.1.6.2  bouyer # 	_real_bsun() - "callout" for enabled Bsun exception		#
   3956  1.1.6.2  bouyer #									#
   3957  1.1.6.2  bouyer # INPUT ***************************************************************	#
   3958  1.1.6.2  bouyer #	- The system stack contains the "Unimplemented Instr" stk frame	#
   3959  1.1.6.2  bouyer # 									#
   3960  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   3961  1.1.6.2  bouyer #	If access error:						#
   3962  1.1.6.2  bouyer #	- The system stack is changed to an access error stack frame	#
   3963  1.1.6.2  bouyer #	If Trace exception enabled:					#
   3964  1.1.6.2  bouyer #	- The system stack is changed to a Trace exception stack frame	#
   3965  1.1.6.2  bouyer #	Else: (normal case)						#
   3966  1.1.6.2  bouyer #	- Correct result has been stored as appropriate			#
   3967  1.1.6.2  bouyer #									#
   3968  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   3969  1.1.6.2  bouyer #	There are two main cases of instructions that may enter here to	#
   3970  1.1.6.2  bouyer # be emulated: (1) the FPgen instructions, most of which were also	#
   3971  1.1.6.2  bouyer # unimplemented on the 040, and (2) "ftrapcc", "fscc", and "fdbcc".	#
   3972  1.1.6.2  bouyer #	For the first set, this handler calls the routine load_fop()	#
   3973  1.1.6.2  bouyer # to load the source and destination (for dyadic) operands to be used	#
   3974  1.1.6.2  bouyer # for instruction emulation. The correct emulation routine is then 	#
   3975  1.1.6.2  bouyer # chosen by decoding the instruction type and indexing into an 		#
   3976  1.1.6.2  bouyer # emulation subroutine index table. After emulation returns, this 	#
   3977  1.1.6.2  bouyer # handler checks to see if an exception should occur as a result of the #
   3978  1.1.6.2  bouyer # FP instruction emulation. If so, then an FP exception of the correct	#
   3979  1.1.6.2  bouyer # type is inserted into the FPU state frame using the "frestore"	#
   3980  1.1.6.2  bouyer # instruction before exiting through _fpsp_done(). In either the 	#
   3981  1.1.6.2  bouyer # exceptional or non-exceptional cases, we must check to see if the	#
   3982  1.1.6.2  bouyer # Trace exception is enabled. If so, then we must create a Trace	#
   3983  1.1.6.2  bouyer # exception frame from the current exception frame and exit through	#
   3984  1.1.6.2  bouyer # _real_trace().							#
   3985  1.1.6.2  bouyer # 	For "fdbcc", "ftrapcc", and "fscc", the emulation subroutines	#
   3986  1.1.6.2  bouyer # _fdbcc(), _ftrapcc(), and _fscc() respectively are used. All three	#
   3987  1.1.6.2  bouyer # may flag that a BSUN exception should be taken. If so, then the 	#
   3988  1.1.6.2  bouyer # current exception stack frame is converted into a BSUN exception 	#
   3989  1.1.6.2  bouyer # stack frame and an exit is made through _real_bsun(). If the		#
   3990  1.1.6.2  bouyer # instruction was "ftrapcc" and a Trap exception should result, a Trap	#
   3991  1.1.6.2  bouyer # exception stack frame is created from the current frame and an exit	#
   3992  1.1.6.2  bouyer # is made through _real_trap(). If a Trace exception is pending, then	#
   3993  1.1.6.2  bouyer # a Trace exception frame is created from the current frame and a jump	#
   3994  1.1.6.2  bouyer # is made to _real_trace(). Finally, if none of these conditions exist,	#
   3995  1.1.6.2  bouyer # then the handler exits though the callout _fpsp_done().		#
   3996  1.1.6.2  bouyer #									#
   3997  1.1.6.2  bouyer # 	In any of the above scenarios, if a _mem_read() or _mem_write()	#
   3998  1.1.6.2  bouyer # "callout" returns a failing value, then an access error stack frame	#
   3999  1.1.6.2  bouyer # is created from the current stack frame and an exit is made through	#
   4000  1.1.6.2  bouyer # _real_access().							#
   4001  1.1.6.2  bouyer #									#
   4002  1.1.6.2  bouyer #########################################################################
   4003  1.1.6.2  bouyer 
   4004  1.1.6.2  bouyer #
   4005  1.1.6.2  bouyer # FP UNIMPLEMENTED INSTRUCTION STACK FRAME:
   4006  1.1.6.2  bouyer #
   4007  1.1.6.2  bouyer #	*****************
   4008  1.1.6.2  bouyer #	*		* => <ea> of fp unimp instr.
   4009  1.1.6.2  bouyer #	-      EA	-
   4010  1.1.6.2  bouyer #	*		*
   4011  1.1.6.2  bouyer #	*****************
   4012  1.1.6.2  bouyer #	* 0x2 *  0x02c	* => frame format and vector offset(vector #11)
   4013  1.1.6.2  bouyer #	*****************
   4014  1.1.6.2  bouyer #	*		*
   4015  1.1.6.2  bouyer #	-    Next PC	- => PC of instr to execute after exc handling
   4016  1.1.6.2  bouyer #	*		*
   4017  1.1.6.2  bouyer #	*****************
   4018  1.1.6.2  bouyer #	*      SR	* => SR at the time the exception was taken
   4019  1.1.6.2  bouyer #	*****************
   4020  1.1.6.2  bouyer #
   4021  1.1.6.2  bouyer # Note: the !NULL bit does not get set in the fsave frame when the
   4022  1.1.6.2  bouyer # machine encounters an fp unimp exception. Therefore, it must be set
   4023  1.1.6.2  bouyer # before leaving this handler.
   4024  1.1.6.2  bouyer #
   4025  1.1.6.2  bouyer 	global		_fpsp_unimp
   4026  1.1.6.2  bouyer _fpsp_unimp:
   4027  1.1.6.2  bouyer 
   4028  1.1.6.2  bouyer 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
   4029  1.1.6.2  bouyer 
   4030  1.1.6.2  bouyer 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
   4031  1.1.6.2  bouyer 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
   4032  1.1.6.2  bouyer 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1
   4033  1.1.6.2  bouyer 
   4034  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user mode exception?
   4035  1.1.6.2  bouyer 	bne.b		funimp_s		# no; supervisor mode
   4036  1.1.6.2  bouyer 
   4037  1.1.6.2  bouyer # save the value of the user stack pointer onto the stack frame
   4038  1.1.6.2  bouyer funimp_u:
   4039  1.1.6.2  bouyer 	mov.l		%usp,%a0		# fetch user stack pointer
   4040  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)		# store in stack frame
   4041  1.1.6.2  bouyer 	bra.b		funimp_cont
   4042  1.1.6.2  bouyer 
   4043  1.1.6.2  bouyer # store the value of the supervisor stack pointer BEFORE the exc occurred.
   4044  1.1.6.2  bouyer # old_sp is address just above stacked effective address.
   4045  1.1.6.2  bouyer funimp_s:
   4046  1.1.6.2  bouyer 	lea		4+EXC_EA(%a6),%a0	# load old a7'
   4047  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)		# store a7'
   4048  1.1.6.2  bouyer 	mov.l		%a0,OLD_A7(%a6)		# make a copy
   4049  1.1.6.2  bouyer 
   4050  1.1.6.2  bouyer funimp_cont:
   4051  1.1.6.2  bouyer 
   4052  1.1.6.2  bouyer # the FPIAR holds the "current PC" of the faulting instruction.
   4053  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
   4054  1.1.6.2  bouyer 
   4055  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   4056  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   4057  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch the instruction words
   4058  1.1.6.2  bouyer 	mov.l		%d0,EXC_OPWORD(%a6)
   4059  1.1.6.2  bouyer 
   4060  1.1.6.2  bouyer ############################################################################
   4061  1.1.6.2  bouyer 
   4062  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   4063  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   4064  1.1.6.2  bouyer 
   4065  1.1.6.2  bouyer 	clr.b		SPCOND_FLG(%a6)		# clear "special case" flag
   4066  1.1.6.2  bouyer 
   4067  1.1.6.2  bouyer # Divide the fp instructions into 8 types based on the TYPE field in
   4068  1.1.6.2  bouyer # bits 6-8 of the opword(classes 6,7 are undefined).
   4069  1.1.6.2  bouyer # (for the '060, only two types  can take this exception)
   4070  1.1.6.2  bouyer #	bftst		%d0{&7:&3}		# test TYPE
   4071  1.1.6.2  bouyer 	btst		&22,%d0			# type 0 or 1 ?
   4072  1.1.6.2  bouyer 	bne.w		funimp_misc		# type 1
   4073  1.1.6.2  bouyer 
   4074  1.1.6.2  bouyer #########################################
   4075  1.1.6.2  bouyer # TYPE == 0: General instructions	#
   4076  1.1.6.2  bouyer #########################################
   4077  1.1.6.2  bouyer funimp_gen:
   4078  1.1.6.2  bouyer 
   4079  1.1.6.2  bouyer 	clr.b		STORE_FLG(%a6)		# clear "store result" flag
   4080  1.1.6.2  bouyer 
   4081  1.1.6.2  bouyer # clear the ccode byte and exception status byte
   4082  1.1.6.2  bouyer 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
   4083  1.1.6.2  bouyer 
   4084  1.1.6.2  bouyer 	bfextu		%d0{&16:&6},%d1		# extract upper 6 of cmdreg
   4085  1.1.6.2  bouyer 	cmpi.b		%d1,&0x17		# is op an fmovecr?
   4086  1.1.6.2  bouyer 	beq.w		funimp_fmovcr		# yes
   4087  1.1.6.2  bouyer 
   4088  1.1.6.2  bouyer funimp_gen_op:
   4089  1.1.6.2  bouyer 	bsr.l		_load_fop		# load
   4090  1.1.6.2  bouyer 
   4091  1.1.6.2  bouyer 	clr.l		%d0
   4092  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode
   4093  1.1.6.2  bouyer 
   4094  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1
   4095  1.1.6.2  bouyer 	andi.w		&0x003f,%d1		# extract extension bits
   4096  1.1.6.2  bouyer 	lsl.w		&0x3,%d1		# shift right 3 bits
   4097  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1		# insert src optag bits
   4098  1.1.6.2  bouyer 
   4099  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1		# pass dst ptr in a1
   4100  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass src ptr in a0
   4101  1.1.6.2  bouyer 
   4102  1.1.6.2  bouyer 	mov.w		(tbl_trans.w,%pc,%d1.w*2),%d1
   4103  1.1.6.2  bouyer 	jsr		(tbl_trans.w,%pc,%d1.w*1) # emulate
   4104  1.1.6.2  bouyer 
   4105  1.1.6.2  bouyer funimp_fsave:
   4106  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
   4107  1.1.6.2  bouyer 	bne.w		funimp_ena		# some are enabled
   4108  1.1.6.2  bouyer 
   4109  1.1.6.2  bouyer funimp_store:
   4110  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch Dn
   4111  1.1.6.2  bouyer 	bsr.l		store_fpreg		# store result to fp regfile
   4112  1.1.6.2  bouyer 
   4113  1.1.6.2  bouyer funimp_gen_exit:
   4114  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4115  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4116  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4117  1.1.6.2  bouyer 
   4118  1.1.6.2  bouyer funimp_gen_exit_cmp:
   4119  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mia7_flg # was the ea mode (sp)+ ?
   4120  1.1.6.2  bouyer 	beq.b		funimp_gen_exit_a7	# yes
   4121  1.1.6.2  bouyer 
   4122  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was the ea mode -(sp) ?
   4123  1.1.6.2  bouyer 	beq.b		funimp_gen_exit_a7	# yes
   4124  1.1.6.2  bouyer 
   4125  1.1.6.2  bouyer funimp_gen_exit_cont:
   4126  1.1.6.2  bouyer 	unlk		%a6
   4127  1.1.6.2  bouyer 
   4128  1.1.6.2  bouyer funimp_gen_exit_cont2:
   4129  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace on?
   4130  1.1.6.2  bouyer 	beq.l		_fpsp_done		# no
   4131  1.1.6.2  bouyer 
   4132  1.1.6.2  bouyer # this catches a problem with the case where an exception will be re-inserted
   4133  1.1.6.2  bouyer # into the machine. the frestore has already been executed...so, the fmov.l
   4134  1.1.6.2  bouyer # alone of the control register would trigger an unwanted exception.
   4135  1.1.6.2  bouyer # until I feel like fixing this, we'll sidestep the exception.
   4136  1.1.6.2  bouyer 	fsave		-(%sp)
   4137  1.1.6.2  bouyer 	fmov.l		%fpiar,0x14(%sp)	# "Current PC" is in FPIAR
   4138  1.1.6.2  bouyer 	frestore	(%sp)+
   4139  1.1.6.2  bouyer 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x24
   4140  1.1.6.2  bouyer 	bra.l		_real_trace
   4141  1.1.6.2  bouyer 
   4142  1.1.6.2  bouyer funimp_gen_exit_a7:
   4143  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# supervisor or user mode?
   4144  1.1.6.2  bouyer 	bne.b		funimp_gen_exit_a7_s	# supervisor
   4145  1.1.6.2  bouyer 
   4146  1.1.6.2  bouyer 	mov.l		%a0,-(%sp)
   4147  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0
   4148  1.1.6.2  bouyer 	mov.l		%a0,%usp
   4149  1.1.6.2  bouyer 	mov.l		(%sp)+,%a0
   4150  1.1.6.2  bouyer 	bra.b		funimp_gen_exit_cont
   4151  1.1.6.2  bouyer 
   4152  1.1.6.2  bouyer # if the instruction was executed from supervisor mode and the addressing
   4153  1.1.6.2  bouyer # mode was (a7)+, then the stack frame for the rte must be shifted "up"
   4154  1.1.6.2  bouyer # "n" bytes where "n" is the size of the src operand type.
   4155  1.1.6.2  bouyer # f<op>.{b,w,l,s,d,x,p}
   4156  1.1.6.2  bouyer funimp_gen_exit_a7_s:
   4157  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save d0
   4158  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%d0		# load new a7'
   4159  1.1.6.2  bouyer 	sub.l		OLD_A7(%a6),%d0		# subtract old a7'
   4160  1.1.6.2  bouyer 	mov.l		0x2+EXC_PC(%a6),(0x2+EXC_PC,%a6,%d0) # shift stack frame
   4161  1.1.6.2  bouyer 	mov.l		EXC_SR(%a6),(EXC_SR,%a6,%d0) # shift stack frame
   4162  1.1.6.2  bouyer 	mov.w		%d0,EXC_SR(%a6)		# store incr number
   4163  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   4164  1.1.6.2  bouyer 
   4165  1.1.6.2  bouyer 	unlk		%a6
   4166  1.1.6.2  bouyer 
   4167  1.1.6.2  bouyer 	add.w		(%sp),%sp		# stack frame shifted
   4168  1.1.6.2  bouyer 	bra.b		funimp_gen_exit_cont2
   4169  1.1.6.2  bouyer 
   4170  1.1.6.2  bouyer ######################
   4171  1.1.6.2  bouyer # fmovecr.x #ccc,fpn #
   4172  1.1.6.2  bouyer ######################
   4173  1.1.6.2  bouyer funimp_fmovcr:
   4174  1.1.6.2  bouyer 	clr.l		%d0
   4175  1.1.6.2  bouyer 	mov.b		FPCR_MODE(%a6),%d0
   4176  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1
   4177  1.1.6.2  bouyer 	andi.l		&0x0000007f,%d1		# pass rom offset in d1
   4178  1.1.6.2  bouyer 	bsr.l		smovcr
   4179  1.1.6.2  bouyer 	bra.w		funimp_fsave
   4180  1.1.6.2  bouyer 
   4181  1.1.6.2  bouyer #########################################################################
   4182  1.1.6.2  bouyer 
   4183  1.1.6.2  bouyer #
   4184  1.1.6.2  bouyer # the user has enabled some exceptions. we figure not to see this too
   4185  1.1.6.2  bouyer # often so that's why it gets lower priority.
   4186  1.1.6.2  bouyer #
   4187  1.1.6.2  bouyer funimp_ena:
   4188  1.1.6.2  bouyer 
   4189  1.1.6.2  bouyer # was an exception set that was also enabled?
   4190  1.1.6.2  bouyer 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled and set
   4191  1.1.6.2  bouyer 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
   4192  1.1.6.2  bouyer 	bne.b		funimp_exc		# at least one was set
   4193  1.1.6.2  bouyer 
   4194  1.1.6.2  bouyer # no exception that was enabled was set BUT if we got an exact overflow
   4195  1.1.6.2  bouyer # and overflow wasn't enabled but inexact was (yech!) then this is
   4196  1.1.6.2  bouyer # an inexact exception; otherwise, return to normal non-exception flow.
   4197  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   4198  1.1.6.2  bouyer 	beq.w		funimp_store		# no; return to normal flow
   4199  1.1.6.2  bouyer 
   4200  1.1.6.2  bouyer # the overflow w/ exact result happened but was inexact set in the FPCR?
   4201  1.1.6.2  bouyer funimp_ovfl:
   4202  1.1.6.2  bouyer 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
   4203  1.1.6.2  bouyer 	beq.w		funimp_store		# no; return to normal flow
   4204  1.1.6.2  bouyer 	bra.b		funimp_exc_ovfl		# yes
   4205  1.1.6.2  bouyer 
   4206  1.1.6.2  bouyer # some exception happened that was actually enabled.
   4207  1.1.6.2  bouyer # we'll insert this new exception into the FPU and then return.
   4208  1.1.6.2  bouyer funimp_exc:
   4209  1.1.6.2  bouyer 	subi.l		&24,%d0			# fix offset to be 0-8
   4210  1.1.6.2  bouyer 	cmpi.b		%d0,&0x6		# is exception INEX?
   4211  1.1.6.2  bouyer 	bne.b		funimp_exc_force	# no
   4212  1.1.6.2  bouyer 
   4213  1.1.6.2  bouyer # the enabled exception was inexact. so, if it occurs with an overflow
   4214  1.1.6.2  bouyer # or underflow that was disabled, then we have to force an overflow or
   4215  1.1.6.2  bouyer # underflow frame. the eventual overflow or underflow handler will see that
   4216  1.1.6.2  bouyer # it's actually an inexact and act appropriately. this is the only easy
   4217  1.1.6.2  bouyer # way to have the EXOP available for the enabled inexact handler when
   4218  1.1.6.2  bouyer # a disabled overflow or underflow has also happened.
   4219  1.1.6.2  bouyer 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
   4220  1.1.6.2  bouyer 	bne.b		funimp_exc_ovfl		# yes
   4221  1.1.6.2  bouyer 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur?
   4222  1.1.6.2  bouyer 	bne.b		funimp_exc_unfl		# yes
   4223  1.1.6.2  bouyer 
   4224  1.1.6.2  bouyer # force the fsave exception status bits to signal an exception of the
   4225  1.1.6.2  bouyer # appropriate type. don't forget to "skew" the source operand in case we
   4226  1.1.6.2  bouyer # "unskewed" the one the hardware initially gave us.
   4227  1.1.6.2  bouyer funimp_exc_force:
   4228  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save d0
   4229  1.1.6.2  bouyer 	bsr.l		funimp_skew		# check for special case
   4230  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   4231  1.1.6.2  bouyer 	mov.w		(tbl_funimp_except.b,%pc,%d0.w*2),2+FP_SRC(%a6)
   4232  1.1.6.2  bouyer 	bra.b		funimp_gen_exit2	# exit with frestore
   4233  1.1.6.2  bouyer 
   4234  1.1.6.2  bouyer tbl_funimp_except:
   4235  1.1.6.2  bouyer 	short		0xe002, 0xe006, 0xe004, 0xe005
   4236  1.1.6.2  bouyer 	short		0xe003, 0xe002, 0xe001, 0xe001
   4237  1.1.6.2  bouyer 
   4238  1.1.6.2  bouyer # insert an overflow frame
   4239  1.1.6.2  bouyer funimp_exc_ovfl:
   4240  1.1.6.2  bouyer 	bsr.l		funimp_skew		# check for special case
   4241  1.1.6.2  bouyer 	mov.w		&0xe005,2+FP_SRC(%a6)
   4242  1.1.6.2  bouyer 	bra.b		funimp_gen_exit2
   4243  1.1.6.2  bouyer 
   4244  1.1.6.2  bouyer # insert an underflow frame
   4245  1.1.6.2  bouyer funimp_exc_unfl:
   4246  1.1.6.2  bouyer 	bsr.l		funimp_skew		# check for special case
   4247  1.1.6.2  bouyer 	mov.w		&0xe003,2+FP_SRC(%a6)
   4248  1.1.6.2  bouyer 
   4249  1.1.6.2  bouyer # this is the general exit point for an enabled exception that will be
   4250  1.1.6.2  bouyer # restored into the machine for the instruction just emulated.
   4251  1.1.6.2  bouyer funimp_gen_exit2:
   4252  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4253  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4254  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4255  1.1.6.2  bouyer 
   4256  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# insert exceptional status
   4257  1.1.6.2  bouyer 
   4258  1.1.6.2  bouyer 	bra.w		funimp_gen_exit_cmp
   4259  1.1.6.2  bouyer 
   4260  1.1.6.2  bouyer ############################################################################
   4261  1.1.6.2  bouyer 
   4262  1.1.6.2  bouyer #
   4263  1.1.6.2  bouyer # TYPE == 1: FDB<cc>, FS<cc>, FTRAP<cc>
   4264  1.1.6.2  bouyer #
   4265  1.1.6.2  bouyer # These instructions were implemented on the '881/2 and '040 in hardware but
   4266  1.1.6.2  bouyer # are emulated in software on the '060.
   4267  1.1.6.2  bouyer #
   4268  1.1.6.2  bouyer funimp_misc:
   4269  1.1.6.2  bouyer 	bfextu		%d0{&10:&3},%d1		# extract mode field
   4270  1.1.6.2  bouyer 	cmpi.b		%d1,&0x1		# is it an fdb<cc>?
   4271  1.1.6.2  bouyer 	beq.w		funimp_fdbcc		# yes
   4272  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is it an fs<cc>?
   4273  1.1.6.2  bouyer 	bne.w		funimp_fscc		# yes
   4274  1.1.6.2  bouyer 	bfextu		%d0{&13:&3},%d1
   4275  1.1.6.2  bouyer 	cmpi.b		%d1,&0x2		# is it an fs<cc>?
   4276  1.1.6.2  bouyer 	blt.w		funimp_fscc		# yes
   4277  1.1.6.2  bouyer 
   4278  1.1.6.2  bouyer #########################
   4279  1.1.6.2  bouyer # ftrap<cc>		#
   4280  1.1.6.2  bouyer # ftrap<cc>.w #<data>	#
   4281  1.1.6.2  bouyer # ftrap<cc>.l #<data>	#
   4282  1.1.6.2  bouyer #########################
   4283  1.1.6.2  bouyer funimp_ftrapcc:
   4284  1.1.6.2  bouyer 
   4285  1.1.6.2  bouyer 	bsr.l		_ftrapcc		# FTRAP<cc>()
   4286  1.1.6.2  bouyer 
   4287  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
   4288  1.1.6.2  bouyer 	beq.w		funimp_bsun		# yes
   4289  1.1.6.2  bouyer 
   4290  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&ftrapcc_flg # should a trap occur?
   4291  1.1.6.2  bouyer 	bne.w		funimp_done		# no
   4292  1.1.6.2  bouyer 
   4293  1.1.6.2  bouyer #	 FP UNIMP FRAME		   TRAP  FRAME
   4294  1.1.6.2  bouyer #	*****************	*****************
   4295  1.1.6.2  bouyer #	**    <EA>     **	**  Current PC **
   4296  1.1.6.2  bouyer #	*****************	*****************
   4297  1.1.6.2  bouyer #	* 0x2 *  0x02c	*	* 0x2 *  0x01c  *
   4298  1.1.6.2  bouyer #	*****************	*****************
   4299  1.1.6.2  bouyer #	**   Next PC   **	**   Next PC   **
   4300  1.1.6.2  bouyer #	*****************	*****************
   4301  1.1.6.2  bouyer #	*      SR	*	*      SR	*
   4302  1.1.6.2  bouyer #	*****************	*****************
   4303  1.1.6.2  bouyer #	    (6 words)		    (6 words)
   4304  1.1.6.2  bouyer #
   4305  1.1.6.2  bouyer # the ftrapcc instruction should take a trap. so, here we must create a
   4306  1.1.6.2  bouyer # trap stack frame from an unimplemented fp instruction stack frame and
   4307  1.1.6.2  bouyer # jump to the user supplied entry point for the trap exception
   4308  1.1.6.2  bouyer funimp_ftrapcc_tp:
   4309  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_EA(%a6) # Address = Current PC
   4310  1.1.6.2  bouyer 	mov.w		&0x201c,EXC_VOFF(%a6)	# Vector Offset = 0x01c
   4311  1.1.6.2  bouyer 
   4312  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4313  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4314  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4315  1.1.6.2  bouyer 
   4316  1.1.6.2  bouyer 	unlk		%a6
   4317  1.1.6.2  bouyer 	bra.l		_real_trap
   4318  1.1.6.2  bouyer 
   4319  1.1.6.2  bouyer #########################
   4320  1.1.6.2  bouyer # fdb<cc> Dn,<label>	#
   4321  1.1.6.2  bouyer #########################
   4322  1.1.6.2  bouyer funimp_fdbcc:
   4323  1.1.6.2  bouyer 
   4324  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   4325  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   4326  1.1.6.2  bouyer 	bsr.l		_imem_read_word		# read displacement
   4327  1.1.6.2  bouyer 
   4328  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   4329  1.1.6.2  bouyer 	bne.w		funimp_iacc		# yes
   4330  1.1.6.2  bouyer 
   4331  1.1.6.2  bouyer 	ext.l		%d0			# sign extend displacement
   4332  1.1.6.2  bouyer 
   4333  1.1.6.2  bouyer 	bsr.l		_fdbcc			# FDB<cc>()
   4334  1.1.6.2  bouyer 
   4335  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
   4336  1.1.6.2  bouyer 	beq.w		funimp_bsun
   4337  1.1.6.2  bouyer 
   4338  1.1.6.2  bouyer 	bra.w		funimp_done		# branch to finish
   4339  1.1.6.2  bouyer 
   4340  1.1.6.2  bouyer #################
   4341  1.1.6.2  bouyer # fs<cc>.b <ea>	#
   4342  1.1.6.2  bouyer #################
   4343  1.1.6.2  bouyer funimp_fscc:
   4344  1.1.6.2  bouyer 
   4345  1.1.6.2  bouyer 	bsr.l		_fscc			# FS<cc>()
   4346  1.1.6.2  bouyer 
   4347  1.1.6.2  bouyer # I am assuming here that an "fs<cc>.b -(An)" or "fs<cc>.b (An)+" instruction
   4348  1.1.6.2  bouyer # does not need to update "An" before taking a bsun exception.
   4349  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
   4350  1.1.6.2  bouyer 	beq.w		funimp_bsun
   4351  1.1.6.2  bouyer 
   4352  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# yes; is it a user mode exception?
   4353  1.1.6.2  bouyer 	bne.b		funimp_fscc_s		# no
   4354  1.1.6.2  bouyer 
   4355  1.1.6.2  bouyer funimp_fscc_u:
   4356  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# yes; set new USP
   4357  1.1.6.2  bouyer 	mov.l		%a0,%usp
   4358  1.1.6.2  bouyer 	bra.w		funimp_done		# branch to finish
   4359  1.1.6.2  bouyer 
   4360  1.1.6.2  bouyer # remember, I'm assuming that post-increment is bogus...(it IS!!!)
   4361  1.1.6.2  bouyer # so, the least significant WORD of the stacked effective address got
   4362  1.1.6.2  bouyer # overwritten by the "fs<cc> -(An)". We must shift the stack frame "down"
   4363  1.1.6.2  bouyer # so that the rte will work correctly without destroying the result.
   4364  1.1.6.2  bouyer # even though the operation size is byte, the stack ptr is decr by 2.
   4365  1.1.6.2  bouyer #
   4366  1.1.6.2  bouyer # remember, also, this instruction may be traced.
   4367  1.1.6.2  bouyer funimp_fscc_s:
   4368  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was a7 modified?
   4369  1.1.6.2  bouyer 	bne.w		funimp_done		# no
   4370  1.1.6.2  bouyer 
   4371  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4372  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4373  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4374  1.1.6.2  bouyer 
   4375  1.1.6.2  bouyer 	unlk		%a6
   4376  1.1.6.2  bouyer 
   4377  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace enabled?
   4378  1.1.6.2  bouyer 	bne.b		funimp_fscc_s_trace	# yes
   4379  1.1.6.2  bouyer 
   4380  1.1.6.2  bouyer 	subq.l		&0x2,%sp
   4381  1.1.6.2  bouyer 	mov.l		0x2(%sp),(%sp)		# shift SR,hi(PC) "down"
   4382  1.1.6.2  bouyer 	mov.l		0x6(%sp),0x4(%sp)	# shift lo(PC),voff "down"
   4383  1.1.6.2  bouyer 	bra.l		_fpsp_done
   4384  1.1.6.2  bouyer 
   4385  1.1.6.2  bouyer funimp_fscc_s_trace:
   4386  1.1.6.2  bouyer 	subq.l		&0x2,%sp
   4387  1.1.6.2  bouyer 	mov.l		0x2(%sp),(%sp)		# shift SR,hi(PC) "down"
   4388  1.1.6.2  bouyer 	mov.w		0x6(%sp),0x4(%sp)	# shift lo(PC)
   4389  1.1.6.2  bouyer 	mov.w		&0x2024,0x6(%sp)	# fmt/voff = $2024
   4390  1.1.6.2  bouyer 	fmov.l		%fpiar,0x8(%sp)		# insert "current PC"
   4391  1.1.6.2  bouyer 
   4392  1.1.6.2  bouyer 	bra.l		_real_trace
   4393  1.1.6.2  bouyer 
   4394  1.1.6.2  bouyer #
   4395  1.1.6.2  bouyer # The ftrap<cc>, fs<cc>, or fdb<cc> is to take an enabled bsun. we must convert
   4396  1.1.6.2  bouyer # the fp unimplemented instruction exception stack frame into a bsun stack frame,
   4397  1.1.6.2  bouyer # restore a bsun exception into the machine, and branch to the user
   4398  1.1.6.2  bouyer # supplied bsun hook.
   4399  1.1.6.2  bouyer #
   4400  1.1.6.2  bouyer #	 FP UNIMP FRAME		   BSUN FRAME
   4401  1.1.6.2  bouyer #	*****************	*****************
   4402  1.1.6.2  bouyer #	**    <EA>     **	* 0x0 * 0x0c0	*
   4403  1.1.6.2  bouyer #	*****************	*****************
   4404  1.1.6.2  bouyer #	* 0x2 *  0x02c  *	** Current PC  **
   4405  1.1.6.2  bouyer #	*****************	*****************
   4406  1.1.6.2  bouyer #	**   Next PC   **	*      SR	*
   4407  1.1.6.2  bouyer #	*****************	*****************
   4408  1.1.6.2  bouyer #	*      SR	*	    (4 words)
   4409  1.1.6.2  bouyer #	*****************
   4410  1.1.6.2  bouyer #	    (6 words)
   4411  1.1.6.2  bouyer #
   4412  1.1.6.2  bouyer funimp_bsun:
   4413  1.1.6.2  bouyer 	mov.w		&0x00c0,2+EXC_EA(%a6)	# Fmt = 0x0; Vector Offset = 0x0c0
   4414  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_VOFF(%a6) # PC = Current PC
   4415  1.1.6.2  bouyer 	mov.w		EXC_SR(%a6),2+EXC_PC(%a6) # shift SR "up"
   4416  1.1.6.2  bouyer 
   4417  1.1.6.2  bouyer 	mov.w		&0xe000,2+FP_SRC(%a6)	# bsun exception enabled
   4418  1.1.6.2  bouyer 
   4419  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4420  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4421  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4422  1.1.6.2  bouyer 
   4423  1.1.6.2  bouyer 	frestore	FP_SRC(%a6)		# restore bsun exception
   4424  1.1.6.2  bouyer 
   4425  1.1.6.2  bouyer 	unlk		%a6
   4426  1.1.6.2  bouyer 
   4427  1.1.6.2  bouyer 	addq.l		&0x4,%sp		# erase sludge
   4428  1.1.6.2  bouyer 
   4429  1.1.6.2  bouyer 	bra.l		_real_bsun		# branch to user bsun hook
   4430  1.1.6.2  bouyer 
   4431  1.1.6.2  bouyer #
   4432  1.1.6.2  bouyer # all ftrapcc/fscc/fdbcc processing has been completed. unwind the stack frame
   4433  1.1.6.2  bouyer # and return.
   4434  1.1.6.2  bouyer #
   4435  1.1.6.2  bouyer # as usual, we have to check for trace mode being on here. since instructions
   4436  1.1.6.2  bouyer # modifying the supervisor stack frame don't pass through here, this is a
   4437  1.1.6.2  bouyer # relatively easy task.
   4438  1.1.6.2  bouyer #
   4439  1.1.6.2  bouyer funimp_done:
   4440  1.1.6.2  bouyer 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
   4441  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4442  1.1.6.2  bouyer  	movm.l		EXC_DREGS(%a6),&0x0303 	# restore d0-d1/a0-a1
   4443  1.1.6.2  bouyer 
   4444  1.1.6.2  bouyer 	unlk		%a6
   4445  1.1.6.2  bouyer 
   4446  1.1.6.2  bouyer 	btst		&0x7,(%sp)		# is trace enabled?
   4447  1.1.6.2  bouyer 	bne.b		funimp_trace		# yes
   4448  1.1.6.2  bouyer 
   4449  1.1.6.2  bouyer 	bra.l		_fpsp_done
   4450  1.1.6.2  bouyer 
   4451  1.1.6.2  bouyer #	 FP UNIMP FRAME		  TRACE  FRAME
   4452  1.1.6.2  bouyer #	*****************	*****************
   4453  1.1.6.2  bouyer #	**    <EA>     **	**  Current PC **
   4454  1.1.6.2  bouyer #	*****************	*****************
   4455  1.1.6.2  bouyer #	* 0x2 *  0x02c	*	* 0x2 *  0x024  *
   4456  1.1.6.2  bouyer #	*****************	*****************
   4457  1.1.6.2  bouyer #	**   Next PC   **	**   Next PC   **
   4458  1.1.6.2  bouyer #	*****************	*****************
   4459  1.1.6.2  bouyer #	*      SR	*	*      SR	*
   4460  1.1.6.2  bouyer #	*****************	*****************
   4461  1.1.6.2  bouyer #	    (6 words)		    (6 words)
   4462  1.1.6.2  bouyer #
   4463  1.1.6.2  bouyer # the fscc instruction should take a trace trap. so, here we must create a
   4464  1.1.6.2  bouyer # trace stack frame from an unimplemented fp instruction stack frame and
   4465  1.1.6.2  bouyer # jump to the user supplied entry point for the trace exception
   4466  1.1.6.2  bouyer funimp_trace:
   4467  1.1.6.2  bouyer 	fmov.l		%fpiar,0x8(%sp)		# current PC is in fpiar
   4468  1.1.6.2  bouyer 	mov.b		&0x24,0x7(%sp)		# vector offset = 0x024
   4469  1.1.6.2  bouyer 
   4470  1.1.6.2  bouyer 	bra.l		_real_trace
   4471  1.1.6.2  bouyer 
   4472  1.1.6.2  bouyer ################################################################
   4473  1.1.6.2  bouyer 
   4474  1.1.6.2  bouyer 	global		tbl_trans
   4475  1.1.6.2  bouyer 	swbeg		&0x1c0
   4476  1.1.6.2  bouyer tbl_trans:
   4477  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-0 fmovecr all
   4478  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-1 fmovecr all
   4479  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-2 fmovecr all
   4480  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-3 fmovecr all
   4481  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-4 fmovecr all
   4482  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-5 fmovecr all
   4483  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-6 fmovecr all
   4484  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $00-7 fmovecr all
   4485  1.1.6.2  bouyer 
   4486  1.1.6.2  bouyer 	short 		tbl_trans - tbl_trans	# $01-0 fint norm
   4487  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $01-1 fint zero
   4488  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $01-2 fint inf
   4489  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $01-3 fint qnan
   4490  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $01-5 fint denorm
   4491  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $01-4 fint snan
   4492  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $01-6 fint unnorm
   4493  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $01-7 ERROR
   4494  1.1.6.2  bouyer 
   4495  1.1.6.2  bouyer 	short		ssinh	 - tbl_trans	# $02-0 fsinh norm
   4496  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $02-1 fsinh zero
   4497  1.1.6.2  bouyer 	short		src_inf	 - tbl_trans	# $02-2 fsinh inf
   4498  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $02-3 fsinh qnan
   4499  1.1.6.2  bouyer 	short		ssinhd	 - tbl_trans	# $02-5 fsinh denorm
   4500  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $02-4 fsinh snan
   4501  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $02-6 fsinh unnorm
   4502  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $02-7 ERROR
   4503  1.1.6.2  bouyer 
   4504  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-0 fintrz norm
   4505  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-1 fintrz zero
   4506  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-2 fintrz inf
   4507  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-3 fintrz qnan
   4508  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-5 fintrz denorm
   4509  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-4 fintrz snan
   4510  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-6 fintrz unnorm
   4511  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $03-7 ERROR
   4512  1.1.6.2  bouyer 
   4513  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-0 fsqrt norm
   4514  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-1 fsqrt zero
   4515  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-2 fsqrt inf
   4516  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-3 fsqrt qnan
   4517  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-5 fsqrt denorm
   4518  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-4 fsqrt snan
   4519  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-6 fsqrt unnorm
   4520  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $04-7 ERROR
   4521  1.1.6.2  bouyer 
   4522  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-0 ERROR
   4523  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-1 ERROR
   4524  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-2 ERROR
   4525  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-3 ERROR
   4526  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-4 ERROR
   4527  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-5 ERROR
   4528  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-6 ERROR
   4529  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $05-7 ERROR
   4530  1.1.6.2  bouyer 
   4531  1.1.6.2  bouyer 	short		slognp1	 - tbl_trans	# $06-0 flognp1 norm
   4532  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $06-1 flognp1 zero
   4533  1.1.6.2  bouyer 	short		sopr_inf - tbl_trans	# $06-2 flognp1 inf
   4534  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $06-3 flognp1 qnan
   4535  1.1.6.2  bouyer 	short		slognp1d - tbl_trans	# $06-5 flognp1 denorm
   4536  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $06-4 flognp1 snan
   4537  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $06-6 flognp1 unnorm
   4538  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $06-7 ERROR
   4539  1.1.6.2  bouyer 
   4540  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-0 ERROR
   4541  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-1 ERROR
   4542  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-2 ERROR
   4543  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-3 ERROR
   4544  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-4 ERROR
   4545  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-5 ERROR
   4546  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-6 ERROR
   4547  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $07-7 ERROR
   4548  1.1.6.2  bouyer 
   4549  1.1.6.2  bouyer 	short		setoxm1	 - tbl_trans	# $08-0 fetoxm1 norm
   4550  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $08-1 fetoxm1 zero
   4551  1.1.6.2  bouyer 	short		setoxm1i - tbl_trans	# $08-2 fetoxm1 inf
   4552  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $08-3 fetoxm1 qnan
   4553  1.1.6.2  bouyer 	short		setoxm1d - tbl_trans	# $08-5 fetoxm1 denorm
   4554  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $08-4 fetoxm1 snan
   4555  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $08-6 fetoxm1 unnorm
   4556  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $08-7 ERROR
   4557  1.1.6.2  bouyer 
   4558  1.1.6.2  bouyer 	short		stanh	 - tbl_trans	# $09-0 ftanh norm
   4559  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $09-1 ftanh zero
   4560  1.1.6.2  bouyer 	short		src_one	 - tbl_trans	# $09-2 ftanh inf
   4561  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $09-3 ftanh qnan
   4562  1.1.6.2  bouyer 	short		stanhd	 - tbl_trans	# $09-5 ftanh denorm
   4563  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $09-4 ftanh snan
   4564  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $09-6 ftanh unnorm
   4565  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $09-7 ERROR
   4566  1.1.6.2  bouyer 
   4567  1.1.6.2  bouyer 	short		satan	 - tbl_trans	# $0a-0 fatan norm
   4568  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $0a-1 fatan zero
   4569  1.1.6.2  bouyer 	short		spi_2	 - tbl_trans	# $0a-2 fatan inf
   4570  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $0a-3 fatan qnan
   4571  1.1.6.2  bouyer 	short		satand	 - tbl_trans	# $0a-5 fatan denorm
   4572  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $0a-4 fatan snan
   4573  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0a-6 fatan unnorm
   4574  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0a-7 ERROR
   4575  1.1.6.2  bouyer 
   4576  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-0 ERROR
   4577  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-1 ERROR
   4578  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-2 ERROR
   4579  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-3 ERROR
   4580  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-4 ERROR
   4581  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-5 ERROR
   4582  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-6 ERROR
   4583  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0b-7 ERROR
   4584  1.1.6.2  bouyer 
   4585  1.1.6.2  bouyer 	short		sasin	 - tbl_trans	# $0c-0 fasin norm
   4586  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $0c-1 fasin zero
   4587  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $0c-2 fasin inf
   4588  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $0c-3 fasin qnan
   4589  1.1.6.2  bouyer 	short		sasind	 - tbl_trans	# $0c-5 fasin denorm
   4590  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $0c-4 fasin snan
   4591  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0c-6 fasin unnorm
   4592  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0c-7 ERROR
   4593  1.1.6.2  bouyer 
   4594  1.1.6.2  bouyer 	short		satanh	 - tbl_trans	# $0d-0 fatanh norm
   4595  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $0d-1 fatanh zero
   4596  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $0d-2 fatanh inf
   4597  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $0d-3 fatanh qnan
   4598  1.1.6.2  bouyer 	short		satanhd	 - tbl_trans	# $0d-5 fatanh denorm
   4599  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $0d-4 fatanh snan
   4600  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0d-6 fatanh unnorm
   4601  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0d-7 ERROR
   4602  1.1.6.2  bouyer 
   4603  1.1.6.2  bouyer 	short		ssin	 - tbl_trans	# $0e-0 fsin norm
   4604  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $0e-1 fsin zero
   4605  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $0e-2 fsin inf
   4606  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $0e-3 fsin qnan
   4607  1.1.6.2  bouyer 	short		ssind	 - tbl_trans	# $0e-5 fsin denorm
   4608  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $0e-4 fsin snan
   4609  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0e-6 fsin unnorm
   4610  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0e-7 ERROR
   4611  1.1.6.2  bouyer 
   4612  1.1.6.2  bouyer 	short		stan	 - tbl_trans	# $0f-0 ftan norm
   4613  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $0f-1 ftan zero
   4614  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $0f-2 ftan inf
   4615  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $0f-3 ftan qnan
   4616  1.1.6.2  bouyer 	short		stand	 - tbl_trans	# $0f-5 ftan denorm
   4617  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $0f-4 ftan snan
   4618  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0f-6 ftan unnorm
   4619  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $0f-7 ERROR
   4620  1.1.6.2  bouyer 
   4621  1.1.6.2  bouyer 	short		setox	 - tbl_trans	# $10-0 fetox norm
   4622  1.1.6.2  bouyer 	short		ld_pone	 - tbl_trans	# $10-1 fetox zero
   4623  1.1.6.2  bouyer 	short		szr_inf	 - tbl_trans	# $10-2 fetox inf
   4624  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $10-3 fetox qnan
   4625  1.1.6.2  bouyer 	short		setoxd	 - tbl_trans	# $10-5 fetox denorm
   4626  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $10-4 fetox snan
   4627  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $10-6 fetox unnorm
   4628  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $10-7 ERROR
   4629  1.1.6.2  bouyer 
   4630  1.1.6.2  bouyer 	short		stwotox	 - tbl_trans	# $11-0 ftwotox norm
   4631  1.1.6.2  bouyer 	short		ld_pone	 - tbl_trans	# $11-1 ftwotox zero
   4632  1.1.6.2  bouyer 	short		szr_inf	 - tbl_trans	# $11-2 ftwotox inf
   4633  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $11-3 ftwotox qnan
   4634  1.1.6.2  bouyer 	short		stwotoxd - tbl_trans	# $11-5 ftwotox denorm
   4635  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $11-4 ftwotox snan
   4636  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $11-6 ftwotox unnorm
   4637  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $11-7 ERROR
   4638  1.1.6.2  bouyer 
   4639  1.1.6.2  bouyer 	short		stentox	 - tbl_trans	# $12-0 ftentox norm
   4640  1.1.6.2  bouyer 	short		ld_pone	 - tbl_trans	# $12-1 ftentox zero
   4641  1.1.6.2  bouyer 	short		szr_inf	 - tbl_trans	# $12-2 ftentox inf
   4642  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $12-3 ftentox qnan
   4643  1.1.6.2  bouyer 	short		stentoxd - tbl_trans	# $12-5 ftentox denorm
   4644  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $12-4 ftentox snan
   4645  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $12-6 ftentox unnorm
   4646  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $12-7 ERROR
   4647  1.1.6.2  bouyer 
   4648  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-0 ERROR
   4649  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-1 ERROR
   4650  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-2 ERROR
   4651  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-3 ERROR
   4652  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-4 ERROR
   4653  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-5 ERROR
   4654  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-6 ERROR
   4655  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $13-7 ERROR
   4656  1.1.6.2  bouyer 
   4657  1.1.6.2  bouyer 	short		slogn	 - tbl_trans	# $14-0 flogn norm
   4658  1.1.6.2  bouyer 	short		t_dz2	 - tbl_trans	# $14-1 flogn zero
   4659  1.1.6.2  bouyer 	short		sopr_inf - tbl_trans	# $14-2 flogn inf
   4660  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $14-3 flogn qnan
   4661  1.1.6.2  bouyer 	short		slognd	 - tbl_trans	# $14-5 flogn denorm
   4662  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $14-4 flogn snan
   4663  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $14-6 flogn unnorm
   4664  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $14-7 ERROR
   4665  1.1.6.2  bouyer 
   4666  1.1.6.2  bouyer 	short		slog10	 - tbl_trans	# $15-0 flog10 norm
   4667  1.1.6.2  bouyer 	short		t_dz2	 - tbl_trans	# $15-1 flog10 zero
   4668  1.1.6.2  bouyer 	short		sopr_inf - tbl_trans	# $15-2 flog10 inf
   4669  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $15-3 flog10 qnan
   4670  1.1.6.2  bouyer 	short		slog10d	 - tbl_trans	# $15-5 flog10 denorm
   4671  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $15-4 flog10 snan
   4672  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $15-6 flog10 unnorm
   4673  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $15-7 ERROR
   4674  1.1.6.2  bouyer 
   4675  1.1.6.2  bouyer 	short		slog2	 - tbl_trans	# $16-0 flog2 norm
   4676  1.1.6.2  bouyer 	short		t_dz2	 - tbl_trans	# $16-1 flog2 zero
   4677  1.1.6.2  bouyer 	short		sopr_inf - tbl_trans	# $16-2 flog2 inf
   4678  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $16-3 flog2 qnan
   4679  1.1.6.2  bouyer 	short		slog2d	 - tbl_trans	# $16-5 flog2 denorm
   4680  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $16-4 flog2 snan
   4681  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $16-6 flog2 unnorm
   4682  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $16-7 ERROR
   4683  1.1.6.2  bouyer 
   4684  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-0 ERROR
   4685  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-1 ERROR
   4686  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-2 ERROR
   4687  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-3 ERROR
   4688  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-4 ERROR
   4689  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-5 ERROR
   4690  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-6 ERROR
   4691  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $17-7 ERROR
   4692  1.1.6.2  bouyer 
   4693  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-0 fabs norm
   4694  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-1 fabs zero
   4695  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-2 fabs inf
   4696  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-3 fabs qnan
   4697  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-5 fabs denorm
   4698  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-4 fabs snan
   4699  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-6 fabs unnorm
   4700  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $18-7 ERROR
   4701  1.1.6.2  bouyer 
   4702  1.1.6.2  bouyer 	short		scosh	 - tbl_trans	# $19-0 fcosh norm
   4703  1.1.6.2  bouyer 	short		ld_pone	 - tbl_trans	# $19-1 fcosh zero
   4704  1.1.6.2  bouyer 	short		ld_pinf	 - tbl_trans	# $19-2 fcosh inf
   4705  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $19-3 fcosh qnan
   4706  1.1.6.2  bouyer 	short		scoshd	 - tbl_trans	# $19-5 fcosh denorm
   4707  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $19-4 fcosh snan
   4708  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $19-6 fcosh unnorm
   4709  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $19-7 ERROR
   4710  1.1.6.2  bouyer 
   4711  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-0 fneg norm
   4712  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-1 fneg zero
   4713  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-2 fneg inf
   4714  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-3 fneg qnan
   4715  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-5 fneg denorm
   4716  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-4 fneg snan
   4717  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-6 fneg unnorm
   4718  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1a-7 ERROR
   4719  1.1.6.2  bouyer 
   4720  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-0 ERROR
   4721  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-1 ERROR
   4722  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-2 ERROR
   4723  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-3 ERROR
   4724  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-4 ERROR
   4725  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-5 ERROR
   4726  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-6 ERROR
   4727  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1b-7 ERROR
   4728  1.1.6.2  bouyer 
   4729  1.1.6.2  bouyer 	short		sacos	 - tbl_trans	# $1c-0 facos norm
   4730  1.1.6.2  bouyer 	short		ld_ppi2	 - tbl_trans	# $1c-1 facos zero
   4731  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $1c-2 facos inf
   4732  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $1c-3 facos qnan
   4733  1.1.6.2  bouyer 	short		sacosd	 - tbl_trans	# $1c-5 facos denorm
   4734  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $1c-4 facos snan
   4735  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1c-6 facos unnorm
   4736  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1c-7 ERROR
   4737  1.1.6.2  bouyer 
   4738  1.1.6.2  bouyer 	short		scos	 - tbl_trans	# $1d-0 fcos norm
   4739  1.1.6.2  bouyer 	short		ld_pone	 - tbl_trans	# $1d-1 fcos zero
   4740  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $1d-2 fcos inf
   4741  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $1d-3 fcos qnan
   4742  1.1.6.2  bouyer 	short		scosd	 - tbl_trans	# $1d-5 fcos denorm
   4743  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $1d-4 fcos snan
   4744  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1d-6 fcos unnorm
   4745  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1d-7 ERROR
   4746  1.1.6.2  bouyer 
   4747  1.1.6.2  bouyer 	short		sgetexp	 - tbl_trans	# $1e-0 fgetexp norm
   4748  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $1e-1 fgetexp zero
   4749  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $1e-2 fgetexp inf
   4750  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $1e-3 fgetexp qnan
   4751  1.1.6.2  bouyer 	short		sgetexpd - tbl_trans	# $1e-5 fgetexp denorm
   4752  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $1e-4 fgetexp snan
   4753  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1e-6 fgetexp unnorm
   4754  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1e-7 ERROR
   4755  1.1.6.2  bouyer 
   4756  1.1.6.2  bouyer 	short		sgetman	 - tbl_trans	# $1f-0 fgetman norm
   4757  1.1.6.2  bouyer 	short		src_zero - tbl_trans	# $1f-1 fgetman zero
   4758  1.1.6.2  bouyer 	short		t_operr	 - tbl_trans	# $1f-2 fgetman inf
   4759  1.1.6.2  bouyer 	short		src_qnan - tbl_trans	# $1f-3 fgetman qnan
   4760  1.1.6.2  bouyer 	short		sgetmand - tbl_trans	# $1f-5 fgetman denorm
   4761  1.1.6.2  bouyer 	short		src_snan - tbl_trans	# $1f-4 fgetman snan
   4762  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1f-6 fgetman unnorm
   4763  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $1f-7 ERROR
   4764  1.1.6.2  bouyer 
   4765  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-0 fdiv norm
   4766  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-1 fdiv zero
   4767  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-2 fdiv inf
   4768  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-3 fdiv qnan
   4769  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-5 fdiv denorm
   4770  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-4 fdiv snan
   4771  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-6 fdiv unnorm
   4772  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $20-7 ERROR
   4773  1.1.6.2  bouyer 
   4774  1.1.6.2  bouyer 	short		smod_snorm - tbl_trans	# $21-0 fmod norm
   4775  1.1.6.2  bouyer 	short		smod_szero - tbl_trans	# $21-1 fmod zero
   4776  1.1.6.2  bouyer 	short		smod_sinf - tbl_trans	# $21-2 fmod inf
   4777  1.1.6.2  bouyer 	short		sop_sqnan - tbl_trans	# $21-3 fmod qnan
   4778  1.1.6.2  bouyer 	short		smod_sdnrm - tbl_trans	# $21-5 fmod denorm
   4779  1.1.6.2  bouyer 	short		sop_ssnan - tbl_trans	# $21-4 fmod snan
   4780  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $21-6 fmod unnorm
   4781  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $21-7 ERROR
   4782  1.1.6.2  bouyer 
   4783  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-0 fadd norm
   4784  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-1 fadd zero
   4785  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-2 fadd inf
   4786  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-3 fadd qnan
   4787  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-5 fadd denorm
   4788  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-4 fadd snan
   4789  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-6 fadd unnorm
   4790  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $22-7 ERROR
   4791  1.1.6.2  bouyer 
   4792  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-0 fmul norm
   4793  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-1 fmul zero
   4794  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-2 fmul inf
   4795  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-3 fmul qnan
   4796  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-5 fmul denorm
   4797  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-4 fmul snan
   4798  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-6 fmul unnorm
   4799  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $23-7 ERROR
   4800  1.1.6.2  bouyer 
   4801  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-0 fsgldiv norm
   4802  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-1 fsgldiv zero
   4803  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-2 fsgldiv inf
   4804  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-3 fsgldiv qnan
   4805  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-5 fsgldiv denorm
   4806  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-4 fsgldiv snan
   4807  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-6 fsgldiv unnorm
   4808  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $24-7 ERROR
   4809  1.1.6.2  bouyer 
   4810  1.1.6.2  bouyer 	short		srem_snorm - tbl_trans	# $25-0 frem norm
   4811  1.1.6.2  bouyer 	short		srem_szero - tbl_trans	# $25-1 frem zero
   4812  1.1.6.2  bouyer 	short		srem_sinf - tbl_trans	# $25-2 frem inf
   4813  1.1.6.2  bouyer 	short		sop_sqnan - tbl_trans	# $25-3 frem qnan
   4814  1.1.6.2  bouyer 	short		srem_sdnrm - tbl_trans	# $25-5 frem denorm
   4815  1.1.6.2  bouyer 	short		sop_ssnan - tbl_trans	# $25-4 frem snan
   4816  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $25-6 frem unnorm
   4817  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $25-7 ERROR
   4818  1.1.6.2  bouyer 
   4819  1.1.6.2  bouyer 	short		sscale_snorm - tbl_trans # $26-0 fscale norm
   4820  1.1.6.2  bouyer 	short		sscale_szero - tbl_trans # $26-1 fscale zero
   4821  1.1.6.2  bouyer 	short		sscale_sinf - tbl_trans	# $26-2 fscale inf
   4822  1.1.6.2  bouyer 	short		sop_sqnan - tbl_trans	# $26-3 fscale qnan
   4823  1.1.6.2  bouyer 	short		sscale_sdnrm - tbl_trans # $26-5 fscale denorm
   4824  1.1.6.2  bouyer 	short		sop_ssnan - tbl_trans	# $26-4 fscale snan
   4825  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $26-6 fscale unnorm
   4826  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $26-7 ERROR
   4827  1.1.6.2  bouyer 
   4828  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-0 fsglmul norm
   4829  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-1 fsglmul zero
   4830  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-2 fsglmul inf
   4831  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-3 fsglmul qnan
   4832  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-5 fsglmul denorm
   4833  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-4 fsglmul snan
   4834  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-6 fsglmul unnorm
   4835  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $27-7 ERROR
   4836  1.1.6.2  bouyer 
   4837  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-0 fsub norm
   4838  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-1 fsub zero
   4839  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-2 fsub inf
   4840  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-3 fsub qnan
   4841  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-5 fsub denorm
   4842  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-4 fsub snan
   4843  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-6 fsub unnorm
   4844  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $28-7 ERROR
   4845  1.1.6.2  bouyer 
   4846  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-0 ERROR
   4847  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-1 ERROR
   4848  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-2 ERROR
   4849  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-3 ERROR
   4850  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-4 ERROR
   4851  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-5 ERROR
   4852  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-6 ERROR
   4853  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $29-7 ERROR
   4854  1.1.6.2  bouyer 
   4855  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-0 ERROR
   4856  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-1 ERROR
   4857  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-2 ERROR
   4858  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-3 ERROR
   4859  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-4 ERROR
   4860  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-5 ERROR
   4861  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-6 ERROR
   4862  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2a-7 ERROR
   4863  1.1.6.2  bouyer 
   4864  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-0 ERROR
   4865  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-1 ERROR
   4866  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-2 ERROR
   4867  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-3 ERROR
   4868  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-4 ERROR
   4869  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-5 ERROR
   4870  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-6 ERROR
   4871  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2b-7 ERROR
   4872  1.1.6.2  bouyer 
   4873  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-0 ERROR
   4874  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-1 ERROR
   4875  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-2 ERROR
   4876  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-3 ERROR
   4877  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-4 ERROR
   4878  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-5 ERROR
   4879  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-6 ERROR
   4880  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2c-7 ERROR
   4881  1.1.6.2  bouyer 
   4882  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-0 ERROR
   4883  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-1 ERROR
   4884  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-2 ERROR
   4885  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-3 ERROR
   4886  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-4 ERROR
   4887  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-5 ERROR
   4888  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-6 ERROR
   4889  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2d-7 ERROR
   4890  1.1.6.2  bouyer 
   4891  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-0 ERROR
   4892  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-1 ERROR
   4893  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-2 ERROR
   4894  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-3 ERROR
   4895  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-4 ERROR
   4896  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-5 ERROR
   4897  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-6 ERROR
   4898  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2e-7 ERROR
   4899  1.1.6.2  bouyer 
   4900  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-0 ERROR
   4901  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-1 ERROR
   4902  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-2 ERROR
   4903  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-3 ERROR
   4904  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-4 ERROR
   4905  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-5 ERROR
   4906  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-6 ERROR
   4907  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $2f-7 ERROR
   4908  1.1.6.2  bouyer 
   4909  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $30-0 fsincos norm
   4910  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $30-1 fsincos zero
   4911  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $30-2 fsincos inf
   4912  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $30-3 fsincos qnan
   4913  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $30-5 fsincos denorm
   4914  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $30-4 fsincos snan
   4915  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $30-6 fsincos unnorm
   4916  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $30-7 ERROR
   4917  1.1.6.2  bouyer 
   4918  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $31-0 fsincos norm
   4919  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $31-1 fsincos zero
   4920  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $31-2 fsincos inf
   4921  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $31-3 fsincos qnan
   4922  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $31-5 fsincos denorm
   4923  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $31-4 fsincos snan
   4924  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $31-6 fsincos unnorm
   4925  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $31-7 ERROR
   4926  1.1.6.2  bouyer 
   4927  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $32-0 fsincos norm
   4928  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $32-1 fsincos zero
   4929  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $32-2 fsincos inf
   4930  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $32-3 fsincos qnan
   4931  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $32-5 fsincos denorm
   4932  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $32-4 fsincos snan
   4933  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $32-6 fsincos unnorm
   4934  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $32-7 ERROR
   4935  1.1.6.2  bouyer 
   4936  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $33-0 fsincos norm
   4937  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $33-1 fsincos zero
   4938  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $33-2 fsincos inf
   4939  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $33-3 fsincos qnan
   4940  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $33-5 fsincos denorm
   4941  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $33-4 fsincos snan
   4942  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $33-6 fsincos unnorm
   4943  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $33-7 ERROR
   4944  1.1.6.2  bouyer 
   4945  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $34-0 fsincos norm
   4946  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $34-1 fsincos zero
   4947  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $34-2 fsincos inf
   4948  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $34-3 fsincos qnan
   4949  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $34-5 fsincos denorm
   4950  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $34-4 fsincos snan
   4951  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $34-6 fsincos unnorm
   4952  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $34-7 ERROR
   4953  1.1.6.2  bouyer 
   4954  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $35-0 fsincos norm
   4955  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $35-1 fsincos zero
   4956  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $35-2 fsincos inf
   4957  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $35-3 fsincos qnan
   4958  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $35-5 fsincos denorm
   4959  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $35-4 fsincos snan
   4960  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $35-6 fsincos unnorm
   4961  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $35-7 ERROR
   4962  1.1.6.2  bouyer 
   4963  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $36-0 fsincos norm
   4964  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $36-1 fsincos zero
   4965  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $36-2 fsincos inf
   4966  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $36-3 fsincos qnan
   4967  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $36-5 fsincos denorm
   4968  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $36-4 fsincos snan
   4969  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $36-6 fsincos unnorm
   4970  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $36-7 ERROR
   4971  1.1.6.2  bouyer 
   4972  1.1.6.2  bouyer 	short		ssincos	 - tbl_trans	# $37-0 fsincos norm
   4973  1.1.6.2  bouyer 	short		ssincosz - tbl_trans	# $37-1 fsincos zero
   4974  1.1.6.2  bouyer 	short		ssincosi - tbl_trans	# $37-2 fsincos inf
   4975  1.1.6.2  bouyer 	short		ssincosqnan - tbl_trans	# $37-3 fsincos qnan
   4976  1.1.6.2  bouyer 	short		ssincosd - tbl_trans	# $37-5 fsincos denorm
   4977  1.1.6.2  bouyer 	short		ssincossnan - tbl_trans	# $37-4 fsincos snan
   4978  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $37-6 fsincos unnorm
   4979  1.1.6.2  bouyer 	short		tbl_trans - tbl_trans	# $37-7 ERROR
   4980  1.1.6.2  bouyer 
   4981  1.1.6.2  bouyer ##########
   4982  1.1.6.2  bouyer 
   4983  1.1.6.2  bouyer # the instruction fetch access for the displacement word for the
   4984  1.1.6.2  bouyer # fdbcc emulation failed. here, we create an access error frame
   4985  1.1.6.2  bouyer # from the current frame and branch to _real_access().
   4986  1.1.6.2  bouyer funimp_iacc:
   4987  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   4988  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   4989  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   4990  1.1.6.2  bouyer 
   4991  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_PC(%a6) # store current PC
   4992  1.1.6.2  bouyer 
   4993  1.1.6.2  bouyer 	unlk		%a6
   4994  1.1.6.2  bouyer 
   4995  1.1.6.2  bouyer 	mov.l		(%sp),-(%sp)		# store SR,hi(PC)
   4996  1.1.6.2  bouyer 	mov.w		0x8(%sp),0x4(%sp)	# store lo(PC)
   4997  1.1.6.2  bouyer 	mov.w		&0x4008,0x6(%sp)	# store voff
   4998  1.1.6.2  bouyer 	mov.l		0x2(%sp),0x8(%sp)	# store EA
   4999  1.1.6.2  bouyer 	mov.l		&0x09428001,0xc(%sp)	# store FSLW
   5000  1.1.6.2  bouyer 
   5001  1.1.6.2  bouyer 	btst		&0x5,(%sp)		# user or supervisor mode?
   5002  1.1.6.2  bouyer 	beq.b		funimp_iacc_end		# user
   5003  1.1.6.2  bouyer 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
   5004  1.1.6.2  bouyer 
   5005  1.1.6.2  bouyer funimp_iacc_end:
   5006  1.1.6.2  bouyer 	bra.l		_real_access
   5007  1.1.6.2  bouyer 
   5008  1.1.6.2  bouyer #########################################################################
   5009  1.1.6.2  bouyer # ssin():     computes the sine of a normalized input			#
   5010  1.1.6.2  bouyer # ssind():    computes the sine of a denormalized input			#
   5011  1.1.6.2  bouyer # scos():     computes the cosine of a normalized input			#
   5012  1.1.6.2  bouyer # scosd():    computes the cosine of a denormalized input		#
   5013  1.1.6.2  bouyer # ssincos():  computes the sine and cosine of a normalized input	#
   5014  1.1.6.2  bouyer # ssincosd(): computes the sine and cosine of a denormalized input	#
   5015  1.1.6.2  bouyer #									#
   5016  1.1.6.2  bouyer # INPUT *************************************************************** #
   5017  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   5018  1.1.6.2  bouyer #	d0 = round precision,mode					#
   5019  1.1.6.2  bouyer #									#
   5020  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   5021  1.1.6.2  bouyer #	fp0 = sin(X) or cos(X) 						#
   5022  1.1.6.2  bouyer #									#
   5023  1.1.6.2  bouyer #    For ssincos(X):							#
   5024  1.1.6.2  bouyer #	fp0 = sin(X)							#
   5025  1.1.6.2  bouyer #	fp1 = cos(X)							#
   5026  1.1.6.2  bouyer #									#
   5027  1.1.6.2  bouyer # ACCURACY and MONOTONICITY ******************************************* #
   5028  1.1.6.2  bouyer #	The returned result is within 1 ulp in 64 significant bit, i.e.	#
   5029  1.1.6.2  bouyer #	within 0.5001 ulp to 53 bits if the result is subsequently 	#
   5030  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   5031  1.1.6.2  bouyer #	in double precision.						#
   5032  1.1.6.2  bouyer #									#
   5033  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   5034  1.1.6.2  bouyer #									#
   5035  1.1.6.2  bouyer #	SIN and COS:							#
   5036  1.1.6.2  bouyer #	1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1.	#
   5037  1.1.6.2  bouyer #									#
   5038  1.1.6.2  bouyer #	2. If |X| >= 15Pi or |X| < 2**(-40), go to 7.			#
   5039  1.1.6.2  bouyer #									#
   5040  1.1.6.2  bouyer #	3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   5041  1.1.6.2  bouyer #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
   5042  1.1.6.2  bouyer #		Overwrite k by k := k + AdjN.				#
   5043  1.1.6.2  bouyer #									#
   5044  1.1.6.2  bouyer #	4. If k is even, go to 6.					#
   5045  1.1.6.2  bouyer #									#
   5046  1.1.6.2  bouyer #	5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. 		#
   5047  1.1.6.2  bouyer #		Return sgn*cos(r) where cos(r) is approximated by an 	#
   5048  1.1.6.2  bouyer #		even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)),	#
   5049  1.1.6.2  bouyer #		s = r*r.						#
   5050  1.1.6.2  bouyer #		Exit.							#
   5051  1.1.6.2  bouyer #									#
   5052  1.1.6.2  bouyer #	6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r)	#
   5053  1.1.6.2  bouyer #		where sin(r) is approximated by an odd polynomial in r	#
   5054  1.1.6.2  bouyer #		r + r*s*(A1+s*(A2+ ... + s*A7)),	s = r*r.	#
   5055  1.1.6.2  bouyer #		Exit.							#
   5056  1.1.6.2  bouyer #									#
   5057  1.1.6.2  bouyer #	7. If |X| > 1, go to 9.						#
   5058  1.1.6.2  bouyer #									#
   5059  1.1.6.2  bouyer #	8. (|X|<2**(-40)) If SIN is invoked, return X; 			#
   5060  1.1.6.2  bouyer #		otherwise return 1.					#
   5061  1.1.6.2  bouyer #									#
   5062  1.1.6.2  bouyer #	9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, 		#
   5063  1.1.6.2  bouyer #		go back to 3.						#
   5064  1.1.6.2  bouyer #									#
   5065  1.1.6.2  bouyer #	SINCOS:								#
   5066  1.1.6.2  bouyer #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
   5067  1.1.6.2  bouyer #									#
   5068  1.1.6.2  bouyer #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   5069  1.1.6.2  bouyer #		k = N mod 4, so in particular, k = 0,1,2,or 3.		#
   5070  1.1.6.2  bouyer #									#
   5071  1.1.6.2  bouyer #	3. If k is even, go to 5.					#
   5072  1.1.6.2  bouyer #									#
   5073  1.1.6.2  bouyer #	4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie.	#
   5074  1.1.6.2  bouyer #		j1 exclusive or with the l.s.b. of k.			#
   5075  1.1.6.2  bouyer #		sgn1 := (-1)**j1, sgn2 := (-1)**j2.			#
   5076  1.1.6.2  bouyer #		SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where	#
   5077  1.1.6.2  bouyer #		sin(r) and cos(r) are computed as odd and even 		#
   5078  1.1.6.2  bouyer #		polynomials in r, respectively. Exit			#
   5079  1.1.6.2  bouyer #									#
   5080  1.1.6.2  bouyer #	5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1.			#
   5081  1.1.6.2  bouyer #		SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where	#
   5082  1.1.6.2  bouyer #		sin(r) and cos(r) are computed as odd and even 		#
   5083  1.1.6.2  bouyer #		polynomials in r, respectively. Exit			#
   5084  1.1.6.2  bouyer #									#
   5085  1.1.6.2  bouyer #	6. If |X| > 1, go to 8.						#
   5086  1.1.6.2  bouyer #									#
   5087  1.1.6.2  bouyer #	7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit.		#
   5088  1.1.6.2  bouyer #									#
   5089  1.1.6.2  bouyer #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, 		#
   5090  1.1.6.2  bouyer #		go back to 2.						#
   5091  1.1.6.2  bouyer #									#
   5092  1.1.6.2  bouyer #########################################################################
   5093  1.1.6.2  bouyer 
   5094  1.1.6.2  bouyer SINA7:	long		0xBD6AAA77,0xCCC994F5
   5095  1.1.6.2  bouyer SINA6:	long		0x3DE61209,0x7AAE8DA1
   5096  1.1.6.2  bouyer SINA5:	long		0xBE5AE645,0x2A118AE4
   5097  1.1.6.2  bouyer SINA4:	long		0x3EC71DE3,0xA5341531
   5098  1.1.6.2  bouyer SINA3:	long		0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
   5099  1.1.6.2  bouyer SINA2:	long		0x3FF80000,0x88888888,0x888859AF,0x00000000
   5100  1.1.6.2  bouyer SINA1:	long		0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
   5101  1.1.6.2  bouyer 
   5102  1.1.6.2  bouyer COSB8:	long		0x3D2AC4D0,0xD6011EE3
   5103  1.1.6.2  bouyer COSB7:	long		0xBDA9396F,0x9F45AC19
   5104  1.1.6.2  bouyer COSB6:	long		0x3E21EED9,0x0612C972
   5105  1.1.6.2  bouyer COSB5:	long		0xBE927E4F,0xB79D9FCF
   5106  1.1.6.2  bouyer COSB4:	long		0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
   5107  1.1.6.2  bouyer COSB3:	long		0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
   5108  1.1.6.2  bouyer COSB2:	long		0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
   5109  1.1.6.2  bouyer COSB1:	long		0xBF000000
   5110  1.1.6.2  bouyer 
   5111  1.1.6.2  bouyer 	set		INARG,FP_SCR0
   5112  1.1.6.2  bouyer 
   5113  1.1.6.2  bouyer 	set		X,FP_SCR0
   5114  1.1.6.2  bouyer #	set		XDCARE,X+2
   5115  1.1.6.2  bouyer 	set		XFRAC,X+4
   5116  1.1.6.2  bouyer 
   5117  1.1.6.2  bouyer 	set		RPRIME,FP_SCR0
   5118  1.1.6.2  bouyer 	set		SPRIME,FP_SCR1
   5119  1.1.6.2  bouyer 
   5120  1.1.6.2  bouyer 	set		POSNEG1,L_SCR1
   5121  1.1.6.2  bouyer 	set		TWOTO63,L_SCR1
   5122  1.1.6.2  bouyer 
   5123  1.1.6.2  bouyer 	set		ENDFLAG,L_SCR2
   5124  1.1.6.2  bouyer 	set		INT,L_SCR2
   5125  1.1.6.2  bouyer 
   5126  1.1.6.2  bouyer 	set		ADJN,L_SCR3
   5127  1.1.6.2  bouyer 
   5128  1.1.6.2  bouyer ############################################
   5129  1.1.6.2  bouyer 	global		ssin
   5130  1.1.6.2  bouyer ssin:
   5131  1.1.6.2  bouyer 	mov.l		&0,ADJN(%a6)		# yes; SET ADJN TO 0
   5132  1.1.6.2  bouyer 	bra.b		SINBGN
   5133  1.1.6.2  bouyer 
   5134  1.1.6.2  bouyer ############################################
   5135  1.1.6.2  bouyer 	global		scos
   5136  1.1.6.2  bouyer scos:
   5137  1.1.6.2  bouyer 	mov.l		&1,ADJN(%a6)		# yes; SET ADJN TO 1
   5138  1.1.6.2  bouyer 
   5139  1.1.6.2  bouyer ############################################
   5140  1.1.6.2  bouyer SINBGN:
   5141  1.1.6.2  bouyer #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
   5142  1.1.6.2  bouyer 
   5143  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5144  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)		# save input at X
   5145  1.1.6.2  bouyer 
   5146  1.1.6.2  bouyer # "COMPACTIFY" X
   5147  1.1.6.2  bouyer 	mov.l		(%a0),%d1		# put exp in hi word
   5148  1.1.6.2  bouyer 	mov.w		4(%a0),%d1		# fetch hi(man)
   5149  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1		# strip sign
   5150  1.1.6.2  bouyer 
   5151  1.1.6.2  bouyer 	cmpi.l		%d1,&0x3FD78000		# is |X| >= 2**(-40)?
   5152  1.1.6.2  bouyer 	bge.b		SOK1			# no
   5153  1.1.6.2  bouyer 	bra.w		SINSM			# yes; input is very small
   5154  1.1.6.2  bouyer 
   5155  1.1.6.2  bouyer SOK1:
   5156  1.1.6.2  bouyer 	cmp.l		%d1,&0x4004BC7E		# is |X| < 15 PI?
   5157  1.1.6.2  bouyer 	blt.b		SINMAIN			# no
   5158  1.1.6.2  bouyer 	bra.w		SREDUCEX		# yes; input is very large
   5159  1.1.6.2  bouyer 
   5160  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5161  1.1.6.2  bouyer #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5162  1.1.6.2  bouyer SINMAIN:
   5163  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   5164  1.1.6.2  bouyer 	fmul.d		TWOBYPI(%pc),%fp1 	# X*2/PI
   5165  1.1.6.2  bouyer 
   5166  1.1.6.2  bouyer 	lea		PITBL+0x200(%pc),%a1 	# TABLE OF N*PI/2, N = -32,...,32
   5167  1.1.6.2  bouyer 
   5168  1.1.6.2  bouyer 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
   5169  1.1.6.2  bouyer 
   5170  1.1.6.2  bouyer 	mov.l		INT(%a6),%d1		# make a copy of N
   5171  1.1.6.2  bouyer 	asl.l		&4,%d1			# N *= 16
   5172  1.1.6.2  bouyer 	add.l		%d1,%a1			# tbl_addr = a1 + (N*16)
   5173  1.1.6.2  bouyer 
   5174  1.1.6.2  bouyer # A1 IS THE ADDRESS OF N*PIBY2
   5175  1.1.6.2  bouyer # ...WHICH IS IN TWO PIECES Y1 & Y2
   5176  1.1.6.2  bouyer 	fsub.x		(%a1)+,%fp0 		# X-Y1
   5177  1.1.6.2  bouyer 	fsub.s		(%a1),%fp0 		# fp0 = R = (X-Y1)-Y2
   5178  1.1.6.2  bouyer 
   5179  1.1.6.2  bouyer SINCONT:
   5180  1.1.6.2  bouyer #--continuation from REDUCEX
   5181  1.1.6.2  bouyer 
   5182  1.1.6.2  bouyer #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
   5183  1.1.6.2  bouyer 	mov.l		INT(%a6),%d1
   5184  1.1.6.2  bouyer 	add.l		ADJN(%a6),%d1		# SEE IF D0 IS ODD OR EVEN
   5185  1.1.6.2  bouyer 	ror.l		&1,%d1			# D0 WAS ODD IFF D0 IS NEGATIVE
   5186  1.1.6.2  bouyer 	cmp.l		%d1,&0
   5187  1.1.6.2  bouyer 	blt.w		COSPOLY
   5188  1.1.6.2  bouyer 
   5189  1.1.6.2  bouyer #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
   5190  1.1.6.2  bouyer #--THEN WE RETURN	SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
   5191  1.1.6.2  bouyer #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
   5192  1.1.6.2  bouyer #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
   5193  1.1.6.2  bouyer #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
   5194  1.1.6.2  bouyer #--WHERE T=S*S.
   5195  1.1.6.2  bouyer #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
   5196  1.1.6.2  bouyer #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
   5197  1.1.6.2  bouyer SINPOLY:
   5198  1.1.6.2  bouyer 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   5199  1.1.6.2  bouyer 
   5200  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)		# X IS R
   5201  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# FP0 IS S
   5202  1.1.6.2  bouyer 
   5203  1.1.6.2  bouyer 	fmov.d		SINA7(%pc),%fp3
   5204  1.1.6.2  bouyer 	fmov.d		SINA6(%pc),%fp2
   5205  1.1.6.2  bouyer 
   5206  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   5207  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# FP1 IS T
   5208  1.1.6.2  bouyer 
   5209  1.1.6.2  bouyer 	ror.l		&1,%d1
   5210  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   5211  1.1.6.2  bouyer # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
   5212  1.1.6.2  bouyer 	eor.l		%d1,X(%a6)		# X IS NOW R'= SGN*R
   5213  1.1.6.2  bouyer 
   5214  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# TA7
   5215  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# TA6
   5216  1.1.6.2  bouyer 
   5217  1.1.6.2  bouyer 	fadd.d		SINA5(%pc),%fp3		# A5+TA7
   5218  1.1.6.2  bouyer 	fadd.d		SINA4(%pc),%fp2		# A4+TA6
   5219  1.1.6.2  bouyer 
   5220  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# T(A5+TA7)
   5221  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# T(A4+TA6)
   5222  1.1.6.2  bouyer 
   5223  1.1.6.2  bouyer 	fadd.d		SINA3(%pc),%fp3		# A3+T(A5+TA7)
   5224  1.1.6.2  bouyer 	fadd.x		SINA2(%pc),%fp2		# A2+T(A4+TA6)
   5225  1.1.6.2  bouyer 
   5226  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# T(A3+T(A5+TA7))
   5227  1.1.6.2  bouyer 
   5228  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(A2+T(A4+TA6))
   5229  1.1.6.2  bouyer 	fadd.x		SINA1(%pc),%fp1		# A1+T(A3+T(A5+TA7))
   5230  1.1.6.2  bouyer 	fmul.x		X(%a6),%fp0		# R'*S
   5231  1.1.6.2  bouyer 
   5232  1.1.6.2  bouyer 	fadd.x		%fp2,%fp1		# [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
   5233  1.1.6.2  bouyer 
   5234  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0		# SIN(R')-R'
   5235  1.1.6.2  bouyer 
   5236  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   5237  1.1.6.2  bouyer 
   5238  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5239  1.1.6.2  bouyer 	fadd.x		X(%a6),%fp0		# last inst - possible exception set
   5240  1.1.6.2  bouyer 	bra		t_inx2
   5241  1.1.6.2  bouyer 
   5242  1.1.6.2  bouyer #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
   5243  1.1.6.2  bouyer #--THEN WE RETURN	SGN*COS(R). SGN*COS(R) IS COMPUTED BY
   5244  1.1.6.2  bouyer #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
   5245  1.1.6.2  bouyer #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
   5246  1.1.6.2  bouyer #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
   5247  1.1.6.2  bouyer #--WHERE T=S*S.
   5248  1.1.6.2  bouyer #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
   5249  1.1.6.2  bouyer #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
   5250  1.1.6.2  bouyer #--AND IS THEREFORE STORED AS SINGLE PRECISION.
   5251  1.1.6.2  bouyer COSPOLY:
   5252  1.1.6.2  bouyer 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   5253  1.1.6.2  bouyer 
   5254  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# FP0 IS S
   5255  1.1.6.2  bouyer 
   5256  1.1.6.2  bouyer 	fmov.d		COSB8(%pc),%fp2
   5257  1.1.6.2  bouyer 	fmov.d		COSB7(%pc),%fp3
   5258  1.1.6.2  bouyer 
   5259  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   5260  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# FP1 IS T
   5261  1.1.6.2  bouyer 
   5262  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)		# X IS S
   5263  1.1.6.2  bouyer 	ror.l		&1,%d1
   5264  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   5265  1.1.6.2  bouyer # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
   5266  1.1.6.2  bouyer 
   5267  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# TB8
   5268  1.1.6.2  bouyer 
   5269  1.1.6.2  bouyer 	eor.l		%d1,X(%a6)		# X IS NOW S'= SGN*S
   5270  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   5271  1.1.6.2  bouyer 
   5272  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# TB7
   5273  1.1.6.2  bouyer 
   5274  1.1.6.2  bouyer 	or.l		&0x3F800000,%d1		# D0 IS SGN IN SINGLE
   5275  1.1.6.2  bouyer 	mov.l		%d1,POSNEG1(%a6)
   5276  1.1.6.2  bouyer 
   5277  1.1.6.2  bouyer 	fadd.d		COSB6(%pc),%fp2		# B6+TB8
   5278  1.1.6.2  bouyer 	fadd.d		COSB5(%pc),%fp3		# B5+TB7
   5279  1.1.6.2  bouyer 
   5280  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# T(B6+TB8)
   5281  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# T(B5+TB7)
   5282  1.1.6.2  bouyer 
   5283  1.1.6.2  bouyer 	fadd.d		COSB4(%pc),%fp2		# B4+T(B6+TB8)
   5284  1.1.6.2  bouyer 	fadd.x		COSB3(%pc),%fp3		# B3+T(B5+TB7)
   5285  1.1.6.2  bouyer 
   5286  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# T(B4+T(B6+TB8))
   5287  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# T(B3+T(B5+TB7))
   5288  1.1.6.2  bouyer 
   5289  1.1.6.2  bouyer 	fadd.x		COSB2(%pc),%fp2		# B2+T(B4+T(B6+TB8))
   5290  1.1.6.2  bouyer 	fadd.s		COSB1(%pc),%fp1		# B1+T(B3+T(B5+TB7))
   5291  1.1.6.2  bouyer 
   5292  1.1.6.2  bouyer 	fmul.x		%fp2,%fp0		# S(B2+T(B4+T(B6+TB8)))
   5293  1.1.6.2  bouyer 
   5294  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0
   5295  1.1.6.2  bouyer 
   5296  1.1.6.2  bouyer 	fmul.x		X(%a6),%fp0
   5297  1.1.6.2  bouyer 
   5298  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   5299  1.1.6.2  bouyer 
   5300  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5301  1.1.6.2  bouyer 	fadd.s		POSNEG1(%a6),%fp0	# last inst - possible exception set
   5302  1.1.6.2  bouyer 	bra		t_inx2
   5303  1.1.6.2  bouyer 
   5304  1.1.6.2  bouyer ##############################################
   5305  1.1.6.2  bouyer 
   5306  1.1.6.2  bouyer # SINe: Big OR Small?
   5307  1.1.6.2  bouyer #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
   5308  1.1.6.2  bouyer #--IF |X| < 2**(-40), RETURN X OR 1.
   5309  1.1.6.2  bouyer SINBORS:
   5310  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   5311  1.1.6.2  bouyer 	bgt.l		SREDUCEX
   5312  1.1.6.2  bouyer 
   5313  1.1.6.2  bouyer SINSM:
   5314  1.1.6.2  bouyer 	mov.l		ADJN(%a6),%d1
   5315  1.1.6.2  bouyer 	cmp.l		%d1,&0
   5316  1.1.6.2  bouyer 	bgt.b		COSTINY
   5317  1.1.6.2  bouyer 
   5318  1.1.6.2  bouyer # here, the operation may underflow iff the precision is sgl or dbl.
   5319  1.1.6.2  bouyer # extended denorms are handled through another entry point.
   5320  1.1.6.2  bouyer SINTINY:
   5321  1.1.6.2  bouyer #	mov.w		&0x0000,XDCARE(%a6)	# JUST IN CASE
   5322  1.1.6.2  bouyer 
   5323  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5324  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   5325  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   5326  1.1.6.2  bouyer 	bra		t_catch
   5327  1.1.6.2  bouyer 
   5328  1.1.6.2  bouyer COSTINY:
   5329  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
   5330  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5331  1.1.6.2  bouyer 	fadd.s 		&0x80800000,%fp0	# last inst - possible exception set
   5332  1.1.6.2  bouyer 	bra		t_pinx2
   5333  1.1.6.2  bouyer 
   5334  1.1.6.2  bouyer ################################################
   5335  1.1.6.2  bouyer 	global		ssind
   5336  1.1.6.2  bouyer #--SIN(X) = X FOR DENORMALIZED X
   5337  1.1.6.2  bouyer ssind:
   5338  1.1.6.2  bouyer 	bra		t_extdnrm
   5339  1.1.6.2  bouyer 
   5340  1.1.6.2  bouyer ############################################
   5341  1.1.6.2  bouyer 	global		scosd
   5342  1.1.6.2  bouyer #--COS(X) = 1 FOR DENORMALIZED X
   5343  1.1.6.2  bouyer scosd:
   5344  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp0	# fp0 = 1.0
   5345  1.1.6.2  bouyer 	bra		t_pinx2
   5346  1.1.6.2  bouyer 
   5347  1.1.6.2  bouyer ##################################################
   5348  1.1.6.2  bouyer 
   5349  1.1.6.2  bouyer 	global		ssincos
   5350  1.1.6.2  bouyer ssincos:
   5351  1.1.6.2  bouyer #--SET ADJN TO 4
   5352  1.1.6.2  bouyer 	mov.l		&4,ADJN(%a6)
   5353  1.1.6.2  bouyer 
   5354  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5355  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)
   5356  1.1.6.2  bouyer 
   5357  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   5358  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   5359  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1		# COMPACTIFY X
   5360  1.1.6.2  bouyer 
   5361  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
   5362  1.1.6.2  bouyer 	bge.b		SCOK1
   5363  1.1.6.2  bouyer 	bra.w		SCSM
   5364  1.1.6.2  bouyer 
   5365  1.1.6.2  bouyer SCOK1:
   5366  1.1.6.2  bouyer 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
   5367  1.1.6.2  bouyer 	blt.b		SCMAIN
   5368  1.1.6.2  bouyer 	bra.w		SREDUCEX
   5369  1.1.6.2  bouyer 
   5370  1.1.6.2  bouyer 
   5371  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5372  1.1.6.2  bouyer #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5373  1.1.6.2  bouyer SCMAIN:
   5374  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   5375  1.1.6.2  bouyer 
   5376  1.1.6.2  bouyer 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
   5377  1.1.6.2  bouyer 
   5378  1.1.6.2  bouyer 	lea		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
   5379  1.1.6.2  bouyer 
   5380  1.1.6.2  bouyer 	fmov.l		%fp1,INT(%a6)		# CONVERT TO INTEGER
   5381  1.1.6.2  bouyer 
   5382  1.1.6.2  bouyer 	mov.l		INT(%a6),%d1
   5383  1.1.6.2  bouyer 	asl.l		&4,%d1
   5384  1.1.6.2  bouyer 	add.l		%d1,%a1			# ADDRESS OF N*PIBY2, IN Y1, Y2
   5385  1.1.6.2  bouyer 
   5386  1.1.6.2  bouyer 	fsub.x		(%a1)+,%fp0		# X-Y1
   5387  1.1.6.2  bouyer 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
   5388  1.1.6.2  bouyer 
   5389  1.1.6.2  bouyer SCCONT:
   5390  1.1.6.2  bouyer #--continuation point from REDUCEX
   5391  1.1.6.2  bouyer 
   5392  1.1.6.2  bouyer 	mov.l		INT(%a6),%d1
   5393  1.1.6.2  bouyer 	ror.l		&1,%d1
   5394  1.1.6.2  bouyer 	cmp.l		%d1,&0			# D0 < 0 IFF N IS ODD
   5395  1.1.6.2  bouyer 	bge.w		NEVEN
   5396  1.1.6.2  bouyer 
   5397  1.1.6.2  bouyer SNODD:
   5398  1.1.6.2  bouyer #--REGISTERS SAVED SO FAR: D0, A0, FP2.
   5399  1.1.6.2  bouyer 	fmovm.x		&0x04,-(%sp)		# save fp2
   5400  1.1.6.2  bouyer 
   5401  1.1.6.2  bouyer 	fmov.x		%fp0,RPRIME(%a6)
   5402  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
   5403  1.1.6.2  bouyer 	fmov.d		SINA7(%pc),%fp1		# A7
   5404  1.1.6.2  bouyer 	fmov.d		COSB8(%pc),%fp2		# B8
   5405  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# SA7
   5406  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# SB8
   5407  1.1.6.2  bouyer 
   5408  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)
   5409  1.1.6.2  bouyer 	mov.l		%d1,%d2
   5410  1.1.6.2  bouyer 	ror.l		&1,%d2
   5411  1.1.6.2  bouyer 	and.l		&0x80000000,%d2
   5412  1.1.6.2  bouyer 	eor.l		%d1,%d2
   5413  1.1.6.2  bouyer 	and.l		&0x80000000,%d2
   5414  1.1.6.2  bouyer 
   5415  1.1.6.2  bouyer 	fadd.d		SINA6(%pc),%fp1		# A6+SA7
   5416  1.1.6.2  bouyer 	fadd.d		COSB7(%pc),%fp2		# B7+SB8
   5417  1.1.6.2  bouyer 
   5418  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(A6+SA7)
   5419  1.1.6.2  bouyer 	eor.l		%d2,RPRIME(%a6)
   5420  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2
   5421  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(B7+SB8)
   5422  1.1.6.2  bouyer 	ror.l		&1,%d1
   5423  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   5424  1.1.6.2  bouyer 	mov.l		&0x3F800000,POSNEG1(%a6)
   5425  1.1.6.2  bouyer 	eor.l		%d1,POSNEG1(%a6)
   5426  1.1.6.2  bouyer 
   5427  1.1.6.2  bouyer 	fadd.d		SINA5(%pc),%fp1		# A5+S(A6+SA7)
   5428  1.1.6.2  bouyer 	fadd.d		COSB6(%pc),%fp2		# B6+S(B7+SB8)
   5429  1.1.6.2  bouyer 
   5430  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(A5+S(A6+SA7))
   5431  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(B6+S(B7+SB8))
   5432  1.1.6.2  bouyer 	fmov.x		%fp0,SPRIME(%a6)
   5433  1.1.6.2  bouyer 
   5434  1.1.6.2  bouyer 	fadd.d		SINA4(%pc),%fp1		# A4+S(A5+S(A6+SA7))
   5435  1.1.6.2  bouyer 	eor.l		%d1,SPRIME(%a6)
   5436  1.1.6.2  bouyer 	fadd.d		COSB5(%pc),%fp2		# B5+S(B6+S(B7+SB8))
   5437  1.1.6.2  bouyer 
   5438  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(A4+...)
   5439  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(B5+...)
   5440  1.1.6.2  bouyer 
   5441  1.1.6.2  bouyer 	fadd.d		SINA3(%pc),%fp1		# A3+S(A4+...)
   5442  1.1.6.2  bouyer 	fadd.d		COSB4(%pc),%fp2		# B4+S(B5+...)
   5443  1.1.6.2  bouyer 
   5444  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(A3+...)
   5445  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(B4+...)
   5446  1.1.6.2  bouyer 
   5447  1.1.6.2  bouyer 	fadd.x		SINA2(%pc),%fp1		# A2+S(A3+...)
   5448  1.1.6.2  bouyer 	fadd.x		COSB3(%pc),%fp2		# B3+S(B4+...)
   5449  1.1.6.2  bouyer 
   5450  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(A2+...)
   5451  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(B3+...)
   5452  1.1.6.2  bouyer 
   5453  1.1.6.2  bouyer 	fadd.x		SINA1(%pc),%fp1		# A1+S(A2+...)
   5454  1.1.6.2  bouyer 	fadd.x		COSB2(%pc),%fp2		# B2+S(B3+...)
   5455  1.1.6.2  bouyer 
   5456  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(A1+...)
   5457  1.1.6.2  bouyer 	fmul.x		%fp2,%fp0		# S(B2+...)
   5458  1.1.6.2  bouyer 
   5459  1.1.6.2  bouyer 	fmul.x		RPRIME(%a6),%fp1	# R'S(A1+...)
   5460  1.1.6.2  bouyer 	fadd.s		COSB1(%pc),%fp0		# B1+S(B2...)
   5461  1.1.6.2  bouyer 	fmul.x		SPRIME(%a6),%fp0	# S'(B1+S(B2+...))
   5462  1.1.6.2  bouyer 
   5463  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x20		# restore fp2
   5464  1.1.6.2  bouyer 
   5465  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   5466  1.1.6.2  bouyer 	fadd.x		RPRIME(%a6),%fp1	# COS(X)
   5467  1.1.6.2  bouyer 	bsr		sto_cos			# store cosine result
   5468  1.1.6.2  bouyer 	fadd.s		POSNEG1(%a6),%fp0	# SIN(X)
   5469  1.1.6.2  bouyer 	bra		t_inx2
   5470  1.1.6.2  bouyer 
   5471  1.1.6.2  bouyer NEVEN:
   5472  1.1.6.2  bouyer #--REGISTERS SAVED SO FAR: FP2.
   5473  1.1.6.2  bouyer 	fmovm.x		&0x04,-(%sp)		# save fp2
   5474  1.1.6.2  bouyer 
   5475  1.1.6.2  bouyer 	fmov.x		%fp0,RPRIME(%a6)
   5476  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# FP0 IS S = R*R
   5477  1.1.6.2  bouyer 
   5478  1.1.6.2  bouyer 	fmov.d		COSB8(%pc),%fp1		# B8
   5479  1.1.6.2  bouyer 	fmov.d		SINA7(%pc),%fp2		# A7
   5480  1.1.6.2  bouyer 
   5481  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# SB8
   5482  1.1.6.2  bouyer 	fmov.x		%fp0,SPRIME(%a6)
   5483  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# SA7
   5484  1.1.6.2  bouyer 
   5485  1.1.6.2  bouyer 	ror.l		&1,%d1
   5486  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   5487  1.1.6.2  bouyer 
   5488  1.1.6.2  bouyer 	fadd.d		COSB7(%pc),%fp1		# B7+SB8
   5489  1.1.6.2  bouyer 	fadd.d		SINA6(%pc),%fp2		# A6+SA7
   5490  1.1.6.2  bouyer 
   5491  1.1.6.2  bouyer 	eor.l		%d1,RPRIME(%a6)
   5492  1.1.6.2  bouyer 	eor.l		%d1,SPRIME(%a6)
   5493  1.1.6.2  bouyer 
   5494  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(B7+SB8)
   5495  1.1.6.2  bouyer 
   5496  1.1.6.2  bouyer 	or.l		&0x3F800000,%d1
   5497  1.1.6.2  bouyer 	mov.l		%d1,POSNEG1(%a6)
   5498  1.1.6.2  bouyer 
   5499  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(A6+SA7)
   5500  1.1.6.2  bouyer 
   5501  1.1.6.2  bouyer 	fadd.d		COSB6(%pc),%fp1		# B6+S(B7+SB8)
   5502  1.1.6.2  bouyer 	fadd.d		SINA5(%pc),%fp2		# A5+S(A6+SA7)
   5503  1.1.6.2  bouyer 
   5504  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(B6+S(B7+SB8))
   5505  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(A5+S(A6+SA7))
   5506  1.1.6.2  bouyer 
   5507  1.1.6.2  bouyer 	fadd.d		COSB5(%pc),%fp1		# B5+S(B6+S(B7+SB8))
   5508  1.1.6.2  bouyer 	fadd.d		SINA4(%pc),%fp2		# A4+S(A5+S(A6+SA7))
   5509  1.1.6.2  bouyer 
   5510  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(B5+...)
   5511  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(A4+...)
   5512  1.1.6.2  bouyer 
   5513  1.1.6.2  bouyer 	fadd.d		COSB4(%pc),%fp1		# B4+S(B5+...)
   5514  1.1.6.2  bouyer 	fadd.d		SINA3(%pc),%fp2		# A3+S(A4+...)
   5515  1.1.6.2  bouyer 
   5516  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(B4+...)
   5517  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(A3+...)
   5518  1.1.6.2  bouyer 
   5519  1.1.6.2  bouyer 	fadd.x		COSB3(%pc),%fp1		# B3+S(B4+...)
   5520  1.1.6.2  bouyer 	fadd.x		SINA2(%pc),%fp2		# A2+S(A3+...)
   5521  1.1.6.2  bouyer 
   5522  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(B3+...)
   5523  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(A2+...)
   5524  1.1.6.2  bouyer 
   5525  1.1.6.2  bouyer 	fadd.x		COSB2(%pc),%fp1		# B2+S(B3+...)
   5526  1.1.6.2  bouyer 	fadd.x		SINA1(%pc),%fp2		# A1+S(A2+...)
   5527  1.1.6.2  bouyer 
   5528  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# S(B2+...)
   5529  1.1.6.2  bouyer 	fmul.x		%fp2,%fp0		# s(a1+...)
   5530  1.1.6.2  bouyer 
   5531  1.1.6.2  bouyer 
   5532  1.1.6.2  bouyer 	fadd.s		COSB1(%pc),%fp1		# B1+S(B2...)
   5533  1.1.6.2  bouyer 	fmul.x		RPRIME(%a6),%fp0	# R'S(A1+...)
   5534  1.1.6.2  bouyer 	fmul.x		SPRIME(%a6),%fp1	# S'(B1+S(B2+...))
   5535  1.1.6.2  bouyer 
   5536  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x20		# restore fp2
   5537  1.1.6.2  bouyer 
   5538  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   5539  1.1.6.2  bouyer 	fadd.s		POSNEG1(%a6),%fp1	# COS(X)
   5540  1.1.6.2  bouyer 	bsr		sto_cos			# store cosine result
   5541  1.1.6.2  bouyer 	fadd.x		RPRIME(%a6),%fp0	# SIN(X)
   5542  1.1.6.2  bouyer 	bra		t_inx2
   5543  1.1.6.2  bouyer 
   5544  1.1.6.2  bouyer ################################################
   5545  1.1.6.2  bouyer 
   5546  1.1.6.2  bouyer SCBORS:
   5547  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   5548  1.1.6.2  bouyer 	bgt.w		SREDUCEX
   5549  1.1.6.2  bouyer 
   5550  1.1.6.2  bouyer ################################################
   5551  1.1.6.2  bouyer 
   5552  1.1.6.2  bouyer SCSM:
   5553  1.1.6.2  bouyer #	mov.w		&0x0000,XDCARE(%a6)
   5554  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp1
   5555  1.1.6.2  bouyer 
   5556  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   5557  1.1.6.2  bouyer 	fsub.s		&0x00800000,%fp1
   5558  1.1.6.2  bouyer 	bsr		sto_cos			# store cosine result
   5559  1.1.6.2  bouyer 	fmov.l		%fpcr,%d0		# d0 must have fpcr,too
   5560  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   5561  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0
   5562  1.1.6.2  bouyer 	bra		t_catch
   5563  1.1.6.2  bouyer 
   5564  1.1.6.2  bouyer ##############################################
   5565  1.1.6.2  bouyer 
   5566  1.1.6.2  bouyer 	global		ssincosd
   5567  1.1.6.2  bouyer #--SIN AND COS OF X FOR DENORMALIZED X
   5568  1.1.6.2  bouyer ssincosd:
   5569  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save d0
   5570  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp1
   5571  1.1.6.2  bouyer 	bsr		sto_cos			# store cosine result
   5572  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   5573  1.1.6.2  bouyer 	bra		t_extdnrm
   5574  1.1.6.2  bouyer 
   5575  1.1.6.2  bouyer ############################################
   5576  1.1.6.2  bouyer 
   5577  1.1.6.2  bouyer #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
   5578  1.1.6.2  bouyer #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
   5579  1.1.6.2  bouyer #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
   5580  1.1.6.2  bouyer SREDUCEX:
   5581  1.1.6.2  bouyer 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
   5582  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   5583  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp1	# fp1 = 0
   5584  1.1.6.2  bouyer 
   5585  1.1.6.2  bouyer #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
   5586  1.1.6.2  bouyer #--there is a danger of unwanted overflow in first LOOP iteration.  In this
   5587  1.1.6.2  bouyer #--case, reduce argument by one remainder step to make subsequent reduction
   5588  1.1.6.2  bouyer #--safe.
   5589  1.1.6.2  bouyer 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
   5590  1.1.6.2  bouyer 	bne.b		SLOOP			# no
   5591  1.1.6.2  bouyer 
   5592  1.1.6.2  bouyer # yes; create 2**16383*PI/2
   5593  1.1.6.2  bouyer 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
   5594  1.1.6.2  bouyer 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
   5595  1.1.6.2  bouyer 	clr.l		FP_SCR0_LO(%a6)
   5596  1.1.6.2  bouyer 
   5597  1.1.6.2  bouyer # create low half of 2**16383*PI/2 at FP_SCR1
   5598  1.1.6.2  bouyer 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
   5599  1.1.6.2  bouyer 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
   5600  1.1.6.2  bouyer 	clr.l		FP_SCR1_LO(%a6)
   5601  1.1.6.2  bouyer 
   5602  1.1.6.2  bouyer 	ftest.x		%fp0			# test sign of argument
   5603  1.1.6.2  bouyer 	fblt.w		sred_neg
   5604  1.1.6.2  bouyer 
   5605  1.1.6.2  bouyer 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
   5606  1.1.6.2  bouyer 	or.b		&0x80,FP_SCR1_EX(%a6)
   5607  1.1.6.2  bouyer sred_neg:
   5608  1.1.6.2  bouyer 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
   5609  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1		# save high result in fp1
   5610  1.1.6.2  bouyer 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
   5611  1.1.6.2  bouyer 	fsub.x		%fp0,%fp1		# determine low component of result
   5612  1.1.6.2  bouyer 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
   5613  1.1.6.2  bouyer 
   5614  1.1.6.2  bouyer #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
   5615  1.1.6.2  bouyer #--integer quotient will be stored in N
   5616  1.1.6.2  bouyer #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
   5617  1.1.6.2  bouyer SLOOP:
   5618  1.1.6.2  bouyer 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
   5619  1.1.6.2  bouyer 	mov.w		INARG(%a6),%d1
   5620  1.1.6.2  bouyer 	mov.l		%d1,%a1			# save a copy of D0
   5621  1.1.6.2  bouyer 	and.l		&0x00007FFF,%d1
   5622  1.1.6.2  bouyer 	sub.l		&0x00003FFF,%d1		# d0 = K
   5623  1.1.6.2  bouyer 	cmp.l		%d1,&28
   5624  1.1.6.2  bouyer 	ble.b		SLASTLOOP
   5625  1.1.6.2  bouyer SCONTLOOP:
   5626  1.1.6.2  bouyer 	sub.l		&27,%d1			# d0 = L := K-27
   5627  1.1.6.2  bouyer 	mov.b		&0,ENDFLAG(%a6)
   5628  1.1.6.2  bouyer 	bra.b		SWORK
   5629  1.1.6.2  bouyer SLASTLOOP:
   5630  1.1.6.2  bouyer 	clr.l		%d1			# d0 = L := 0
   5631  1.1.6.2  bouyer 	mov.b		&1,ENDFLAG(%a6)
   5632  1.1.6.2  bouyer 
   5633  1.1.6.2  bouyer SWORK:
   5634  1.1.6.2  bouyer #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
   5635  1.1.6.2  bouyer #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
   5636  1.1.6.2  bouyer 
   5637  1.1.6.2  bouyer #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
   5638  1.1.6.2  bouyer #--2**L * (PIby2_1), 2**L * (PIby2_2)
   5639  1.1.6.2  bouyer 
   5640  1.1.6.2  bouyer 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
   5641  1.1.6.2  bouyer 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
   5642  1.1.6.2  bouyer 
   5643  1.1.6.2  bouyer 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
   5644  1.1.6.2  bouyer 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
   5645  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
   5646  1.1.6.2  bouyer 
   5647  1.1.6.2  bouyer 	fmov.x		%fp0,%fp2
   5648  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
   5649  1.1.6.2  bouyer 
   5650  1.1.6.2  bouyer #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
   5651  1.1.6.2  bouyer #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
   5652  1.1.6.2  bouyer #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
   5653  1.1.6.2  bouyer #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
   5654  1.1.6.2  bouyer #--US THE DESIRED VALUE IN FLOATING POINT.
   5655  1.1.6.2  bouyer 	mov.l		%a1,%d2
   5656  1.1.6.2  bouyer 	swap		%d2
   5657  1.1.6.2  bouyer 	and.l		&0x80000000,%d2
   5658  1.1.6.2  bouyer 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
   5659  1.1.6.2  bouyer 	mov.l		%d2,TWOTO63(%a6)
   5660  1.1.6.2  bouyer 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
   5661  1.1.6.2  bouyer 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
   5662  1.1.6.2  bouyer #	fint.x		%fp2
   5663  1.1.6.2  bouyer 
   5664  1.1.6.2  bouyer #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
   5665  1.1.6.2  bouyer 	mov.l		%d1,%d2			# d2 = L
   5666  1.1.6.2  bouyer 
   5667  1.1.6.2  bouyer 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
   5668  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)
   5669  1.1.6.2  bouyer 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
   5670  1.1.6.2  bouyer 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
   5671  1.1.6.2  bouyer 
   5672  1.1.6.2  bouyer 	add.l		&0x00003FDD,%d1
   5673  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR1_EX(%a6)
   5674  1.1.6.2  bouyer 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
   5675  1.1.6.2  bouyer 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
   5676  1.1.6.2  bouyer 
   5677  1.1.6.2  bouyer 	mov.b		ENDFLAG(%a6),%d1
   5678  1.1.6.2  bouyer 
   5679  1.1.6.2  bouyer #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
   5680  1.1.6.2  bouyer #--P2 = 2**(L) * Piby2_2
   5681  1.1.6.2  bouyer 	fmov.x		%fp2,%fp4		# fp4 = N
   5682  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
   5683  1.1.6.2  bouyer 	fmov.x		%fp2,%fp5		# fp5 = N
   5684  1.1.6.2  bouyer 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
   5685  1.1.6.2  bouyer 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
   5686  1.1.6.2  bouyer 
   5687  1.1.6.2  bouyer #--we want P+p = W+w  but  |p| <= half ulp of P
   5688  1.1.6.2  bouyer #--Then, we need to compute  A := R-P   and  a := r-p
   5689  1.1.6.2  bouyer 	fadd.x		%fp5,%fp3		# fp3 = P
   5690  1.1.6.2  bouyer 	fsub.x		%fp3,%fp4		# fp4 = W-P
   5691  1.1.6.2  bouyer 
   5692  1.1.6.2  bouyer 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
   5693  1.1.6.2  bouyer 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
   5694  1.1.6.2  bouyer 
   5695  1.1.6.2  bouyer 	fmov.x		%fp0,%fp3		# fp3 = A
   5696  1.1.6.2  bouyer 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
   5697  1.1.6.2  bouyer 
   5698  1.1.6.2  bouyer #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
   5699  1.1.6.2  bouyer #--|r| <= half ulp of R.
   5700  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
   5701  1.1.6.2  bouyer #--No need to calculate r if this is the last loop
   5702  1.1.6.2  bouyer 	cmp.b		%d1,&0
   5703  1.1.6.2  bouyer 	bgt.w		SRESTORE
   5704  1.1.6.2  bouyer 
   5705  1.1.6.2  bouyer #--Need to calculate r
   5706  1.1.6.2  bouyer 	fsub.x		%fp0,%fp3		# fp3 = A-R
   5707  1.1.6.2  bouyer 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
   5708  1.1.6.2  bouyer 	bra.w		SLOOP
   5709  1.1.6.2  bouyer 
   5710  1.1.6.2  bouyer SRESTORE:
   5711  1.1.6.2  bouyer 	fmov.l		%fp2,INT(%a6)
   5712  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   5713  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
   5714  1.1.6.2  bouyer 
   5715  1.1.6.2  bouyer 	mov.l		ADJN(%a6),%d1
   5716  1.1.6.2  bouyer 	cmp.l		%d1,&4
   5717  1.1.6.2  bouyer 
   5718  1.1.6.2  bouyer 	blt.w		SINCONT
   5719  1.1.6.2  bouyer 	bra.w		SCCONT
   5720  1.1.6.2  bouyer 
   5721  1.1.6.2  bouyer #########################################################################
   5722  1.1.6.2  bouyer # stan():  computes the tangent of a normalized input			#
   5723  1.1.6.2  bouyer # stand(): computes the tangent of a denormalized input			#
   5724  1.1.6.2  bouyer #									#
   5725  1.1.6.2  bouyer # INPUT *************************************************************** #
   5726  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   5727  1.1.6.2  bouyer #	d0 = round precision,mode					#
   5728  1.1.6.2  bouyer #									#
   5729  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   5730  1.1.6.2  bouyer #	fp0 = tan(X)							#
   5731  1.1.6.2  bouyer #									#
   5732  1.1.6.2  bouyer # ACCURACY and MONOTONICITY ******************************************* #
   5733  1.1.6.2  bouyer #	The returned result is within 3 ulp in 64 significant bit, i.e. #
   5734  1.1.6.2  bouyer #	within 0.5001 ulp to 53 bits if the result is subsequently	#
   5735  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   5736  1.1.6.2  bouyer #	in double precision.						#
   5737  1.1.6.2  bouyer #									#
   5738  1.1.6.2  bouyer # ALGORITHM *********************************************************** #
   5739  1.1.6.2  bouyer #									#
   5740  1.1.6.2  bouyer #	1. If |X| >= 15Pi or |X| < 2**(-40), go to 6.			#
   5741  1.1.6.2  bouyer #									#
   5742  1.1.6.2  bouyer #	2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let	#
   5743  1.1.6.2  bouyer #		k = N mod 2, so in particular, k = 0 or 1.		#
   5744  1.1.6.2  bouyer #									#
   5745  1.1.6.2  bouyer #	3. If k is odd, go to 5.					#
   5746  1.1.6.2  bouyer #									#
   5747  1.1.6.2  bouyer #	4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a	#
   5748  1.1.6.2  bouyer #		rational function U/V where				#
   5749  1.1.6.2  bouyer #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
   5750  1.1.6.2  bouyer #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))),  s = r*r.	#
   5751  1.1.6.2  bouyer #		Exit.							#
   5752  1.1.6.2  bouyer #									#
   5753  1.1.6.2  bouyer #	4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
   5754  1.1.6.2  bouyer #		a rational function U/V where				#
   5755  1.1.6.2  bouyer #		U = r + r*s*(P1 + s*(P2 + s*P3)), and			#
   5756  1.1.6.2  bouyer #		V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r,	#
   5757  1.1.6.2  bouyer #		-Cot(r) = -V/U. Exit.					#
   5758  1.1.6.2  bouyer #									#
   5759  1.1.6.2  bouyer #	6. If |X| > 1, go to 8.						#
   5760  1.1.6.2  bouyer #									#
   5761  1.1.6.2  bouyer #	7. (|X|<2**(-40)) Tan(X) = X. Exit.				#
   5762  1.1.6.2  bouyer #									#
   5763  1.1.6.2  bouyer #	8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back 	#
   5764  1.1.6.2  bouyer #		to 2.							#
   5765  1.1.6.2  bouyer #									#
   5766  1.1.6.2  bouyer #########################################################################
   5767  1.1.6.2  bouyer 
   5768  1.1.6.2  bouyer TANQ4:
   5769  1.1.6.2  bouyer 	long		0x3EA0B759,0xF50F8688
   5770  1.1.6.2  bouyer TANP3:
   5771  1.1.6.2  bouyer 	long		0xBEF2BAA5,0xA8924F04
   5772  1.1.6.2  bouyer 
   5773  1.1.6.2  bouyer TANQ3:
   5774  1.1.6.2  bouyer 	long		0xBF346F59,0xB39BA65F,0x00000000,0x00000000
   5775  1.1.6.2  bouyer 
   5776  1.1.6.2  bouyer TANP2:
   5777  1.1.6.2  bouyer 	long		0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
   5778  1.1.6.2  bouyer 
   5779  1.1.6.2  bouyer TANQ2:
   5780  1.1.6.2  bouyer 	long		0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
   5781  1.1.6.2  bouyer 
   5782  1.1.6.2  bouyer TANP1:
   5783  1.1.6.2  bouyer 	long		0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
   5784  1.1.6.2  bouyer 
   5785  1.1.6.2  bouyer TANQ1:
   5786  1.1.6.2  bouyer 	long		0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
   5787  1.1.6.2  bouyer 
   5788  1.1.6.2  bouyer INVTWOPI:
   5789  1.1.6.2  bouyer 	long		0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
   5790  1.1.6.2  bouyer 
   5791  1.1.6.2  bouyer TWOPI1:
   5792  1.1.6.2  bouyer 	long		0x40010000,0xC90FDAA2,0x00000000,0x00000000
   5793  1.1.6.2  bouyer TWOPI2:
   5794  1.1.6.2  bouyer 	long		0x3FDF0000,0x85A308D4,0x00000000,0x00000000
   5795  1.1.6.2  bouyer 
   5796  1.1.6.2  bouyer #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
   5797  1.1.6.2  bouyer #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
   5798  1.1.6.2  bouyer #--MOST 69 BITS LONG.
   5799  1.1.6.2  bouyer #	global		PITBL
   5800  1.1.6.2  bouyer PITBL:
   5801  1.1.6.2  bouyer 	long		0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
   5802  1.1.6.2  bouyer 	long		0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
   5803  1.1.6.2  bouyer 	long		0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
   5804  1.1.6.2  bouyer 	long		0xC0040000,0xB6365E22,0xEE46F000,0x21480000
   5805  1.1.6.2  bouyer 	long		0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
   5806  1.1.6.2  bouyer 	long		0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
   5807  1.1.6.2  bouyer 	long		0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
   5808  1.1.6.2  bouyer 	long		0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
   5809  1.1.6.2  bouyer 	long		0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
   5810  1.1.6.2  bouyer 	long		0xC0040000,0x90836524,0x88034B96,0x20B00000
   5811  1.1.6.2  bouyer 	long		0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
   5812  1.1.6.2  bouyer 	long		0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
   5813  1.1.6.2  bouyer 	long		0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
   5814  1.1.6.2  bouyer 	long		0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
   5815  1.1.6.2  bouyer 	long		0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
   5816  1.1.6.2  bouyer 	long		0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
   5817  1.1.6.2  bouyer 	long		0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
   5818  1.1.6.2  bouyer 	long		0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
   5819  1.1.6.2  bouyer 	long		0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
   5820  1.1.6.2  bouyer 	long		0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
   5821  1.1.6.2  bouyer 	long		0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
   5822  1.1.6.2  bouyer 	long		0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
   5823  1.1.6.2  bouyer 	long		0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
   5824  1.1.6.2  bouyer 	long		0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
   5825  1.1.6.2  bouyer 	long		0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
   5826  1.1.6.2  bouyer 	long		0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
   5827  1.1.6.2  bouyer 	long		0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
   5828  1.1.6.2  bouyer 	long		0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
   5829  1.1.6.2  bouyer 	long		0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
   5830  1.1.6.2  bouyer 	long		0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
   5831  1.1.6.2  bouyer 	long		0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
   5832  1.1.6.2  bouyer 	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
   5833  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000,0x00000000
   5834  1.1.6.2  bouyer 	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
   5835  1.1.6.2  bouyer 	long		0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
   5836  1.1.6.2  bouyer 	long		0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
   5837  1.1.6.2  bouyer 	long		0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
   5838  1.1.6.2  bouyer 	long		0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
   5839  1.1.6.2  bouyer 	long		0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
   5840  1.1.6.2  bouyer 	long		0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
   5841  1.1.6.2  bouyer 	long		0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
   5842  1.1.6.2  bouyer 	long		0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
   5843  1.1.6.2  bouyer 	long		0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
   5844  1.1.6.2  bouyer 	long		0x40030000,0x8A3AE64F,0x76F80584,0x21080000
   5845  1.1.6.2  bouyer 	long		0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
   5846  1.1.6.2  bouyer 	long		0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
   5847  1.1.6.2  bouyer 	long		0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
   5848  1.1.6.2  bouyer 	long		0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
   5849  1.1.6.2  bouyer 	long		0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
   5850  1.1.6.2  bouyer 	long		0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
   5851  1.1.6.2  bouyer 	long		0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
   5852  1.1.6.2  bouyer 	long		0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
   5853  1.1.6.2  bouyer 	long		0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
   5854  1.1.6.2  bouyer 	long		0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
   5855  1.1.6.2  bouyer 	long		0x40040000,0x8A3AE64F,0x76F80584,0x21880000
   5856  1.1.6.2  bouyer 	long		0x40040000,0x90836524,0x88034B96,0xA0B00000
   5857  1.1.6.2  bouyer 	long		0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
   5858  1.1.6.2  bouyer 	long		0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
   5859  1.1.6.2  bouyer 	long		0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
   5860  1.1.6.2  bouyer 	long		0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
   5861  1.1.6.2  bouyer 	long		0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
   5862  1.1.6.2  bouyer 	long		0x40040000,0xB6365E22,0xEE46F000,0xA1480000
   5863  1.1.6.2  bouyer 	long		0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
   5864  1.1.6.2  bouyer 	long		0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
   5865  1.1.6.2  bouyer 	long		0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
   5866  1.1.6.2  bouyer 
   5867  1.1.6.2  bouyer 	set		INARG,FP_SCR0
   5868  1.1.6.2  bouyer 
   5869  1.1.6.2  bouyer 	set		TWOTO63,L_SCR1
   5870  1.1.6.2  bouyer 	set		INT,L_SCR1
   5871  1.1.6.2  bouyer 	set		ENDFLAG,L_SCR2
   5872  1.1.6.2  bouyer 
   5873  1.1.6.2  bouyer 	global		stan
   5874  1.1.6.2  bouyer stan:
   5875  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   5876  1.1.6.2  bouyer 
   5877  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   5878  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   5879  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   5880  1.1.6.2  bouyer 
   5881  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FD78000		# |X| >= 2**(-40)?
   5882  1.1.6.2  bouyer 	bge.b		TANOK1
   5883  1.1.6.2  bouyer 	bra.w		TANSM
   5884  1.1.6.2  bouyer TANOK1:
   5885  1.1.6.2  bouyer 	cmp.l		%d1,&0x4004BC7E		# |X| < 15 PI?
   5886  1.1.6.2  bouyer 	blt.b		TANMAIN
   5887  1.1.6.2  bouyer 	bra.w		REDUCEX
   5888  1.1.6.2  bouyer 
   5889  1.1.6.2  bouyer TANMAIN:
   5890  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| <= 15 PI.
   5891  1.1.6.2  bouyer #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
   5892  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   5893  1.1.6.2  bouyer 	fmul.d		TWOBYPI(%pc),%fp1	# X*2/PI
   5894  1.1.6.2  bouyer 
   5895  1.1.6.2  bouyer 	lea.l		PITBL+0x200(%pc),%a1	# TABLE OF N*PI/2, N = -32,...,32
   5896  1.1.6.2  bouyer 
   5897  1.1.6.2  bouyer 	fmov.l		%fp1,%d1		# CONVERT TO INTEGER
   5898  1.1.6.2  bouyer 
   5899  1.1.6.2  bouyer 	asl.l		&4,%d1
   5900  1.1.6.2  bouyer 	add.l		%d1,%a1			# ADDRESS N*PIBY2 IN Y1, Y2
   5901  1.1.6.2  bouyer 
   5902  1.1.6.2  bouyer 	fsub.x		(%a1)+,%fp0		# X-Y1
   5903  1.1.6.2  bouyer 
   5904  1.1.6.2  bouyer 	fsub.s		(%a1),%fp0		# FP0 IS R = (X-Y1)-Y2
   5905  1.1.6.2  bouyer 
   5906  1.1.6.2  bouyer 	ror.l		&5,%d1
   5907  1.1.6.2  bouyer 	and.l		&0x80000000,%d1		# D0 WAS ODD IFF D0 < 0
   5908  1.1.6.2  bouyer 
   5909  1.1.6.2  bouyer TANCONT:
   5910  1.1.6.2  bouyer 	fmovm.x		&0x0c,-(%sp)		# save fp2,fp3
   5911  1.1.6.2  bouyer 
   5912  1.1.6.2  bouyer 	cmp.l		%d1,&0
   5913  1.1.6.2  bouyer 	blt.w		NODD
   5914  1.1.6.2  bouyer 
   5915  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   5916  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# S = R*R
   5917  1.1.6.2  bouyer 
   5918  1.1.6.2  bouyer 	fmov.d		TANQ4(%pc),%fp3
   5919  1.1.6.2  bouyer 	fmov.d		TANP3(%pc),%fp2
   5920  1.1.6.2  bouyer 
   5921  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# SQ4
   5922  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# SP3
   5923  1.1.6.2  bouyer 
   5924  1.1.6.2  bouyer 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
   5925  1.1.6.2  bouyer 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
   5926  1.1.6.2  bouyer 
   5927  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# S(Q3+SQ4)
   5928  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# S(P2+SP3)
   5929  1.1.6.2  bouyer 
   5930  1.1.6.2  bouyer 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
   5931  1.1.6.2  bouyer 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
   5932  1.1.6.2  bouyer 
   5933  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# S(Q2+S(Q3+SQ4))
   5934  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# S(P1+S(P2+SP3))
   5935  1.1.6.2  bouyer 
   5936  1.1.6.2  bouyer 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
   5937  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# RS(P1+S(P2+SP3))
   5938  1.1.6.2  bouyer 
   5939  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# S(Q1+S(Q2+S(Q3+SQ4)))
   5940  1.1.6.2  bouyer 
   5941  1.1.6.2  bouyer 	fadd.x		%fp2,%fp0		# R+RS(P1+S(P2+SP3))
   5942  1.1.6.2  bouyer 
   5943  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp1	# 1+S(Q1+...)
   5944  1.1.6.2  bouyer 
   5945  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
   5946  1.1.6.2  bouyer 
   5947  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5948  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# last inst - possible exception set
   5949  1.1.6.2  bouyer 	bra		t_inx2
   5950  1.1.6.2  bouyer 
   5951  1.1.6.2  bouyer NODD:
   5952  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   5953  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# S = R*R
   5954  1.1.6.2  bouyer 
   5955  1.1.6.2  bouyer 	fmov.d		TANQ4(%pc),%fp3
   5956  1.1.6.2  bouyer 	fmov.d		TANP3(%pc),%fp2
   5957  1.1.6.2  bouyer 
   5958  1.1.6.2  bouyer 	fmul.x		%fp0,%fp3		# SQ4
   5959  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# SP3
   5960  1.1.6.2  bouyer 
   5961  1.1.6.2  bouyer 	fadd.d		TANQ3(%pc),%fp3		# Q3+SQ4
   5962  1.1.6.2  bouyer 	fadd.x		TANP2(%pc),%fp2		# P2+SP3
   5963  1.1.6.2  bouyer 
   5964  1.1.6.2  bouyer 	fmul.x		%fp0,%fp3		# S(Q3+SQ4)
   5965  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(P2+SP3)
   5966  1.1.6.2  bouyer 
   5967  1.1.6.2  bouyer 	fadd.x		TANQ2(%pc),%fp3		# Q2+S(Q3+SQ4)
   5968  1.1.6.2  bouyer 	fadd.x		TANP1(%pc),%fp2		# P1+S(P2+SP3)
   5969  1.1.6.2  bouyer 
   5970  1.1.6.2  bouyer 	fmul.x		%fp0,%fp3		# S(Q2+S(Q3+SQ4))
   5971  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# S(P1+S(P2+SP3))
   5972  1.1.6.2  bouyer 
   5973  1.1.6.2  bouyer 	fadd.x		TANQ1(%pc),%fp3		# Q1+S(Q2+S(Q3+SQ4))
   5974  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# RS(P1+S(P2+SP3))
   5975  1.1.6.2  bouyer 
   5976  1.1.6.2  bouyer 	fmul.x		%fp3,%fp0		# S(Q1+S(Q2+S(Q3+SQ4)))
   5977  1.1.6.2  bouyer 
   5978  1.1.6.2  bouyer 	fadd.x		%fp2,%fp1		# R+RS(P1+S(P2+SP3))
   5979  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp0	# 1+S(Q1+...)
   5980  1.1.6.2  bouyer 
   5981  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# restore fp2,fp3
   5982  1.1.6.2  bouyer 
   5983  1.1.6.2  bouyer 	fmov.x		%fp1,-(%sp)
   5984  1.1.6.2  bouyer 	eor.l		&0x80000000,(%sp)
   5985  1.1.6.2  bouyer 
   5986  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5987  1.1.6.2  bouyer 	fdiv.x		(%sp)+,%fp0		# last inst - possible exception set
   5988  1.1.6.2  bouyer 	bra		t_inx2
   5989  1.1.6.2  bouyer 
   5990  1.1.6.2  bouyer TANBORS:
   5991  1.1.6.2  bouyer #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
   5992  1.1.6.2  bouyer #--IF |X| < 2**(-40), RETURN X OR 1.
   5993  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   5994  1.1.6.2  bouyer 	bgt.b		REDUCEX
   5995  1.1.6.2  bouyer 
   5996  1.1.6.2  bouyer TANSM:
   5997  1.1.6.2  bouyer 	fmov.x		%fp0,-(%sp)
   5998  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round mode,prec
   5999  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6000  1.1.6.2  bouyer 	fmov.x		(%sp)+,%fp0		# last inst - posibble exception set
   6001  1.1.6.2  bouyer 	bra		t_catch
   6002  1.1.6.2  bouyer 
   6003  1.1.6.2  bouyer 	global		stand
   6004  1.1.6.2  bouyer #--TAN(X) = X FOR DENORMALIZED X
   6005  1.1.6.2  bouyer stand:
   6006  1.1.6.2  bouyer 	bra		t_extdnrm
   6007  1.1.6.2  bouyer 
   6008  1.1.6.2  bouyer #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
   6009  1.1.6.2  bouyer #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
   6010  1.1.6.2  bouyer #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
   6011  1.1.6.2  bouyer REDUCEX:
   6012  1.1.6.2  bouyer 	fmovm.x		&0x3c,-(%sp)		# save {fp2-fp5}
   6013  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   6014  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp1	# fp1 = 0
   6015  1.1.6.2  bouyer 
   6016  1.1.6.2  bouyer #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
   6017  1.1.6.2  bouyer #--there is a danger of unwanted overflow in first LOOP iteration.  In this
   6018  1.1.6.2  bouyer #--case, reduce argument by one remainder step to make subsequent reduction
   6019  1.1.6.2  bouyer #--safe.
   6020  1.1.6.2  bouyer 	cmp.l		%d1,&0x7ffeffff		# is arg dangerously large?
   6021  1.1.6.2  bouyer 	bne.b		LOOP			# no
   6022  1.1.6.2  bouyer 
   6023  1.1.6.2  bouyer # yes; create 2**16383*PI/2
   6024  1.1.6.2  bouyer 	mov.w		&0x7ffe,FP_SCR0_EX(%a6)
   6025  1.1.6.2  bouyer 	mov.l		&0xc90fdaa2,FP_SCR0_HI(%a6)
   6026  1.1.6.2  bouyer 	clr.l		FP_SCR0_LO(%a6)
   6027  1.1.6.2  bouyer 
   6028  1.1.6.2  bouyer # create low half of 2**16383*PI/2 at FP_SCR1
   6029  1.1.6.2  bouyer 	mov.w		&0x7fdc,FP_SCR1_EX(%a6)
   6030  1.1.6.2  bouyer 	mov.l		&0x85a308d3,FP_SCR1_HI(%a6)
   6031  1.1.6.2  bouyer 	clr.l		FP_SCR1_LO(%a6)
   6032  1.1.6.2  bouyer 
   6033  1.1.6.2  bouyer 	ftest.x		%fp0			# test sign of argument
   6034  1.1.6.2  bouyer 	fblt.w		red_neg
   6035  1.1.6.2  bouyer 
   6036  1.1.6.2  bouyer 	or.b		&0x80,FP_SCR0_EX(%a6)	# positive arg
   6037  1.1.6.2  bouyer 	or.b		&0x80,FP_SCR1_EX(%a6)
   6038  1.1.6.2  bouyer red_neg:
   6039  1.1.6.2  bouyer 	fadd.x		FP_SCR0(%a6),%fp0	# high part of reduction is exact
   6040  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1		# save high result in fp1
   6041  1.1.6.2  bouyer 	fadd.x		FP_SCR1(%a6),%fp0	# low part of reduction
   6042  1.1.6.2  bouyer 	fsub.x		%fp0,%fp1		# determine low component of result
   6043  1.1.6.2  bouyer 	fadd.x		FP_SCR1(%a6),%fp1	# fp0/fp1 are reduced argument.
   6044  1.1.6.2  bouyer 
   6045  1.1.6.2  bouyer #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
   6046  1.1.6.2  bouyer #--integer quotient will be stored in N
   6047  1.1.6.2  bouyer #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
   6048  1.1.6.2  bouyer LOOP:
   6049  1.1.6.2  bouyer 	fmov.x		%fp0,INARG(%a6)		# +-2**K * F, 1 <= F < 2
   6050  1.1.6.2  bouyer 	mov.w		INARG(%a6),%d1
   6051  1.1.6.2  bouyer 	mov.l		%d1,%a1			# save a copy of D0
   6052  1.1.6.2  bouyer 	and.l		&0x00007FFF,%d1
   6053  1.1.6.2  bouyer 	sub.l		&0x00003FFF,%d1		# d0 = K
   6054  1.1.6.2  bouyer 	cmp.l		%d1,&28
   6055  1.1.6.2  bouyer 	ble.b		LASTLOOP
   6056  1.1.6.2  bouyer CONTLOOP:
   6057  1.1.6.2  bouyer 	sub.l		&27,%d1			# d0 = L := K-27
   6058  1.1.6.2  bouyer 	mov.b		&0,ENDFLAG(%a6)
   6059  1.1.6.2  bouyer 	bra.b		WORK
   6060  1.1.6.2  bouyer LASTLOOP:
   6061  1.1.6.2  bouyer 	clr.l		%d1			# d0 = L := 0
   6062  1.1.6.2  bouyer 	mov.b		&1,ENDFLAG(%a6)
   6063  1.1.6.2  bouyer 
   6064  1.1.6.2  bouyer WORK:
   6065  1.1.6.2  bouyer #--FIND THE REMAINDER OF (R,r) W.R.T.	2**L * (PI/2). L IS SO CHOSEN
   6066  1.1.6.2  bouyer #--THAT	INT( X * (2/PI) / 2**(L) ) < 2**29.
   6067  1.1.6.2  bouyer 
   6068  1.1.6.2  bouyer #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
   6069  1.1.6.2  bouyer #--2**L * (PIby2_1), 2**L * (PIby2_2)
   6070  1.1.6.2  bouyer 
   6071  1.1.6.2  bouyer 	mov.l		&0x00003FFE,%d2		# BIASED EXP OF 2/PI
   6072  1.1.6.2  bouyer 	sub.l		%d1,%d2			# BIASED EXP OF 2**(-L)*(2/PI)
   6073  1.1.6.2  bouyer 
   6074  1.1.6.2  bouyer 	mov.l		&0xA2F9836E,FP_SCR0_HI(%a6)
   6075  1.1.6.2  bouyer 	mov.l		&0x4E44152A,FP_SCR0_LO(%a6)
   6076  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)	# FP_SCR0 = 2**(-L)*(2/PI)
   6077  1.1.6.2  bouyer 
   6078  1.1.6.2  bouyer 	fmov.x		%fp0,%fp2
   6079  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp2	# fp2 = X * 2**(-L)*(2/PI)
   6080  1.1.6.2  bouyer 
   6081  1.1.6.2  bouyer #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
   6082  1.1.6.2  bouyer #--FLOATING POINT FORMAT, THE TWO FMOVE'S	FMOVE.L FP <--> N
   6083  1.1.6.2  bouyer #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
   6084  1.1.6.2  bouyer #--(SIGN(INARG)*2**63	+	FP2) - SIGN(INARG)*2**63 WILL GIVE
   6085  1.1.6.2  bouyer #--US THE DESIRED VALUE IN FLOATING POINT.
   6086  1.1.6.2  bouyer 	mov.l		%a1,%d2
   6087  1.1.6.2  bouyer 	swap		%d2
   6088  1.1.6.2  bouyer 	and.l		&0x80000000,%d2
   6089  1.1.6.2  bouyer 	or.l		&0x5F000000,%d2		# d2 = SIGN(INARG)*2**63 IN SGL
   6090  1.1.6.2  bouyer 	mov.l		%d2,TWOTO63(%a6)
   6091  1.1.6.2  bouyer 	fadd.s		TWOTO63(%a6),%fp2	# THE FRACTIONAL PART OF FP1 IS ROUNDED
   6092  1.1.6.2  bouyer 	fsub.s		TWOTO63(%a6),%fp2	# fp2 = N
   6093  1.1.6.2  bouyer #	fintrz.x	%fp2,%fp2
   6094  1.1.6.2  bouyer 
   6095  1.1.6.2  bouyer #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
   6096  1.1.6.2  bouyer 	mov.l		%d1,%d2			# d2 = L
   6097  1.1.6.2  bouyer 
   6098  1.1.6.2  bouyer 	add.l		&0x00003FFF,%d2		# BIASED EXP OF 2**L * (PI/2)
   6099  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)
   6100  1.1.6.2  bouyer 	mov.l		&0xC90FDAA2,FP_SCR0_HI(%a6)
   6101  1.1.6.2  bouyer 	clr.l		FP_SCR0_LO(%a6)		# FP_SCR0 = 2**(L) * Piby2_1
   6102  1.1.6.2  bouyer 
   6103  1.1.6.2  bouyer 	add.l		&0x00003FDD,%d1
   6104  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR1_EX(%a6)
   6105  1.1.6.2  bouyer 	mov.l		&0x85A308D3,FP_SCR1_HI(%a6)
   6106  1.1.6.2  bouyer 	clr.l		FP_SCR1_LO(%a6)		# FP_SCR1 = 2**(L) * Piby2_2
   6107  1.1.6.2  bouyer 
   6108  1.1.6.2  bouyer 	mov.b		ENDFLAG(%a6),%d1
   6109  1.1.6.2  bouyer 
   6110  1.1.6.2  bouyer #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
   6111  1.1.6.2  bouyer #--P2 = 2**(L) * Piby2_2
   6112  1.1.6.2  bouyer 	fmov.x		%fp2,%fp4		# fp4 = N
   6113  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp4	# fp4 = W = N*P1
   6114  1.1.6.2  bouyer 	fmov.x		%fp2,%fp5		# fp5 = N
   6115  1.1.6.2  bouyer 	fmul.x		FP_SCR1(%a6),%fp5	# fp5 = w = N*P2
   6116  1.1.6.2  bouyer 	fmov.x		%fp4,%fp3		# fp3 = W = N*P1
   6117  1.1.6.2  bouyer 
   6118  1.1.6.2  bouyer #--we want P+p = W+w  but  |p| <= half ulp of P
   6119  1.1.6.2  bouyer #--Then, we need to compute  A := R-P   and  a := r-p
   6120  1.1.6.2  bouyer 	fadd.x		%fp5,%fp3		# fp3 = P
   6121  1.1.6.2  bouyer 	fsub.x		%fp3,%fp4		# fp4 = W-P
   6122  1.1.6.2  bouyer 
   6123  1.1.6.2  bouyer 	fsub.x		%fp3,%fp0		# fp0 = A := R - P
   6124  1.1.6.2  bouyer 	fadd.x		%fp5,%fp4		# fp4 = p = (W-P)+w
   6125  1.1.6.2  bouyer 
   6126  1.1.6.2  bouyer 	fmov.x		%fp0,%fp3		# fp3 = A
   6127  1.1.6.2  bouyer 	fsub.x		%fp4,%fp1		# fp1 = a := r - p
   6128  1.1.6.2  bouyer 
   6129  1.1.6.2  bouyer #--Now we need to normalize (A,a) to  "new (R,r)" where R+r = A+a but
   6130  1.1.6.2  bouyer #--|r| <= half ulp of R.
   6131  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# fp0 = R := A+a
   6132  1.1.6.2  bouyer #--No need to calculate r if this is the last loop
   6133  1.1.6.2  bouyer 	cmp.b		%d1,&0
   6134  1.1.6.2  bouyer 	bgt.w		RESTORE
   6135  1.1.6.2  bouyer 
   6136  1.1.6.2  bouyer #--Need to calculate r
   6137  1.1.6.2  bouyer 	fsub.x		%fp0,%fp3		# fp3 = A-R
   6138  1.1.6.2  bouyer 	fadd.x		%fp3,%fp1		# fp1 = r := (A-R)+a
   6139  1.1.6.2  bouyer 	bra.w		LOOP
   6140  1.1.6.2  bouyer 
   6141  1.1.6.2  bouyer RESTORE:
   6142  1.1.6.2  bouyer 	fmov.l		%fp2,INT(%a6)
   6143  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   6144  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x3c		# restore {fp2-fp5}
   6145  1.1.6.2  bouyer 
   6146  1.1.6.2  bouyer 	mov.l		INT(%a6),%d1
   6147  1.1.6.2  bouyer 	ror.l		&1,%d1
   6148  1.1.6.2  bouyer 
   6149  1.1.6.2  bouyer 	bra.w		TANCONT
   6150  1.1.6.2  bouyer 
   6151  1.1.6.2  bouyer #########################################################################
   6152  1.1.6.2  bouyer # satan():  computes the arctangent of a normalized number		#
   6153  1.1.6.2  bouyer # satand(): computes the arctangent of a denormalized number		#
   6154  1.1.6.2  bouyer #									#
   6155  1.1.6.2  bouyer # INPUT	*************************************************************** #
   6156  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   6157  1.1.6.2  bouyer #	d0 = round precision,mode					#
   6158  1.1.6.2  bouyer #									#
   6159  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   6160  1.1.6.2  bouyer #	fp0 = arctan(X)							#
   6161  1.1.6.2  bouyer #									#
   6162  1.1.6.2  bouyer # ACCURACY and MONOTONICITY ******************************************* #
   6163  1.1.6.2  bouyer #	The returned result is within 2 ulps in	64 significant bit,	#
   6164  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6165  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   6166  1.1.6.2  bouyer #	in double precision. 						#
   6167  1.1.6.2  bouyer #									#
   6168  1.1.6.2  bouyer # ALGORITHM *********************************************************** #
   6169  1.1.6.2  bouyer #	Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5.		#
   6170  1.1.6.2  bouyer #									#
   6171  1.1.6.2  bouyer #	Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. 			#
   6172  1.1.6.2  bouyer #		Note that k = -4, -3,..., or 3.				#
   6173  1.1.6.2  bouyer #		Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 	#
   6174  1.1.6.2  bouyer #		significant bits of X with a bit-1 attached at the 6-th	#
   6175  1.1.6.2  bouyer #		bit position. Define u to be u = (X-F) / (1 + X*F).	#
   6176  1.1.6.2  bouyer #									#
   6177  1.1.6.2  bouyer #	Step 3. Approximate arctan(u) by a polynomial poly.		#
   6178  1.1.6.2  bouyer #									#
   6179  1.1.6.2  bouyer #	Step 4. Return arctan(F) + poly, arctan(F) is fetched from a 	#
   6180  1.1.6.2  bouyer #		table of values calculated beforehand. Exit.		#
   6181  1.1.6.2  bouyer #									#
   6182  1.1.6.2  bouyer #	Step 5. If |X| >= 16, go to Step 7.				#
   6183  1.1.6.2  bouyer #									#
   6184  1.1.6.2  bouyer #	Step 6. Approximate arctan(X) by an odd polynomial in X. Exit.	#
   6185  1.1.6.2  bouyer #									#
   6186  1.1.6.2  bouyer #	Step 7. Define X' = -1/X. Approximate arctan(X') by an odd 	#
   6187  1.1.6.2  bouyer #		polynomial in X'.					#
   6188  1.1.6.2  bouyer #		Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit.		#
   6189  1.1.6.2  bouyer #									#
   6190  1.1.6.2  bouyer #########################################################################
   6191  1.1.6.2  bouyer 
   6192  1.1.6.2  bouyer ATANA3:	long		0xBFF6687E,0x314987D8
   6193  1.1.6.2  bouyer ATANA2:	long		0x4002AC69,0x34A26DB3
   6194  1.1.6.2  bouyer ATANA1:	long		0xBFC2476F,0x4E1DA28E
   6195  1.1.6.2  bouyer 
   6196  1.1.6.2  bouyer ATANB6:	long		0x3FB34444,0x7F876989
   6197  1.1.6.2  bouyer ATANB5:	long		0xBFB744EE,0x7FAF45DB
   6198  1.1.6.2  bouyer ATANB4:	long		0x3FBC71C6,0x46940220
   6199  1.1.6.2  bouyer ATANB3:	long		0xBFC24924,0x921872F9
   6200  1.1.6.2  bouyer ATANB2:	long		0x3FC99999,0x99998FA9
   6201  1.1.6.2  bouyer ATANB1:	long		0xBFD55555,0x55555555
   6202  1.1.6.2  bouyer 
   6203  1.1.6.2  bouyer ATANC5:	long		0xBFB70BF3,0x98539E6A
   6204  1.1.6.2  bouyer ATANC4:	long		0x3FBC7187,0x962D1D7D
   6205  1.1.6.2  bouyer ATANC3:	long		0xBFC24924,0x827107B8
   6206  1.1.6.2  bouyer ATANC2:	long		0x3FC99999,0x9996263E
   6207  1.1.6.2  bouyer ATANC1:	long		0xBFD55555,0x55555536
   6208  1.1.6.2  bouyer 
   6209  1.1.6.2  bouyer PPIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
   6210  1.1.6.2  bouyer NPIBY2:	long		0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
   6211  1.1.6.2  bouyer 
   6212  1.1.6.2  bouyer PTINY:	long		0x00010000,0x80000000,0x00000000,0x00000000
   6213  1.1.6.2  bouyer NTINY:	long		0x80010000,0x80000000,0x00000000,0x00000000
   6214  1.1.6.2  bouyer 
   6215  1.1.6.2  bouyer ATANTBL:
   6216  1.1.6.2  bouyer 	long		0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
   6217  1.1.6.2  bouyer 	long		0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
   6218  1.1.6.2  bouyer 	long		0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
   6219  1.1.6.2  bouyer 	long		0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
   6220  1.1.6.2  bouyer 	long		0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
   6221  1.1.6.2  bouyer 	long		0x3FFB0000,0xAB98E943,0x62765619,0x00000000
   6222  1.1.6.2  bouyer 	long		0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
   6223  1.1.6.2  bouyer 	long		0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
   6224  1.1.6.2  bouyer 	long		0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
   6225  1.1.6.2  bouyer 	long		0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
   6226  1.1.6.2  bouyer 	long		0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
   6227  1.1.6.2  bouyer 	long		0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
   6228  1.1.6.2  bouyer 	long		0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
   6229  1.1.6.2  bouyer 	long		0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
   6230  1.1.6.2  bouyer 	long		0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
   6231  1.1.6.2  bouyer 	long		0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
   6232  1.1.6.2  bouyer 	long		0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
   6233  1.1.6.2  bouyer 	long		0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
   6234  1.1.6.2  bouyer 	long		0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
   6235  1.1.6.2  bouyer 	long		0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
   6236  1.1.6.2  bouyer 	long		0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
   6237  1.1.6.2  bouyer 	long		0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
   6238  1.1.6.2  bouyer 	long		0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
   6239  1.1.6.2  bouyer 	long		0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
   6240  1.1.6.2  bouyer 	long		0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
   6241  1.1.6.2  bouyer 	long		0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
   6242  1.1.6.2  bouyer 	long		0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
   6243  1.1.6.2  bouyer 	long		0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
   6244  1.1.6.2  bouyer 	long		0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
   6245  1.1.6.2  bouyer 	long		0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
   6246  1.1.6.2  bouyer 	long		0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
   6247  1.1.6.2  bouyer 	long		0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
   6248  1.1.6.2  bouyer 	long		0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
   6249  1.1.6.2  bouyer 	long		0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
   6250  1.1.6.2  bouyer 	long		0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
   6251  1.1.6.2  bouyer 	long		0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
   6252  1.1.6.2  bouyer 	long		0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
   6253  1.1.6.2  bouyer 	long		0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
   6254  1.1.6.2  bouyer 	long		0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
   6255  1.1.6.2  bouyer 	long		0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
   6256  1.1.6.2  bouyer 	long		0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
   6257  1.1.6.2  bouyer 	long		0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
   6258  1.1.6.2  bouyer 	long		0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
   6259  1.1.6.2  bouyer 	long		0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
   6260  1.1.6.2  bouyer 	long		0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
   6261  1.1.6.2  bouyer 	long		0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
   6262  1.1.6.2  bouyer 	long		0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
   6263  1.1.6.2  bouyer 	long		0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
   6264  1.1.6.2  bouyer 	long		0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
   6265  1.1.6.2  bouyer 	long		0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
   6266  1.1.6.2  bouyer 	long		0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
   6267  1.1.6.2  bouyer 	long		0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
   6268  1.1.6.2  bouyer 	long		0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
   6269  1.1.6.2  bouyer 	long		0x3FFE0000,0x97731420,0x365E538C,0x00000000
   6270  1.1.6.2  bouyer 	long		0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
   6271  1.1.6.2  bouyer 	long		0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
   6272  1.1.6.2  bouyer 	long		0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
   6273  1.1.6.2  bouyer 	long		0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
   6274  1.1.6.2  bouyer 	long		0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
   6275  1.1.6.2  bouyer 	long		0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
   6276  1.1.6.2  bouyer 	long		0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
   6277  1.1.6.2  bouyer 	long		0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
   6278  1.1.6.2  bouyer 	long		0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
   6279  1.1.6.2  bouyer 	long		0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
   6280  1.1.6.2  bouyer 	long		0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
   6281  1.1.6.2  bouyer 	long		0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
   6282  1.1.6.2  bouyer 	long		0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
   6283  1.1.6.2  bouyer 	long		0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
   6284  1.1.6.2  bouyer 	long		0x3FFE0000,0xE8771129,0xC4353259,0x00000000
   6285  1.1.6.2  bouyer 	long		0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
   6286  1.1.6.2  bouyer 	long		0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
   6287  1.1.6.2  bouyer 	long		0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
   6288  1.1.6.2  bouyer 	long		0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
   6289  1.1.6.2  bouyer 	long		0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
   6290  1.1.6.2  bouyer 	long		0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
   6291  1.1.6.2  bouyer 	long		0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
   6292  1.1.6.2  bouyer 	long		0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
   6293  1.1.6.2  bouyer 	long		0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
   6294  1.1.6.2  bouyer 	long		0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
   6295  1.1.6.2  bouyer 	long		0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
   6296  1.1.6.2  bouyer 	long		0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
   6297  1.1.6.2  bouyer 	long		0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
   6298  1.1.6.2  bouyer 	long		0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
   6299  1.1.6.2  bouyer 	long		0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
   6300  1.1.6.2  bouyer 	long		0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
   6301  1.1.6.2  bouyer 	long		0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
   6302  1.1.6.2  bouyer 	long		0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
   6303  1.1.6.2  bouyer 	long		0x3FFF0000,0x9F100575,0x006CC571,0x00000000
   6304  1.1.6.2  bouyer 	long		0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
   6305  1.1.6.2  bouyer 	long		0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
   6306  1.1.6.2  bouyer 	long		0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
   6307  1.1.6.2  bouyer 	long		0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
   6308  1.1.6.2  bouyer 	long		0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
   6309  1.1.6.2  bouyer 	long		0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
   6310  1.1.6.2  bouyer 	long		0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
   6311  1.1.6.2  bouyer 	long		0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
   6312  1.1.6.2  bouyer 	long		0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
   6313  1.1.6.2  bouyer 	long		0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
   6314  1.1.6.2  bouyer 	long		0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
   6315  1.1.6.2  bouyer 	long		0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
   6316  1.1.6.2  bouyer 	long		0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
   6317  1.1.6.2  bouyer 	long		0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
   6318  1.1.6.2  bouyer 	long		0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
   6319  1.1.6.2  bouyer 	long		0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
   6320  1.1.6.2  bouyer 	long		0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
   6321  1.1.6.2  bouyer 	long		0x3FFF0000,0xB525529D,0x562246BD,0x00000000
   6322  1.1.6.2  bouyer 	long		0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
   6323  1.1.6.2  bouyer 	long		0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
   6324  1.1.6.2  bouyer 	long		0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
   6325  1.1.6.2  bouyer 	long		0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
   6326  1.1.6.2  bouyer 	long		0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
   6327  1.1.6.2  bouyer 	long		0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
   6328  1.1.6.2  bouyer 	long		0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
   6329  1.1.6.2  bouyer 	long		0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
   6330  1.1.6.2  bouyer 	long		0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
   6331  1.1.6.2  bouyer 	long		0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
   6332  1.1.6.2  bouyer 	long		0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
   6333  1.1.6.2  bouyer 	long		0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
   6334  1.1.6.2  bouyer 	long		0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
   6335  1.1.6.2  bouyer 	long		0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
   6336  1.1.6.2  bouyer 	long		0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
   6337  1.1.6.2  bouyer 	long		0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
   6338  1.1.6.2  bouyer 	long		0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
   6339  1.1.6.2  bouyer 	long		0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
   6340  1.1.6.2  bouyer 	long		0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
   6341  1.1.6.2  bouyer 	long		0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
   6342  1.1.6.2  bouyer 	long		0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
   6343  1.1.6.2  bouyer 	long		0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
   6344  1.1.6.2  bouyer 
   6345  1.1.6.2  bouyer 	set		X,FP_SCR0
   6346  1.1.6.2  bouyer 	set		XDCARE,X+2
   6347  1.1.6.2  bouyer 	set		XFRAC,X+4
   6348  1.1.6.2  bouyer 	set		XFRACLO,X+8
   6349  1.1.6.2  bouyer 
   6350  1.1.6.2  bouyer 	set		ATANF,FP_SCR1
   6351  1.1.6.2  bouyer 	set		ATANFHI,ATANF+4
   6352  1.1.6.2  bouyer 	set		ATANFLO,ATANF+8
   6353  1.1.6.2  bouyer 
   6354  1.1.6.2  bouyer 	global		satan
   6355  1.1.6.2  bouyer #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   6356  1.1.6.2  bouyer satan:
   6357  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6358  1.1.6.2  bouyer 
   6359  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   6360  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   6361  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)
   6362  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   6363  1.1.6.2  bouyer 
   6364  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFB8000		# |X| >= 1/16?
   6365  1.1.6.2  bouyer 	bge.b		ATANOK1
   6366  1.1.6.2  bouyer 	bra.w		ATANSM
   6367  1.1.6.2  bouyer 
   6368  1.1.6.2  bouyer ATANOK1:
   6369  1.1.6.2  bouyer 	cmp.l		%d1,&0x4002FFFF		# |X| < 16 ?
   6370  1.1.6.2  bouyer 	ble.b		ATANMAIN
   6371  1.1.6.2  bouyer 	bra.w		ATANBIG
   6372  1.1.6.2  bouyer 
   6373  1.1.6.2  bouyer #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
   6374  1.1.6.2  bouyer #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
   6375  1.1.6.2  bouyer #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
   6376  1.1.6.2  bouyer #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
   6377  1.1.6.2  bouyer #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
   6378  1.1.6.2  bouyer #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
   6379  1.1.6.2  bouyer #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
   6380  1.1.6.2  bouyer #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
   6381  1.1.6.2  bouyer #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
   6382  1.1.6.2  bouyer #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
   6383  1.1.6.2  bouyer #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
   6384  1.1.6.2  bouyer #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
   6385  1.1.6.2  bouyer #--WILL INVOLVE A VERY LONG POLYNOMIAL.
   6386  1.1.6.2  bouyer 
   6387  1.1.6.2  bouyer #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
   6388  1.1.6.2  bouyer #--WE CHOSE F TO BE +-2^K * 1.BBBB1
   6389  1.1.6.2  bouyer #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
   6390  1.1.6.2  bouyer #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
   6391  1.1.6.2  bouyer #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
   6392  1.1.6.2  bouyer #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
   6393  1.1.6.2  bouyer 
   6394  1.1.6.2  bouyer ATANMAIN:
   6395  1.1.6.2  bouyer 
   6396  1.1.6.2  bouyer 	and.l		&0xF8000000,XFRAC(%a6)	# FIRST 5 BITS
   6397  1.1.6.2  bouyer 	or.l		&0x04000000,XFRAC(%a6)	# SET 6-TH BIT TO 1
   6398  1.1.6.2  bouyer 	mov.l		&0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
   6399  1.1.6.2  bouyer 
   6400  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1		# FP1 IS X
   6401  1.1.6.2  bouyer 	fmul.x		X(%a6),%fp1		# FP1 IS X*F, NOTE THAT X*F > 0
   6402  1.1.6.2  bouyer 	fsub.x		X(%a6),%fp0		# FP0 IS X-F
   6403  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp1	# FP1 IS 1 + X*F
   6404  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# FP0 IS U = (X-F)/(1+X*F)
   6405  1.1.6.2  bouyer 
   6406  1.1.6.2  bouyer #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
   6407  1.1.6.2  bouyer #--CREATE ATAN(F) AND STORE IT IN ATANF, AND
   6408  1.1.6.2  bouyer #--SAVE REGISTERS FP2.
   6409  1.1.6.2  bouyer 
   6410  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# SAVE d2 TEMPORARILY
   6411  1.1.6.2  bouyer 	mov.l		%d1,%d2			# THE EXP AND 16 BITS OF X
   6412  1.1.6.2  bouyer 	and.l		&0x00007800,%d1		# 4 VARYING BITS OF F'S FRACTION
   6413  1.1.6.2  bouyer 	and.l		&0x7FFF0000,%d2		# EXPONENT OF F
   6414  1.1.6.2  bouyer 	sub.l		&0x3FFB0000,%d2		# K+4
   6415  1.1.6.2  bouyer 	asr.l		&1,%d2
   6416  1.1.6.2  bouyer 	add.l		%d2,%d1			# THE 7 BITS IDENTIFYING F
   6417  1.1.6.2  bouyer 	asr.l		&7,%d1			# INDEX INTO TBL OF ATAN(|F|)
   6418  1.1.6.2  bouyer 	lea		ATANTBL(%pc),%a1
   6419  1.1.6.2  bouyer 	add.l		%d1,%a1			# ADDRESS OF ATAN(|F|)
   6420  1.1.6.2  bouyer 	mov.l		(%a1)+,ATANF(%a6)
   6421  1.1.6.2  bouyer 	mov.l		(%a1)+,ATANFHI(%a6)
   6422  1.1.6.2  bouyer 	mov.l		(%a1)+,ATANFLO(%a6)	# ATANF IS NOW ATAN(|F|)
   6423  1.1.6.2  bouyer 	mov.l		X(%a6),%d1		# LOAD SIGN AND EXPO. AGAIN
   6424  1.1.6.2  bouyer 	and.l		&0x80000000,%d1		# SIGN(F)
   6425  1.1.6.2  bouyer 	or.l		%d1,ATANF(%a6)		# ATANF IS NOW SIGN(F)*ATAN(|F|)
   6426  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# RESTORE d2
   6427  1.1.6.2  bouyer 
   6428  1.1.6.2  bouyer #--THAT'S ALL I HAVE TO DO FOR NOW,
   6429  1.1.6.2  bouyer #--BUT ALAS, THE DIVIDE IS STILL CRANKING!
   6430  1.1.6.2  bouyer 
   6431  1.1.6.2  bouyer #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
   6432  1.1.6.2  bouyer #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
   6433  1.1.6.2  bouyer #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
   6434  1.1.6.2  bouyer #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
   6435  1.1.6.2  bouyer #--WHAT WE HAVE HERE IS MERELY	A1 = A3, A2 = A1/A3, A3 = A2/A3.
   6436  1.1.6.2  bouyer #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
   6437  1.1.6.2  bouyer #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
   6438  1.1.6.2  bouyer 
   6439  1.1.6.2  bouyer 	fmovm.x		&0x04,-(%sp)		# save fp2
   6440  1.1.6.2  bouyer 
   6441  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   6442  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1
   6443  1.1.6.2  bouyer 	fmov.d		ATANA3(%pc),%fp2
   6444  1.1.6.2  bouyer 	fadd.x		%fp1,%fp2		# A3+V
   6445  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# V*(A3+V)
   6446  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# U*V
   6447  1.1.6.2  bouyer 	fadd.d		ATANA2(%pc),%fp2	# A2+V*(A3+V)
   6448  1.1.6.2  bouyer 	fmul.d		ATANA1(%pc),%fp1	# A1*U*V
   6449  1.1.6.2  bouyer 	fmul.x		%fp2,%fp1		# A1*U*V*(A2+V*(A3+V))
   6450  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# ATAN(U), FP1 RELEASED
   6451  1.1.6.2  bouyer 
   6452  1.1.6.2  bouyer 	fmovm.x 	(%sp)+,&0x20		# restore fp2
   6453  1.1.6.2  bouyer 
   6454  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6455  1.1.6.2  bouyer 	fadd.x		ATANF(%a6),%fp0		# ATAN(X)
   6456  1.1.6.2  bouyer 	bra		t_inx2
   6457  1.1.6.2  bouyer 
   6458  1.1.6.2  bouyer ATANBORS:
   6459  1.1.6.2  bouyer #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
   6460  1.1.6.2  bouyer #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
   6461  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   6462  1.1.6.2  bouyer 	bgt.w		ATANBIG			# I.E. |X| >= 16
   6463  1.1.6.2  bouyer 
   6464  1.1.6.2  bouyer ATANSM:
   6465  1.1.6.2  bouyer #--|X| <= 1/16
   6466  1.1.6.2  bouyer #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
   6467  1.1.6.2  bouyer #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
   6468  1.1.6.2  bouyer #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
   6469  1.1.6.2  bouyer #--WHERE Y = X*X, AND Z = Y*Y.
   6470  1.1.6.2  bouyer 
   6471  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FD78000
   6472  1.1.6.2  bouyer 	blt.w		ATANTINY
   6473  1.1.6.2  bouyer 
   6474  1.1.6.2  bouyer #--COMPUTE POLYNOMIAL
   6475  1.1.6.2  bouyer 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   6476  1.1.6.2  bouyer 
   6477  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# FPO IS Y = X*X
   6478  1.1.6.2  bouyer 
   6479  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   6480  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
   6481  1.1.6.2  bouyer 
   6482  1.1.6.2  bouyer 	fmov.d		ATANB6(%pc),%fp2
   6483  1.1.6.2  bouyer 	fmov.d		ATANB5(%pc),%fp3
   6484  1.1.6.2  bouyer 
   6485  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# Z*B6
   6486  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# Z*B5
   6487  1.1.6.2  bouyer 
   6488  1.1.6.2  bouyer 	fadd.d		ATANB4(%pc),%fp2	# B4+Z*B6
   6489  1.1.6.2  bouyer 	fadd.d		ATANB3(%pc),%fp3	# B3+Z*B5
   6490  1.1.6.2  bouyer 
   6491  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# Z*(B4+Z*B6)
   6492  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# Z*(B3+Z*B5)
   6493  1.1.6.2  bouyer 
   6494  1.1.6.2  bouyer 	fadd.d		ATANB2(%pc),%fp2	# B2+Z*(B4+Z*B6)
   6495  1.1.6.2  bouyer 	fadd.d		ATANB1(%pc),%fp1	# B1+Z*(B3+Z*B5)
   6496  1.1.6.2  bouyer 
   6497  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# Y*(B2+Z*(B4+Z*B6))
   6498  1.1.6.2  bouyer 	fmul.x		X(%a6),%fp0		# X*Y
   6499  1.1.6.2  bouyer 
   6500  1.1.6.2  bouyer 	fadd.x		%fp2,%fp1		# [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
   6501  1.1.6.2  bouyer 
   6502  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0		# X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
   6503  1.1.6.2  bouyer 
   6504  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   6505  1.1.6.2  bouyer 
   6506  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6507  1.1.6.2  bouyer 	fadd.x		X(%a6),%fp0
   6508  1.1.6.2  bouyer 	bra		t_inx2
   6509  1.1.6.2  bouyer 
   6510  1.1.6.2  bouyer ATANTINY:
   6511  1.1.6.2  bouyer #--|X| < 2^(-40), ATAN(X) = X
   6512  1.1.6.2  bouyer 
   6513  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6514  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6515  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   6516  1.1.6.2  bouyer 
   6517  1.1.6.2  bouyer 	bra		t_catch
   6518  1.1.6.2  bouyer 
   6519  1.1.6.2  bouyer ATANBIG:
   6520  1.1.6.2  bouyer #--IF |X| > 2^(100), RETURN	SIGN(X)*(PI/2 - TINY). OTHERWISE,
   6521  1.1.6.2  bouyer #--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
   6522  1.1.6.2  bouyer 	cmp.l		%d1,&0x40638000
   6523  1.1.6.2  bouyer 	bgt.w		ATANHUGE
   6524  1.1.6.2  bouyer 
   6525  1.1.6.2  bouyer #--APPROXIMATE ATAN(-1/X) BY
   6526  1.1.6.2  bouyer #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
   6527  1.1.6.2  bouyer #--THIS CAN BE RE-WRITTEN AS
   6528  1.1.6.2  bouyer #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
   6529  1.1.6.2  bouyer 
   6530  1.1.6.2  bouyer 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   6531  1.1.6.2  bouyer 
   6532  1.1.6.2  bouyer 	fmov.s		&0xBF800000,%fp1	# LOAD -1
   6533  1.1.6.2  bouyer 	fdiv.x		%fp0,%fp1		# FP1 IS -1/X
   6534  1.1.6.2  bouyer 
   6535  1.1.6.2  bouyer #--DIVIDE IS STILL CRANKING
   6536  1.1.6.2  bouyer 
   6537  1.1.6.2  bouyer 	fmov.x		%fp1,%fp0		# FP0 IS X'
   6538  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# FP0 IS Y = X'*X'
   6539  1.1.6.2  bouyer 	fmov.x		%fp1,X(%a6)		# X IS REALLY X'
   6540  1.1.6.2  bouyer 
   6541  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   6542  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# FP1 IS Z = Y*Y
   6543  1.1.6.2  bouyer 
   6544  1.1.6.2  bouyer 	fmov.d		ATANC5(%pc),%fp3
   6545  1.1.6.2  bouyer 	fmov.d		ATANC4(%pc),%fp2
   6546  1.1.6.2  bouyer 
   6547  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# Z*C5
   6548  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# Z*B4
   6549  1.1.6.2  bouyer 
   6550  1.1.6.2  bouyer 	fadd.d		ATANC3(%pc),%fp3	# C3+Z*C5
   6551  1.1.6.2  bouyer 	fadd.d		ATANC2(%pc),%fp2	# C2+Z*C4
   6552  1.1.6.2  bouyer 
   6553  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# Z*(C3+Z*C5), FP3 RELEASED
   6554  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# Y*(C2+Z*C4)
   6555  1.1.6.2  bouyer 
   6556  1.1.6.2  bouyer 	fadd.d		ATANC1(%pc),%fp1	# C1+Z*(C3+Z*C5)
   6557  1.1.6.2  bouyer 	fmul.x		X(%a6),%fp0		# X'*Y
   6558  1.1.6.2  bouyer 
   6559  1.1.6.2  bouyer 	fadd.x		%fp2,%fp1		# [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
   6560  1.1.6.2  bouyer 
   6561  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0		# X'*Y*([B1+Z*(B3+Z*B5)]
   6562  1.1.6.2  bouyer #					...	+[Y*(B2+Z*(B4+Z*B6))])
   6563  1.1.6.2  bouyer 	fadd.x		X(%a6),%fp0
   6564  1.1.6.2  bouyer 
   6565  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   6566  1.1.6.2  bouyer 
   6567  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6568  1.1.6.2  bouyer 	tst.b		(%a0)
   6569  1.1.6.2  bouyer 	bpl.b		pos_big
   6570  1.1.6.2  bouyer 
   6571  1.1.6.2  bouyer neg_big:
   6572  1.1.6.2  bouyer 	fadd.x		NPIBY2(%pc),%fp0
   6573  1.1.6.2  bouyer 	bra		t_minx2
   6574  1.1.6.2  bouyer 
   6575  1.1.6.2  bouyer pos_big:
   6576  1.1.6.2  bouyer 	fadd.x		PPIBY2(%pc),%fp0
   6577  1.1.6.2  bouyer 	bra		t_pinx2
   6578  1.1.6.2  bouyer 
   6579  1.1.6.2  bouyer ATANHUGE:
   6580  1.1.6.2  bouyer #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
   6581  1.1.6.2  bouyer 	tst.b		(%a0)
   6582  1.1.6.2  bouyer 	bpl.b		pos_huge
   6583  1.1.6.2  bouyer 
   6584  1.1.6.2  bouyer neg_huge:
   6585  1.1.6.2  bouyer 	fmov.x		NPIBY2(%pc),%fp0
   6586  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   6587  1.1.6.2  bouyer 	fadd.x		PTINY(%pc),%fp0
   6588  1.1.6.2  bouyer 	bra		t_minx2
   6589  1.1.6.2  bouyer 
   6590  1.1.6.2  bouyer pos_huge:
   6591  1.1.6.2  bouyer 	fmov.x		PPIBY2(%pc),%fp0
   6592  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   6593  1.1.6.2  bouyer 	fadd.x		NTINY(%pc),%fp0
   6594  1.1.6.2  bouyer 	bra		t_pinx2
   6595  1.1.6.2  bouyer 
   6596  1.1.6.2  bouyer 	global		satand
   6597  1.1.6.2  bouyer #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
   6598  1.1.6.2  bouyer satand:
   6599  1.1.6.2  bouyer 	bra		t_extdnrm
   6600  1.1.6.2  bouyer 
   6601  1.1.6.2  bouyer #########################################################################
   6602  1.1.6.2  bouyer # sasin():  computes the inverse sine of a normalized input		#
   6603  1.1.6.2  bouyer # sasind(): computes the inverse sine of a denormalized input		#
   6604  1.1.6.2  bouyer #									#
   6605  1.1.6.2  bouyer # INPUT ***************************************************************	#
   6606  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   6607  1.1.6.2  bouyer #	d0 = round precision,mode					#
   6608  1.1.6.2  bouyer #									#
   6609  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   6610  1.1.6.2  bouyer #	fp0 = arcsin(X)							#
   6611  1.1.6.2  bouyer #									#
   6612  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   6613  1.1.6.2  bouyer #	The returned result is within 3 ulps in	64 significant bit,	#
   6614  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6615  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   6616  1.1.6.2  bouyer #	in double precision.						#
   6617  1.1.6.2  bouyer #									#
   6618  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   6619  1.1.6.2  bouyer #									#
   6620  1.1.6.2  bouyer #	ASIN								#
   6621  1.1.6.2  bouyer #	1. If |X| >= 1, go to 3.					#
   6622  1.1.6.2  bouyer #									#
   6623  1.1.6.2  bouyer #	2. (|X| < 1) Calculate asin(X) by				#
   6624  1.1.6.2  bouyer #		z := sqrt( [1-X][1+X] )					#
   6625  1.1.6.2  bouyer #		asin(X) = atan( x / z ).				#
   6626  1.1.6.2  bouyer #		Exit.							#
   6627  1.1.6.2  bouyer #									#
   6628  1.1.6.2  bouyer #	3. If |X| > 1, go to 5.						#
   6629  1.1.6.2  bouyer #									#
   6630  1.1.6.2  bouyer #	4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
   6631  1.1.6.2  bouyer #									#
   6632  1.1.6.2  bouyer #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   6633  1.1.6.2  bouyer #		Exit.							#
   6634  1.1.6.2  bouyer #									#
   6635  1.1.6.2  bouyer #########################################################################
   6636  1.1.6.2  bouyer 
   6637  1.1.6.2  bouyer 	global		sasin
   6638  1.1.6.2  bouyer sasin:
   6639  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6640  1.1.6.2  bouyer 
   6641  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   6642  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   6643  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   6644  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   6645  1.1.6.2  bouyer 	bge.b		ASINBIG
   6646  1.1.6.2  bouyer 
   6647  1.1.6.2  bouyer # This catch is added here for the '060 QSP. Originally, the call to
   6648  1.1.6.2  bouyer # satan() would handle this case by causing the exception which would
   6649  1.1.6.2  bouyer # not be caught until gen_except(). Now, with the exceptions being
   6650  1.1.6.2  bouyer # detected inside of satan(), the exception would have been handled there
   6651  1.1.6.2  bouyer # instead of inside sasin() as expected.
   6652  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FD78000
   6653  1.1.6.2  bouyer 	blt.w		ASINTINY
   6654  1.1.6.2  bouyer 
   6655  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| < 1
   6656  1.1.6.2  bouyer #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
   6657  1.1.6.2  bouyer 
   6658  1.1.6.2  bouyer ASINMAIN:
   6659  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp1
   6660  1.1.6.2  bouyer 	fsub.x		%fp0,%fp1		# 1-X
   6661  1.1.6.2  bouyer 	fmovm.x		&0x4,-(%sp)		#  {fp2}
   6662  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp2
   6663  1.1.6.2  bouyer 	fadd.x		%fp0,%fp2		# 1+X
   6664  1.1.6.2  bouyer 	fmul.x		%fp2,%fp1		# (1+X)(1-X)
   6665  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x20		#  {fp2}
   6666  1.1.6.2  bouyer 	fsqrt.x		%fp1			# SQRT([1-X][1+X])
   6667  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# X/SQRT([1-X][1+X])
   6668  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save X/SQRT(...)
   6669  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to X/SQRT(...)
   6670  1.1.6.2  bouyer 	bsr		satan
   6671  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear X/SQRT(...) from stack
   6672  1.1.6.2  bouyer 	bra		t_inx2
   6673  1.1.6.2  bouyer 
   6674  1.1.6.2  bouyer ASINBIG:
   6675  1.1.6.2  bouyer 	fabs.x		%fp0			# |X|
   6676  1.1.6.2  bouyer 	fcmp.s		%fp0,&0x3F800000
   6677  1.1.6.2  bouyer 	fbgt		t_operr			# cause an operr exception
   6678  1.1.6.2  bouyer 
   6679  1.1.6.2  bouyer #--|X| = 1, ASIN(X) = +- PI/2.
   6680  1.1.6.2  bouyer ASINONE:
   6681  1.1.6.2  bouyer 	fmov.x		PIBY2(%pc),%fp0
   6682  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   6683  1.1.6.2  bouyer 	and.l		&0x80000000,%d1		# SIGN BIT OF X
   6684  1.1.6.2  bouyer 	or.l		&0x3F800000,%d1		# +-1 IN SGL FORMAT
   6685  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# push SIGN(X) IN SGL-FMT
   6686  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   6687  1.1.6.2  bouyer 	fmul.s		(%sp)+,%fp0
   6688  1.1.6.2  bouyer 	bra		t_inx2
   6689  1.1.6.2  bouyer 
   6690  1.1.6.2  bouyer #--|X| < 2^(-40), ATAN(X) = X
   6691  1.1.6.2  bouyer ASINTINY:
   6692  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users rnd mode,prec
   6693  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   6694  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# last inst - possible exception
   6695  1.1.6.2  bouyer 	bra		t_catch
   6696  1.1.6.2  bouyer 
   6697  1.1.6.2  bouyer 	global		sasind
   6698  1.1.6.2  bouyer #--ASIN(X) = X FOR DENORMALIZED X
   6699  1.1.6.2  bouyer sasind:
   6700  1.1.6.2  bouyer 	bra		t_extdnrm
   6701  1.1.6.2  bouyer 
   6702  1.1.6.2  bouyer #########################################################################
   6703  1.1.6.2  bouyer # sacos():  computes the inverse cosine of a normalized input		#
   6704  1.1.6.2  bouyer # sacosd(): computes the inverse cosine of a denormalized input		#
   6705  1.1.6.2  bouyer #									#
   6706  1.1.6.2  bouyer # INPUT ***************************************************************	#
   6707  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   6708  1.1.6.2  bouyer #	d0 = round precision,mode					#
   6709  1.1.6.2  bouyer #									#
   6710  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   6711  1.1.6.2  bouyer #	fp0 = arccos(X)							#
   6712  1.1.6.2  bouyer #									#
   6713  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   6714  1.1.6.2  bouyer #	The returned result is within 3 ulps in	64 significant bit,	#
   6715  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   6716  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   6717  1.1.6.2  bouyer #	in double precision.						#
   6718  1.1.6.2  bouyer #									#
   6719  1.1.6.2  bouyer # ALGORITHM *********************************************************** #
   6720  1.1.6.2  bouyer #									#
   6721  1.1.6.2  bouyer #	ACOS								#
   6722  1.1.6.2  bouyer #	1. If |X| >= 1, go to 3.					#
   6723  1.1.6.2  bouyer #									#
   6724  1.1.6.2  bouyer #	2. (|X| < 1) Calculate acos(X) by				#
   6725  1.1.6.2  bouyer #		z := (1-X) / (1+X)					#
   6726  1.1.6.2  bouyer #		acos(X) = 2 * atan( sqrt(z) ).				#
   6727  1.1.6.2  bouyer #		Exit.							#
   6728  1.1.6.2  bouyer #									#
   6729  1.1.6.2  bouyer #	3. If |X| > 1, go to 5.						#
   6730  1.1.6.2  bouyer #									#
   6731  1.1.6.2  bouyer #	4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit.	#
   6732  1.1.6.2  bouyer #									#
   6733  1.1.6.2  bouyer #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   6734  1.1.6.2  bouyer #		Exit.							#
   6735  1.1.6.2  bouyer #									#
   6736  1.1.6.2  bouyer #########################################################################
   6737  1.1.6.2  bouyer 
   6738  1.1.6.2  bouyer 	global		sacos
   6739  1.1.6.2  bouyer sacos:
   6740  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   6741  1.1.6.2  bouyer 
   6742  1.1.6.2  bouyer 	mov.l		(%a0),%d1		# pack exp w/ upper 16 fraction
   6743  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   6744  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   6745  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   6746  1.1.6.2  bouyer 	bge.b		ACOSBIG
   6747  1.1.6.2  bouyer 
   6748  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| < 1
   6749  1.1.6.2  bouyer #--ACOS(X) = 2 * ATAN(	SQRT( (1-X)/(1+X) ) )
   6750  1.1.6.2  bouyer 
   6751  1.1.6.2  bouyer ACOSMAIN:
   6752  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp1
   6753  1.1.6.2  bouyer 	fadd.x		%fp0,%fp1		# 1+X
   6754  1.1.6.2  bouyer 	fneg.x		%fp0			# -X
   6755  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp0	# 1-X
   6756  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# (1-X)/(1+X)
   6757  1.1.6.2  bouyer 	fsqrt.x		%fp0			# SQRT((1-X)/(1+X))
   6758  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save original users fpcr
   6759  1.1.6.2  bouyer 	clr.l		%d0
   6760  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save SQRT(...) to stack
   6761  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to sqrt
   6762  1.1.6.2  bouyer 	bsr		satan			# ATAN(SQRT([1-X]/[1+X]))
   6763  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear SQRT(...) from stack
   6764  1.1.6.2  bouyer 
   6765  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr		# restore users round prec,mode
   6766  1.1.6.2  bouyer 	fadd.x		%fp0,%fp0		# 2 * ATAN( STUFF )
   6767  1.1.6.2  bouyer 	bra		t_pinx2
   6768  1.1.6.2  bouyer 
   6769  1.1.6.2  bouyer ACOSBIG:
   6770  1.1.6.2  bouyer 	fabs.x		%fp0
   6771  1.1.6.2  bouyer 	fcmp.s		%fp0,&0x3F800000
   6772  1.1.6.2  bouyer 	fbgt		t_operr			# cause an operr exception
   6773  1.1.6.2  bouyer 
   6774  1.1.6.2  bouyer #--|X| = 1, ACOS(X) = 0 OR PI
   6775  1.1.6.2  bouyer 	tst.b		(%a0)			# is X positive or negative?
   6776  1.1.6.2  bouyer 	bpl.b		ACOSP1
   6777  1.1.6.2  bouyer 
   6778  1.1.6.2  bouyer #--X = -1
   6779  1.1.6.2  bouyer #Returns PI and inexact exception
   6780  1.1.6.2  bouyer ACOSM1:
   6781  1.1.6.2  bouyer 	fmov.x		PI(%pc),%fp0		# load PI
   6782  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# load round mode,prec
   6783  1.1.6.2  bouyer 	fadd.s		&0x00800000,%fp0	# add a small value
   6784  1.1.6.2  bouyer 	bra		t_pinx2
   6785  1.1.6.2  bouyer 
   6786  1.1.6.2  bouyer ACOSP1:
   6787  1.1.6.2  bouyer 	bra		ld_pzero		# answer is positive zero
   6788  1.1.6.2  bouyer 
   6789  1.1.6.2  bouyer 	global		sacosd
   6790  1.1.6.2  bouyer #--ACOS(X) = PI/2 FOR DENORMALIZED X
   6791  1.1.6.2  bouyer sacosd:
   6792  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# load user's rnd mode/prec
   6793  1.1.6.2  bouyer 	fmov.x		PIBY2(%pc),%fp0
   6794  1.1.6.2  bouyer 	bra		t_pinx2
   6795  1.1.6.2  bouyer 
   6796  1.1.6.2  bouyer #########################################################################
   6797  1.1.6.2  bouyer # setox():    computes the exponential for a normalized input		#
   6798  1.1.6.2  bouyer # setoxd():   computes the exponential for a denormalized input		#
   6799  1.1.6.2  bouyer # setoxm1():  computes the exponential minus 1 for a normalized input	#
   6800  1.1.6.2  bouyer # setoxm1d(): computes the exponential minus 1 for a denormalized input	#
   6801  1.1.6.2  bouyer #									#
   6802  1.1.6.2  bouyer # INPUT	*************************************************************** #
   6803  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   6804  1.1.6.2  bouyer #	d0 = round precision,mode					#
   6805  1.1.6.2  bouyer #									#
   6806  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   6807  1.1.6.2  bouyer #	fp0 = exp(X) or exp(X)-1					#
   6808  1.1.6.2  bouyer #									#
   6809  1.1.6.2  bouyer # ACCURACY and MONOTONICITY ******************************************* #
   6810  1.1.6.2  bouyer #	The returned result is within 0.85 ulps in 64 significant bit, 	#
   6811  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   6812  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic 	#
   6813  1.1.6.2  bouyer #	in double precision.						#
   6814  1.1.6.2  bouyer #									#
   6815  1.1.6.2  bouyer # ALGORITHM and IMPLEMENTATION **************************************** #
   6816  1.1.6.2  bouyer #									#
   6817  1.1.6.2  bouyer #	setoxd								#
   6818  1.1.6.2  bouyer #	------								#
   6819  1.1.6.2  bouyer #	Step 1.	Set ans := 1.0						#
   6820  1.1.6.2  bouyer #									#
   6821  1.1.6.2  bouyer #	Step 2.	Return	ans := ans + sign(X)*2^(-126). Exit.		#
   6822  1.1.6.2  bouyer #	Notes:	This will always generate one exception -- inexact.	#
   6823  1.1.6.2  bouyer #									#
   6824  1.1.6.2  bouyer #									#
   6825  1.1.6.2  bouyer #	setox								#
   6826  1.1.6.2  bouyer #	-----								#
   6827  1.1.6.2  bouyer #									#
   6828  1.1.6.2  bouyer #	Step 1.	Filter out extreme cases of input argument.		#
   6829  1.1.6.2  bouyer #		1.1	If |X| >= 2^(-65), go to Step 1.3.		#
   6830  1.1.6.2  bouyer #		1.2	Go to Step 7.					#
   6831  1.1.6.2  bouyer #		1.3	If |X| < 16380 log(2), go to Step 2.		#
   6832  1.1.6.2  bouyer #		1.4	Go to Step 8.					#
   6833  1.1.6.2  bouyer #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
   6834  1.1.6.2  bouyer #		To avoid the use of floating-point comparisons, a	#
   6835  1.1.6.2  bouyer #		compact representation of |X| is used. This format is a	#
   6836  1.1.6.2  bouyer #		32-bit integer, the upper (more significant) 16 bits 	#
   6837  1.1.6.2  bouyer #		are the sign and biased exponent field of |X|; the 	#
   6838  1.1.6.2  bouyer #		lower 16 bits are the 16 most significant fraction	#
   6839  1.1.6.2  bouyer #		(including the explicit bit) bits of |X|. Consequently,	#
   6840  1.1.6.2  bouyer #		the comparisons in Steps 1.1 and 1.3 can be performed	#
   6841  1.1.6.2  bouyer #		by integer comparison. Note also that the constant	#
   6842  1.1.6.2  bouyer #		16380 log(2) used in Step 1.3 is also in the compact	#
   6843  1.1.6.2  bouyer #		form. Thus taking the branch to Step 2 guarantees 	#
   6844  1.1.6.2  bouyer #		|X| < 16380 log(2). There is no harm to have a small	#
   6845  1.1.6.2  bouyer #		number of cases where |X| is less than,	but close to,	#
   6846  1.1.6.2  bouyer #		16380 log(2) and the branch to Step 9 is taken.		#
   6847  1.1.6.2  bouyer #									#
   6848  1.1.6.2  bouyer #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
   6849  1.1.6.2  bouyer #		2.1	Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
   6850  1.1.6.2  bouyer #			was taken)					#
   6851  1.1.6.2  bouyer #		2.2	N := round-to-nearest-integer( X * 64/log2 ).	#
   6852  1.1.6.2  bouyer #		2.3	Calculate	J = N mod 64; so J = 0,1,2,..., #
   6853  1.1.6.2  bouyer #			or 63.						#
   6854  1.1.6.2  bouyer #		2.4	Calculate	M = (N - J)/64; so N = 64M + J.	#
   6855  1.1.6.2  bouyer #		2.5	Calculate the address of the stored value of 	#
   6856  1.1.6.2  bouyer #			2^(J/64).					#
   6857  1.1.6.2  bouyer #		2.6	Create the value Scale = 2^M.			#
   6858  1.1.6.2  bouyer #	Notes:	The calculation in 2.2 is really performed by		#
   6859  1.1.6.2  bouyer #			Z := X * constant				#
   6860  1.1.6.2  bouyer #			N := round-to-nearest-integer(Z)		#
   6861  1.1.6.2  bouyer #		where							#
   6862  1.1.6.2  bouyer #			constant := single-precision( 64/log 2 ).	#
   6863  1.1.6.2  bouyer #									#
   6864  1.1.6.2  bouyer #		Using a single-precision constant avoids memory 	#
   6865  1.1.6.2  bouyer #		access. Another effect of using a single-precision	#
   6866  1.1.6.2  bouyer #		"constant" is that the calculated value Z is 		#
   6867  1.1.6.2  bouyer #									#
   6868  1.1.6.2  bouyer #			Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24).	#
   6869  1.1.6.2  bouyer #									#
   6870  1.1.6.2  bouyer #		This error has to be considered later in Steps 3 and 4.	#
   6871  1.1.6.2  bouyer #									#
   6872  1.1.6.2  bouyer #	Step 3.	Calculate X - N*log2/64.				#
   6873  1.1.6.2  bouyer #		3.1	R := X + N*L1, 					#
   6874  1.1.6.2  bouyer #				where L1 := single-precision(-log2/64).	#
   6875  1.1.6.2  bouyer #		3.2	R := R + N*L2, 					#
   6876  1.1.6.2  bouyer #				L2 := extended-precision(-log2/64 - L1).#
   6877  1.1.6.2  bouyer #	Notes:	a) The way L1 and L2 are chosen ensures L1+L2 		#
   6878  1.1.6.2  bouyer #		approximate the value -log2/64 to 88 bits of accuracy.	#
   6879  1.1.6.2  bouyer #		b) N*L1 is exact because N is no longer than 22 bits	#
   6880  1.1.6.2  bouyer #		and L1 is no longer than 24 bits.			#
   6881  1.1.6.2  bouyer #		c) The calculation X+N*L1 is also exact due to 		#
   6882  1.1.6.2  bouyer #		cancellation. Thus, R is practically X+N(L1+L2) to full	#
   6883  1.1.6.2  bouyer #		64 bits. 						#
   6884  1.1.6.2  bouyer #		d) It is important to estimate how large can |R| be	#
   6885  1.1.6.2  bouyer #		after Step 3.2.						#
   6886  1.1.6.2  bouyer #									#
   6887  1.1.6.2  bouyer #		N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24)	#
   6888  1.1.6.2  bouyer #		X*64/log2 (1+eps)	=	N + f,	|f| <= 0.5	#
   6889  1.1.6.2  bouyer #		X*64/log2 - N	=	f - eps*X 64/log2		#
   6890  1.1.6.2  bouyer #		X - N*log2/64	=	f*log2/64 - eps*X		#
   6891  1.1.6.2  bouyer #									#
   6892  1.1.6.2  bouyer #									#
   6893  1.1.6.2  bouyer #		Now |X| <= 16446 log2, thus				#
   6894  1.1.6.2  bouyer #									#
   6895  1.1.6.2  bouyer #			|X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64	#
   6896  1.1.6.2  bouyer #					<= 0.57 log2/64.		#
   6897  1.1.6.2  bouyer #		 This bound will be used in Step 4.			#
   6898  1.1.6.2  bouyer #									#
   6899  1.1.6.2  bouyer #	Step 4.	Approximate exp(R)-1 by a polynomial			#
   6900  1.1.6.2  bouyer #		p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))	#
   6901  1.1.6.2  bouyer #	Notes:	a) In order to reduce memory access, the coefficients 	#
   6902  1.1.6.2  bouyer #		are made as "short" as possible: A1 (which is 1/2), A4	#
   6903  1.1.6.2  bouyer #		and A5 are single precision; A2 and A3 are double	#
   6904  1.1.6.2  bouyer #		precision. 						#
   6905  1.1.6.2  bouyer #		b) Even with the restrictions above, 			#
   6906  1.1.6.2  bouyer #		   |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062.	#
   6907  1.1.6.2  bouyer #		Note that 0.0062 is slightly bigger than 0.57 log2/64.	#
   6908  1.1.6.2  bouyer #		c) To fully utilize the pipeline, p is separated into	#
   6909  1.1.6.2  bouyer #		two independent pieces of roughly equal complexities	#
   6910  1.1.6.2  bouyer #			p = [ R + R*S*(A2 + S*A4) ]	+		#
   6911  1.1.6.2  bouyer #				[ S*(A1 + S*(A3 + S*A5)) ]		#
   6912  1.1.6.2  bouyer #		where S = R*R.						#
   6913  1.1.6.2  bouyer #									#
   6914  1.1.6.2  bouyer #	Step 5.	Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by		#
   6915  1.1.6.2  bouyer #				ans := T + ( T*p + t)			#
   6916  1.1.6.2  bouyer #		where T and t are the stored values for 2^(J/64).	#
   6917  1.1.6.2  bouyer #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
   6918  1.1.6.2  bouyer #		2^(J/64) to roughly 85 bits; T is in extended precision	#
   6919  1.1.6.2  bouyer #		and t is in single precision. Note also that T is 	#
   6920  1.1.6.2  bouyer #		rounded to 62 bits so that the last two bits of T are 	#
   6921  1.1.6.2  bouyer #		zero. The reason for such a special form is that T-1, 	#
   6922  1.1.6.2  bouyer #		T-2, and T-8 will all be exact --- a property that will	#
   6923  1.1.6.2  bouyer #		give much more accurate computation of the function 	#
   6924  1.1.6.2  bouyer #		EXPM1.							#
   6925  1.1.6.2  bouyer #									#
   6926  1.1.6.2  bouyer #	Step 6.	Reconstruction of exp(X)				#
   6927  1.1.6.2  bouyer #			exp(X) = 2^M * 2^(J/64) * exp(R).		#
   6928  1.1.6.2  bouyer #		6.1	If AdjFlag = 0, go to 6.3			#
   6929  1.1.6.2  bouyer #		6.2	ans := ans * AdjScale				#
   6930  1.1.6.2  bouyer #		6.3	Restore the user FPCR				#
   6931  1.1.6.2  bouyer #		6.4	Return ans := ans * Scale. Exit.		#
   6932  1.1.6.2  bouyer #	Notes:	If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R,	#
   6933  1.1.6.2  bouyer #		|M| <= 16380, and Scale = 2^M. Moreover, exp(X) will	#
   6934  1.1.6.2  bouyer #		neither overflow nor underflow. If AdjFlag = 1, that	#
   6935  1.1.6.2  bouyer #		means that						#
   6936  1.1.6.2  bouyer #			X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380.	#
   6937  1.1.6.2  bouyer #		Hence, exp(X) may overflow or underflow or neither.	#
   6938  1.1.6.2  bouyer #		When that is the case, AdjScale = 2^(M1) where M1 is	#
   6939  1.1.6.2  bouyer #		approximately M. Thus 6.2 will never cause 		#
   6940  1.1.6.2  bouyer #		over/underflow. Possible exception in 6.4 is overflow	#
   6941  1.1.6.2  bouyer #		or underflow. The inexact exception is not generated in	#
   6942  1.1.6.2  bouyer #		6.4. Although one can argue that the inexact flag	#
   6943  1.1.6.2  bouyer #		should always be raised, to simulate that exception 	#
   6944  1.1.6.2  bouyer #		cost to much than the flag is worth in practical uses.	#
   6945  1.1.6.2  bouyer #									#
   6946  1.1.6.2  bouyer #	Step 7.	Return 1 + X.						#
   6947  1.1.6.2  bouyer #		7.1	ans := X					#
   6948  1.1.6.2  bouyer #		7.2	Restore user FPCR.				#
   6949  1.1.6.2  bouyer #		7.3	Return ans := 1 + ans. Exit			#
   6950  1.1.6.2  bouyer #	Notes:	For non-zero X, the inexact exception will always be	#
   6951  1.1.6.2  bouyer #		raised by 7.3. That is the only exception raised by 7.3.#
   6952  1.1.6.2  bouyer #		Note also that we use the FMOVEM instruction to move X	#
   6953  1.1.6.2  bouyer #		in Step 7.1 to avoid unnecessary trapping. (Although	#
   6954  1.1.6.2  bouyer #		the FMOVEM may not seem relevant since X is normalized,	#
   6955  1.1.6.2  bouyer #		the precaution will be useful in the library version of	#
   6956  1.1.6.2  bouyer #		this code where the separate entry for denormalized 	#
   6957  1.1.6.2  bouyer #		inputs will be done away with.)				#
   6958  1.1.6.2  bouyer #									#
   6959  1.1.6.2  bouyer #	Step 8.	Handle exp(X) where |X| >= 16380log2.			#
   6960  1.1.6.2  bouyer #		8.1	If |X| > 16480 log2, go to Step 9.		#
   6961  1.1.6.2  bouyer #		(mimic 2.2 - 2.6)					#
   6962  1.1.6.2  bouyer #		8.2	N := round-to-integer( X * 64/log2 )		#
   6963  1.1.6.2  bouyer #		8.3	Calculate J = N mod 64, J = 0,1,...,63		#
   6964  1.1.6.2  bouyer #		8.4	K := (N-J)/64, M1 := truncate(K/2), M = K-M1, 	#
   6965  1.1.6.2  bouyer #			AdjFlag := 1.					#
   6966  1.1.6.2  bouyer #		8.5	Calculate the address of the stored value 	#
   6967  1.1.6.2  bouyer #			2^(J/64).					#
   6968  1.1.6.2  bouyer #		8.6	Create the values Scale = 2^M, AdjScale = 2^M1.	#
   6969  1.1.6.2  bouyer #		8.7	Go to Step 3.					#
   6970  1.1.6.2  bouyer #	Notes:	Refer to notes for 2.2 - 2.6.				#
   6971  1.1.6.2  bouyer #									#
   6972  1.1.6.2  bouyer #	Step 9.	Handle exp(X), |X| > 16480 log2.			#
   6973  1.1.6.2  bouyer #		9.1	If X < 0, go to 9.3				#
   6974  1.1.6.2  bouyer #		9.2	ans := Huge, go to 9.4				#
   6975  1.1.6.2  bouyer #		9.3	ans := Tiny.					#
   6976  1.1.6.2  bouyer #		9.4	Restore user FPCR.				#
   6977  1.1.6.2  bouyer #		9.5	Return ans := ans * ans. Exit.			#
   6978  1.1.6.2  bouyer #	Notes:	Exp(X) will surely overflow or underflow, depending on	#
   6979  1.1.6.2  bouyer #		X's sign. "Huge" and "Tiny" are respectively large/tiny	#
   6980  1.1.6.2  bouyer #		extended-precision numbers whose square over/underflow	#
   6981  1.1.6.2  bouyer #		with an inexact result. Thus, 9.5 always raises the	#
   6982  1.1.6.2  bouyer #		inexact together with either overflow or underflow.	#
   6983  1.1.6.2  bouyer #									#
   6984  1.1.6.2  bouyer #	setoxm1d							#
   6985  1.1.6.2  bouyer #	--------							#
   6986  1.1.6.2  bouyer #									#
   6987  1.1.6.2  bouyer #	Step 1.	Set ans := 0						#
   6988  1.1.6.2  bouyer #									#
   6989  1.1.6.2  bouyer #	Step 2.	Return	ans := X + ans. Exit.				#
   6990  1.1.6.2  bouyer #	Notes:	This will return X with the appropriate rounding	#
   6991  1.1.6.2  bouyer #		 precision prescribed by the user FPCR.			#
   6992  1.1.6.2  bouyer #									#
   6993  1.1.6.2  bouyer #	setoxm1								#
   6994  1.1.6.2  bouyer #	-------								#
   6995  1.1.6.2  bouyer #									#
   6996  1.1.6.2  bouyer #	Step 1.	Check |X|						#
   6997  1.1.6.2  bouyer #		1.1	If |X| >= 1/4, go to Step 1.3.			#
   6998  1.1.6.2  bouyer #		1.2	Go to Step 7.					#
   6999  1.1.6.2  bouyer #		1.3	If |X| < 70 log(2), go to Step 2.		#
   7000  1.1.6.2  bouyer #		1.4	Go to Step 10.					#
   7001  1.1.6.2  bouyer #	Notes:	The usual case should take the branches 1.1 -> 1.3 -> 2.#
   7002  1.1.6.2  bouyer #		However, it is conceivable |X| can be small very often	#
   7003  1.1.6.2  bouyer #		because EXPM1 is intended to evaluate exp(X)-1 		#
   7004  1.1.6.2  bouyer #		accurately when |X| is small. For further details on 	#
   7005  1.1.6.2  bouyer #		the comparisons, see the notes on Step 1 of setox.	#
   7006  1.1.6.2  bouyer #									#
   7007  1.1.6.2  bouyer #	Step 2.	Calculate N = round-to-nearest-int( X * 64/log2 ).	#
   7008  1.1.6.2  bouyer #		2.1	N := round-to-nearest-integer( X * 64/log2 ).	#
   7009  1.1.6.2  bouyer #		2.2	Calculate	J = N mod 64; so J = 0,1,2,..., #
   7010  1.1.6.2  bouyer #			or 63.						#
   7011  1.1.6.2  bouyer #		2.3	Calculate	M = (N - J)/64; so N = 64M + J.	#
   7012  1.1.6.2  bouyer #		2.4	Calculate the address of the stored value of 	#
   7013  1.1.6.2  bouyer #			2^(J/64).					#
   7014  1.1.6.2  bouyer #		2.5	Create the values Sc = 2^M and 			#
   7015  1.1.6.2  bouyer #			OnebySc := -2^(-M).				#
   7016  1.1.6.2  bouyer #	Notes:	See the notes on Step 2 of setox.			#
   7017  1.1.6.2  bouyer #									#
   7018  1.1.6.2  bouyer #	Step 3.	Calculate X - N*log2/64.				#
   7019  1.1.6.2  bouyer #		3.1	R := X + N*L1, 					#
   7020  1.1.6.2  bouyer #				where L1 := single-precision(-log2/64).	#
   7021  1.1.6.2  bouyer #		3.2	R := R + N*L2, 					#
   7022  1.1.6.2  bouyer #				L2 := extended-precision(-log2/64 - L1).#
   7023  1.1.6.2  bouyer #	Notes:	Applying the analysis of Step 3 of setox in this case	#
   7024  1.1.6.2  bouyer #		shows that |R| <= 0.0055 (note that |X| <= 70 log2 in	#
   7025  1.1.6.2  bouyer #		this case).						#
   7026  1.1.6.2  bouyer #									#
   7027  1.1.6.2  bouyer #	Step 4.	Approximate exp(R)-1 by a polynomial			#
   7028  1.1.6.2  bouyer #			p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6)))))	#
   7029  1.1.6.2  bouyer #	Notes:	a) In order to reduce memory access, the coefficients 	#
   7030  1.1.6.2  bouyer #		are made as "short" as possible: A1 (which is 1/2), A5 	#
   7031  1.1.6.2  bouyer #		and A6 are single precision; A2, A3 and A4 are double 	#
   7032  1.1.6.2  bouyer #		precision. 						#
   7033  1.1.6.2  bouyer #		b) Even with the restriction above,			#
   7034  1.1.6.2  bouyer #			|p - (exp(R)-1)| <	|R| * 2^(-72.7)		#
   7035  1.1.6.2  bouyer #		for all |R| <= 0.0055.					#
   7036  1.1.6.2  bouyer #		c) To fully utilize the pipeline, p is separated into	#
   7037  1.1.6.2  bouyer #		two independent pieces of roughly equal complexity	#
   7038  1.1.6.2  bouyer #			p = [ R*S*(A2 + S*(A4 + S*A6)) ]	+	#
   7039  1.1.6.2  bouyer #				[ R + S*(A1 + S*(A3 + S*A5)) ]		#
   7040  1.1.6.2  bouyer #		where S = R*R.						#
   7041  1.1.6.2  bouyer #									#
   7042  1.1.6.2  bouyer #	Step 5.	Compute 2^(J/64)*p by					#
   7043  1.1.6.2  bouyer #				p := T*p				#
   7044  1.1.6.2  bouyer #		where T and t are the stored values for 2^(J/64).	#
   7045  1.1.6.2  bouyer #	Notes:	2^(J/64) is stored as T and t where T+t approximates	#
   7046  1.1.6.2  bouyer #		2^(J/64) to roughly 85 bits; T is in extended precision	#
   7047  1.1.6.2  bouyer #		and t is in single precision. Note also that T is 	#
   7048  1.1.6.2  bouyer #		rounded to 62 bits so that the last two bits of T are 	#
   7049  1.1.6.2  bouyer #		zero. The reason for such a special form is that T-1, 	#
   7050  1.1.6.2  bouyer #		T-2, and T-8 will all be exact --- a property that will	#
   7051  1.1.6.2  bouyer #		be exploited in Step 6 below. The total relative error	#
   7052  1.1.6.2  bouyer #		in p is no bigger than 2^(-67.7) compared to the final	#
   7053  1.1.6.2  bouyer #		result.							#
   7054  1.1.6.2  bouyer #									#
   7055  1.1.6.2  bouyer #	Step 6.	Reconstruction of exp(X)-1				#
   7056  1.1.6.2  bouyer #			exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ).	#
   7057  1.1.6.2  bouyer #		6.1	If M <= 63, go to Step 6.3.			#
   7058  1.1.6.2  bouyer #		6.2	ans := T + (p + (t + OnebySc)). Go to 6.6	#
   7059  1.1.6.2  bouyer #		6.3	If M >= -3, go to 6.5.				#
   7060  1.1.6.2  bouyer #		6.4	ans := (T + (p + t)) + OnebySc. Go to 6.6	#
   7061  1.1.6.2  bouyer #		6.5	ans := (T + OnebySc) + (p + t).			#
   7062  1.1.6.2  bouyer #		6.6	Restore user FPCR.				#
   7063  1.1.6.2  bouyer #		6.7	Return ans := Sc * ans. Exit.			#
   7064  1.1.6.2  bouyer #	Notes:	The various arrangements of the expressions give 	#
   7065  1.1.6.2  bouyer #		accurate evaluations.					#
   7066  1.1.6.2  bouyer #									#
   7067  1.1.6.2  bouyer #	Step 7.	exp(X)-1 for |X| < 1/4.					#
   7068  1.1.6.2  bouyer #		7.1	If |X| >= 2^(-65), go to Step 9.		#
   7069  1.1.6.2  bouyer #		7.2	Go to Step 8.					#
   7070  1.1.6.2  bouyer #									#
   7071  1.1.6.2  bouyer #	Step 8.	Calculate exp(X)-1, |X| < 2^(-65).			#
   7072  1.1.6.2  bouyer #		8.1	If |X| < 2^(-16312), goto 8.3			#
   7073  1.1.6.2  bouyer #		8.2	Restore FPCR; return ans := X - 2^(-16382).	#
   7074  1.1.6.2  bouyer #			Exit.						#
   7075  1.1.6.2  bouyer #		8.3	X := X * 2^(140).				#
   7076  1.1.6.2  bouyer #		8.4	Restore FPCR; ans := ans - 2^(-16382).		#
   7077  1.1.6.2  bouyer #		 Return ans := ans*2^(140). Exit			#
   7078  1.1.6.2  bouyer #	Notes:	The idea is to return "X - tiny" under the user		#
   7079  1.1.6.2  bouyer #		precision and rounding modes. To avoid unnecessary	#
   7080  1.1.6.2  bouyer #		inefficiency, we stay away from denormalized numbers 	#
   7081  1.1.6.2  bouyer #		the best we can. For |X| >= 2^(-16312), the 		#
   7082  1.1.6.2  bouyer #		straightforward 8.2 generates the inexact exception as	#
   7083  1.1.6.2  bouyer #		the case warrants.					#
   7084  1.1.6.2  bouyer #									#
   7085  1.1.6.2  bouyer #	Step 9.	Calculate exp(X)-1, |X| < 1/4, by a polynomial		#
   7086  1.1.6.2  bouyer #			p = X + X*X*(B1 + X*(B2 + ... + X*B12))		#
   7087  1.1.6.2  bouyer #	Notes:	a) In order to reduce memory access, the coefficients	#
   7088  1.1.6.2  bouyer #		are made as "short" as possible: B1 (which is 1/2), B9	#
   7089  1.1.6.2  bouyer #		to B12 are single precision; B3 to B8 are double 	#
   7090  1.1.6.2  bouyer #		precision; and B2 is double extended.			#
   7091  1.1.6.2  bouyer #		b) Even with the restriction above,			#
   7092  1.1.6.2  bouyer #			|p - (exp(X)-1)| < |X| 2^(-70.6)		#
   7093  1.1.6.2  bouyer #		for all |X| <= 0.251.					#
   7094  1.1.6.2  bouyer #		Note that 0.251 is slightly bigger than 1/4.		#
   7095  1.1.6.2  bouyer #		c) To fully preserve accuracy, the polynomial is 	#
   7096  1.1.6.2  bouyer #		computed as						#
   7097  1.1.6.2  bouyer #			X + ( S*B1 +	Q ) where S = X*X and		#
   7098  1.1.6.2  bouyer #			Q	=	X*S*(B2 + X*(B3 + ... + X*B12))	#
   7099  1.1.6.2  bouyer #		d) To fully utilize the pipeline, Q is separated into	#
   7100  1.1.6.2  bouyer #		two independent pieces of roughly equal complexity	#
   7101  1.1.6.2  bouyer #			Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] +	#
   7102  1.1.6.2  bouyer #				[ S*S*(B3 + S*(B5 + ... + S*B11)) ]	#
   7103  1.1.6.2  bouyer #									#
   7104  1.1.6.2  bouyer #	Step 10. Calculate exp(X)-1 for |X| >= 70 log 2.		#
   7105  1.1.6.2  bouyer #		10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all 	#
   7106  1.1.6.2  bouyer #		practical purposes. Therefore, go to Step 1 of setox.	#
   7107  1.1.6.2  bouyer #		10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical	#
   7108  1.1.6.2  bouyer #		purposes. 						#
   7109  1.1.6.2  bouyer #		ans := -1 						#
   7110  1.1.6.2  bouyer #		Restore user FPCR					#
   7111  1.1.6.2  bouyer #		Return ans := ans + 2^(-126). Exit.			#
   7112  1.1.6.2  bouyer #	Notes:	10.2 will always create an inexact and return -1 + tiny	#
   7113  1.1.6.2  bouyer #		in the user rounding precision and mode.		#
   7114  1.1.6.2  bouyer #									#
   7115  1.1.6.2  bouyer #########################################################################
   7116  1.1.6.2  bouyer 
   7117  1.1.6.2  bouyer L2:	long		0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
   7118  1.1.6.2  bouyer 
   7119  1.1.6.2  bouyer EEXPA3:	long		0x3FA55555,0x55554CC1
   7120  1.1.6.2  bouyer EEXPA2:	long		0x3FC55555,0x55554A54
   7121  1.1.6.2  bouyer 
   7122  1.1.6.2  bouyer EM1A4:	long		0x3F811111,0x11174385
   7123  1.1.6.2  bouyer EM1A3:	long		0x3FA55555,0x55554F5A
   7124  1.1.6.2  bouyer 
   7125  1.1.6.2  bouyer EM1A2:	long		0x3FC55555,0x55555555,0x00000000,0x00000000
   7126  1.1.6.2  bouyer 
   7127  1.1.6.2  bouyer EM1B8:	long		0x3EC71DE3,0xA5774682
   7128  1.1.6.2  bouyer EM1B7:	long		0x3EFA01A0,0x19D7CB68
   7129  1.1.6.2  bouyer 
   7130  1.1.6.2  bouyer EM1B6:	long		0x3F2A01A0,0x1A019DF3
   7131  1.1.6.2  bouyer EM1B5:	long		0x3F56C16C,0x16C170E2
   7132  1.1.6.2  bouyer 
   7133  1.1.6.2  bouyer EM1B4:	long		0x3F811111,0x11111111
   7134  1.1.6.2  bouyer EM1B3:	long		0x3FA55555,0x55555555
   7135  1.1.6.2  bouyer 
   7136  1.1.6.2  bouyer EM1B2:	long		0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
   7137  1.1.6.2  bouyer 	long		0x00000000
   7138  1.1.6.2  bouyer 
   7139  1.1.6.2  bouyer TWO140:	long		0x48B00000,0x00000000
   7140  1.1.6.2  bouyer TWON140:
   7141  1.1.6.2  bouyer 	long		0x37300000,0x00000000
   7142  1.1.6.2  bouyer 
   7143  1.1.6.2  bouyer EEXPTBL:
   7144  1.1.6.2  bouyer 	long		0x3FFF0000,0x80000000,0x00000000,0x00000000
   7145  1.1.6.2  bouyer 	long		0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
   7146  1.1.6.2  bouyer 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
   7147  1.1.6.2  bouyer 	long		0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
   7148  1.1.6.2  bouyer 	long		0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
   7149  1.1.6.2  bouyer 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
   7150  1.1.6.2  bouyer 	long		0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
   7151  1.1.6.2  bouyer 	long		0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
   7152  1.1.6.2  bouyer 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
   7153  1.1.6.2  bouyer 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
   7154  1.1.6.2  bouyer 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
   7155  1.1.6.2  bouyer 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
   7156  1.1.6.2  bouyer 	long		0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
   7157  1.1.6.2  bouyer 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
   7158  1.1.6.2  bouyer 	long		0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
   7159  1.1.6.2  bouyer 	long		0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
   7160  1.1.6.2  bouyer 	long		0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
   7161  1.1.6.2  bouyer 	long		0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
   7162  1.1.6.2  bouyer 	long		0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
   7163  1.1.6.2  bouyer 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
   7164  1.1.6.2  bouyer 	long		0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
   7165  1.1.6.2  bouyer 	long		0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
   7166  1.1.6.2  bouyer 	long		0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
   7167  1.1.6.2  bouyer 	long		0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
   7168  1.1.6.2  bouyer 	long		0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
   7169  1.1.6.2  bouyer 	long		0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
   7170  1.1.6.2  bouyer 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
   7171  1.1.6.2  bouyer 	long		0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
   7172  1.1.6.2  bouyer 	long		0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
   7173  1.1.6.2  bouyer 	long		0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
   7174  1.1.6.2  bouyer 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
   7175  1.1.6.2  bouyer 	long		0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
   7176  1.1.6.2  bouyer 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
   7177  1.1.6.2  bouyer 	long		0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
   7178  1.1.6.2  bouyer 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
   7179  1.1.6.2  bouyer 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
   7180  1.1.6.2  bouyer 	long		0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
   7181  1.1.6.2  bouyer 	long		0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
   7182  1.1.6.2  bouyer 	long		0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
   7183  1.1.6.2  bouyer 	long		0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
   7184  1.1.6.2  bouyer 	long		0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
   7185  1.1.6.2  bouyer 	long		0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
   7186  1.1.6.2  bouyer 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
   7187  1.1.6.2  bouyer 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
   7188  1.1.6.2  bouyer 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
   7189  1.1.6.2  bouyer 	long		0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
   7190  1.1.6.2  bouyer 	long		0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
   7191  1.1.6.2  bouyer 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
   7192  1.1.6.2  bouyer 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
   7193  1.1.6.2  bouyer 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
   7194  1.1.6.2  bouyer 	long		0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
   7195  1.1.6.2  bouyer 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
   7196  1.1.6.2  bouyer 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
   7197  1.1.6.2  bouyer 	long		0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
   7198  1.1.6.2  bouyer 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
   7199  1.1.6.2  bouyer 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
   7200  1.1.6.2  bouyer 	long		0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
   7201  1.1.6.2  bouyer 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
   7202  1.1.6.2  bouyer 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
   7203  1.1.6.2  bouyer 	long		0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
   7204  1.1.6.2  bouyer 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
   7205  1.1.6.2  bouyer 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
   7206  1.1.6.2  bouyer 	long		0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
   7207  1.1.6.2  bouyer 	long		0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
   7208  1.1.6.2  bouyer 
   7209  1.1.6.2  bouyer 	set		ADJFLAG,L_SCR2
   7210  1.1.6.2  bouyer 	set		SCALE,FP_SCR0
   7211  1.1.6.2  bouyer 	set		ADJSCALE,FP_SCR1
   7212  1.1.6.2  bouyer 	set		SC,FP_SCR0
   7213  1.1.6.2  bouyer 	set		ONEBYSC,FP_SCR1
   7214  1.1.6.2  bouyer 
   7215  1.1.6.2  bouyer 	global		setox
   7216  1.1.6.2  bouyer setox:
   7217  1.1.6.2  bouyer #--entry point for EXP(X), here X is finite, non-zero, and not NaN's
   7218  1.1.6.2  bouyer 
   7219  1.1.6.2  bouyer #--Step 1.
   7220  1.1.6.2  bouyer 	mov.l		(%a0),%d1		# load part of input X
   7221  1.1.6.2  bouyer 	and.l		&0x7FFF0000,%d1		# biased expo. of X
   7222  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
   7223  1.1.6.2  bouyer 	bge.b		EXPC1			# normal case
   7224  1.1.6.2  bouyer 	bra		EXPSM
   7225  1.1.6.2  bouyer 
   7226  1.1.6.2  bouyer EXPC1:
   7227  1.1.6.2  bouyer #--The case |X| >= 2^(-65)
   7228  1.1.6.2  bouyer 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
   7229  1.1.6.2  bouyer 	cmp.l		%d1,&0x400CB167		# 16380 log2 trunc. 16 bits
   7230  1.1.6.2  bouyer 	blt.b		EXPMAIN			# normal case
   7231  1.1.6.2  bouyer 	bra		EEXPBIG
   7232  1.1.6.2  bouyer 
   7233  1.1.6.2  bouyer EXPMAIN:
   7234  1.1.6.2  bouyer #--Step 2.
   7235  1.1.6.2  bouyer #--This is the normal branch:	2^(-65) <= |X| < 16380 log2.
   7236  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# load input from (a0)
   7237  1.1.6.2  bouyer 
   7238  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   7239  1.1.6.2  bouyer 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7240  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7241  1.1.6.2  bouyer 	mov.l		&0,ADJFLAG(%a6)
   7242  1.1.6.2  bouyer 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7243  1.1.6.2  bouyer 	lea		EEXPTBL(%pc),%a1
   7244  1.1.6.2  bouyer 	fmov.l		%d1,%fp0		# convert to floating-format
   7245  1.1.6.2  bouyer 
   7246  1.1.6.2  bouyer 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7247  1.1.6.2  bouyer 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7248  1.1.6.2  bouyer 	lsl.l		&4,%d1
   7249  1.1.6.2  bouyer 	add.l		%d1,%a1			# address of 2^(J/64)
   7250  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d1
   7251  1.1.6.2  bouyer 	asr.l		&6,%d1			# D0 is M
   7252  1.1.6.2  bouyer 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
   7253  1.1.6.2  bouyer 	mov.w		L2(%pc),L_SCR1(%a6)	# prefetch L2, no need in CB
   7254  1.1.6.2  bouyer 
   7255  1.1.6.2  bouyer EXPCONT1:
   7256  1.1.6.2  bouyer #--Step 3.
   7257  1.1.6.2  bouyer #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
   7258  1.1.6.2  bouyer #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
   7259  1.1.6.2  bouyer 	fmov.x		%fp0,%fp2
   7260  1.1.6.2  bouyer 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
   7261  1.1.6.2  bouyer 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
   7262  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# X + N*L1
   7263  1.1.6.2  bouyer 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
   7264  1.1.6.2  bouyer 
   7265  1.1.6.2  bouyer #--Step 4.
   7266  1.1.6.2  bouyer #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
   7267  1.1.6.2  bouyer #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
   7268  1.1.6.2  bouyer #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
   7269  1.1.6.2  bouyer #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
   7270  1.1.6.2  bouyer 
   7271  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   7272  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
   7273  1.1.6.2  bouyer 
   7274  1.1.6.2  bouyer 	fmov.s		&0x3AB60B70,%fp2	# fp2 IS A5
   7275  1.1.6.2  bouyer 
   7276  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# fp2 IS S*A5
   7277  1.1.6.2  bouyer 	fmov.x		%fp1,%fp3
   7278  1.1.6.2  bouyer 	fmul.s		&0x3C088895,%fp3	# fp3 IS S*A4
   7279  1.1.6.2  bouyer 
   7280  1.1.6.2  bouyer 	fadd.d		EEXPA3(%pc),%fp2	# fp2 IS A3+S*A5
   7281  1.1.6.2  bouyer 	fadd.d		EEXPA2(%pc),%fp3	# fp3 IS A2+S*A4
   7282  1.1.6.2  bouyer 
   7283  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# fp2 IS S*(A3+S*A5)
   7284  1.1.6.2  bouyer 	mov.w		%d1,SCALE(%a6)		# SCALE is 2^(M) in extended
   7285  1.1.6.2  bouyer 	mov.l		&0x80000000,SCALE+4(%a6)
   7286  1.1.6.2  bouyer 	clr.l		SCALE+8(%a6)
   7287  1.1.6.2  bouyer 
   7288  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# fp3 IS S*(A2+S*A4)
   7289  1.1.6.2  bouyer 
   7290  1.1.6.2  bouyer 	fadd.s		&0x3F000000,%fp2	# fp2 IS A1+S*(A3+S*A5)
   7291  1.1.6.2  bouyer 	fmul.x		%fp0,%fp3		# fp3 IS R*S*(A2+S*A4)
   7292  1.1.6.2  bouyer 
   7293  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# fp2 IS S*(A1+S*(A3+S*A5))
   7294  1.1.6.2  bouyer 	fadd.x		%fp3,%fp0		# fp0 IS R+R*S*(A2+S*A4),
   7295  1.1.6.2  bouyer 
   7296  1.1.6.2  bouyer 	fmov.x		(%a1)+,%fp1		# fp1 is lead. pt. of 2^(J/64)
   7297  1.1.6.2  bouyer 	fadd.x		%fp2,%fp0		# fp0 is EXP(R) - 1
   7298  1.1.6.2  bouyer 
   7299  1.1.6.2  bouyer #--Step 5
   7300  1.1.6.2  bouyer #--final reconstruction process
   7301  1.1.6.2  bouyer #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
   7302  1.1.6.2  bouyer 
   7303  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0		# 2^(J/64)*(Exp(R)-1)
   7304  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7305  1.1.6.2  bouyer 	fadd.s		(%a1),%fp0		# accurate 2^(J/64)
   7306  1.1.6.2  bouyer 
   7307  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# 2^(J/64) + 2^(J/64)*...
   7308  1.1.6.2  bouyer 	mov.l		ADJFLAG(%a6),%d1
   7309  1.1.6.2  bouyer 
   7310  1.1.6.2  bouyer #--Step 6
   7311  1.1.6.2  bouyer 	tst.l		%d1
   7312  1.1.6.2  bouyer 	beq.b		NORMAL
   7313  1.1.6.2  bouyer ADJUST:
   7314  1.1.6.2  bouyer 	fmul.x		ADJSCALE(%a6),%fp0
   7315  1.1.6.2  bouyer NORMAL:
   7316  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore user FPCR
   7317  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7318  1.1.6.2  bouyer 	fmul.x		SCALE(%a6),%fp0		# multiply 2^(M)
   7319  1.1.6.2  bouyer 	bra		t_catch
   7320  1.1.6.2  bouyer 
   7321  1.1.6.2  bouyer EXPSM:
   7322  1.1.6.2  bouyer #--Step 7
   7323  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# load X
   7324  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7325  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp0	# 1+X in user mode
   7326  1.1.6.2  bouyer 	bra		t_pinx2
   7327  1.1.6.2  bouyer 
   7328  1.1.6.2  bouyer EEXPBIG:
   7329  1.1.6.2  bouyer #--Step 8
   7330  1.1.6.2  bouyer 	cmp.l		%d1,&0x400CB27C		# 16480 log2
   7331  1.1.6.2  bouyer 	bgt.b		EXP2BIG
   7332  1.1.6.2  bouyer #--Steps 8.2 -- 8.6
   7333  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# load input from (a0)
   7334  1.1.6.2  bouyer 
   7335  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   7336  1.1.6.2  bouyer 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7337  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7338  1.1.6.2  bouyer 	mov.l		&1,ADJFLAG(%a6)
   7339  1.1.6.2  bouyer 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7340  1.1.6.2  bouyer 	lea		EEXPTBL(%pc),%a1
   7341  1.1.6.2  bouyer 	fmov.l		%d1,%fp0		# convert to floating-format
   7342  1.1.6.2  bouyer 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7343  1.1.6.2  bouyer 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7344  1.1.6.2  bouyer 	lsl.l		&4,%d1
   7345  1.1.6.2  bouyer 	add.l		%d1,%a1			# address of 2^(J/64)
   7346  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d1
   7347  1.1.6.2  bouyer 	asr.l		&6,%d1			# D0 is K
   7348  1.1.6.2  bouyer 	mov.l		%d1,L_SCR1(%a6)		# save K temporarily
   7349  1.1.6.2  bouyer 	asr.l		&1,%d1			# D0 is M1
   7350  1.1.6.2  bouyer 	sub.l		%d1,L_SCR1(%a6)		# a1 is M
   7351  1.1.6.2  bouyer 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M1)
   7352  1.1.6.2  bouyer 	mov.w		%d1,ADJSCALE(%a6)	# ADJSCALE := 2^(M1)
   7353  1.1.6.2  bouyer 	mov.l		&0x80000000,ADJSCALE+4(%a6)
   7354  1.1.6.2  bouyer 	clr.l		ADJSCALE+8(%a6)
   7355  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d1		# D0 is M
   7356  1.1.6.2  bouyer 	add.w		&0x3FFF,%d1		# biased expo. of 2^(M)
   7357  1.1.6.2  bouyer 	bra.w		EXPCONT1		# go back to Step 3
   7358  1.1.6.2  bouyer 
   7359  1.1.6.2  bouyer EXP2BIG:
   7360  1.1.6.2  bouyer #--Step 9
   7361  1.1.6.2  bouyer 	tst.b		(%a0)			# is X positive or negative?
   7362  1.1.6.2  bouyer 	bmi		t_unfl2
   7363  1.1.6.2  bouyer 	bra		t_ovfl2
   7364  1.1.6.2  bouyer 
   7365  1.1.6.2  bouyer 	global		setoxd
   7366  1.1.6.2  bouyer setoxd:
   7367  1.1.6.2  bouyer #--entry point for EXP(X), X is denormalized
   7368  1.1.6.2  bouyer 	mov.l		(%a0),-(%sp)
   7369  1.1.6.2  bouyer 	andi.l		&0x80000000,(%sp)
   7370  1.1.6.2  bouyer 	ori.l		&0x00800000,(%sp)	# sign(X)*2^(-126)
   7371  1.1.6.2  bouyer 
   7372  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp0
   7373  1.1.6.2  bouyer 
   7374  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7375  1.1.6.2  bouyer 	fadd.s		(%sp)+,%fp0
   7376  1.1.6.2  bouyer 	bra		t_pinx2
   7377  1.1.6.2  bouyer 
   7378  1.1.6.2  bouyer 	global		setoxm1
   7379  1.1.6.2  bouyer setoxm1:
   7380  1.1.6.2  bouyer #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
   7381  1.1.6.2  bouyer 
   7382  1.1.6.2  bouyer #--Step 1.
   7383  1.1.6.2  bouyer #--Step 1.1
   7384  1.1.6.2  bouyer 	mov.l		(%a0),%d1		# load part of input X
   7385  1.1.6.2  bouyer 	and.l		&0x7FFF0000,%d1		# biased expo. of X
   7386  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFD0000		# 1/4
   7387  1.1.6.2  bouyer 	bge.b		EM1CON1			# |X| >= 1/4
   7388  1.1.6.2  bouyer 	bra		EM1SM
   7389  1.1.6.2  bouyer 
   7390  1.1.6.2  bouyer EM1CON1:
   7391  1.1.6.2  bouyer #--Step 1.3
   7392  1.1.6.2  bouyer #--The case |X| >= 1/4
   7393  1.1.6.2  bouyer 	mov.w		4(%a0),%d1		# expo. and partial sig. of |X|
   7394  1.1.6.2  bouyer 	cmp.l		%d1,&0x4004C215		# 70log2 rounded up to 16 bits
   7395  1.1.6.2  bouyer 	ble.b		EM1MAIN			# 1/4 <= |X| <= 70log2
   7396  1.1.6.2  bouyer 	bra		EM1BIG
   7397  1.1.6.2  bouyer 
   7398  1.1.6.2  bouyer EM1MAIN:
   7399  1.1.6.2  bouyer #--Step 2.
   7400  1.1.6.2  bouyer #--This is the case:	1/4 <= |X| <= 70 log2.
   7401  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# load input from (a0)
   7402  1.1.6.2  bouyer 
   7403  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   7404  1.1.6.2  bouyer 	fmul.s		&0x42B8AA3B,%fp0	# 64/log2 * X
   7405  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7406  1.1.6.2  bouyer 	fmov.l		%fp0,%d1		# N = int( X * 64/log2 )
   7407  1.1.6.2  bouyer 	lea		EEXPTBL(%pc),%a1
   7408  1.1.6.2  bouyer 	fmov.l		%d1,%fp0		# convert to floating-format
   7409  1.1.6.2  bouyer 
   7410  1.1.6.2  bouyer 	mov.l		%d1,L_SCR1(%a6)		# save N temporarily
   7411  1.1.6.2  bouyer 	and.l		&0x3F,%d1		# D0 is J = N mod 64
   7412  1.1.6.2  bouyer 	lsl.l		&4,%d1
   7413  1.1.6.2  bouyer 	add.l		%d1,%a1			# address of 2^(J/64)
   7414  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d1
   7415  1.1.6.2  bouyer 	asr.l		&6,%d1			# D0 is M
   7416  1.1.6.2  bouyer 	mov.l		%d1,L_SCR1(%a6)		# save a copy of M
   7417  1.1.6.2  bouyer 
   7418  1.1.6.2  bouyer #--Step 3.
   7419  1.1.6.2  bouyer #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
   7420  1.1.6.2  bouyer #--a0 points to 2^(J/64), D0 and a1 both contain M
   7421  1.1.6.2  bouyer 	fmov.x		%fp0,%fp2
   7422  1.1.6.2  bouyer 	fmul.s		&0xBC317218,%fp0	# N * L1, L1 = lead(-log2/64)
   7423  1.1.6.2  bouyer 	fmul.x		L2(%pc),%fp2		# N * L2, L1+L2 = -log2/64
   7424  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# X + N*L1
   7425  1.1.6.2  bouyer 	fadd.x		%fp2,%fp0		# fp0 is R, reduced arg.
   7426  1.1.6.2  bouyer 	add.w		&0x3FFF,%d1		# D0 is biased expo. of 2^M
   7427  1.1.6.2  bouyer 
   7428  1.1.6.2  bouyer #--Step 4.
   7429  1.1.6.2  bouyer #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
   7430  1.1.6.2  bouyer #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
   7431  1.1.6.2  bouyer #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
   7432  1.1.6.2  bouyer #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
   7433  1.1.6.2  bouyer 
   7434  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   7435  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# fp1 IS S = R*R
   7436  1.1.6.2  bouyer 
   7437  1.1.6.2  bouyer 	fmov.s		&0x3950097B,%fp2	# fp2 IS a6
   7438  1.1.6.2  bouyer 
   7439  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# fp2 IS S*A6
   7440  1.1.6.2  bouyer 	fmov.x		%fp1,%fp3
   7441  1.1.6.2  bouyer 	fmul.s		&0x3AB60B6A,%fp3	# fp3 IS S*A5
   7442  1.1.6.2  bouyer 
   7443  1.1.6.2  bouyer 	fadd.d		EM1A4(%pc),%fp2		# fp2 IS A4+S*A6
   7444  1.1.6.2  bouyer 	fadd.d		EM1A3(%pc),%fp3		# fp3 IS A3+S*A5
   7445  1.1.6.2  bouyer 	mov.w		%d1,SC(%a6)		# SC is 2^(M) in extended
   7446  1.1.6.2  bouyer 	mov.l		&0x80000000,SC+4(%a6)
   7447  1.1.6.2  bouyer 	clr.l		SC+8(%a6)
   7448  1.1.6.2  bouyer 
   7449  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# fp2 IS S*(A4+S*A6)
   7450  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d1		# D0 is	M
   7451  1.1.6.2  bouyer 	neg.w		%d1			# D0 is -M
   7452  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# fp3 IS S*(A3+S*A5)
   7453  1.1.6.2  bouyer 	add.w		&0x3FFF,%d1		# biased expo. of 2^(-M)
   7454  1.1.6.2  bouyer 	fadd.d		EM1A2(%pc),%fp2		# fp2 IS A2+S*(A4+S*A6)
   7455  1.1.6.2  bouyer 	fadd.s		&0x3F000000,%fp3	# fp3 IS A1+S*(A3+S*A5)
   7456  1.1.6.2  bouyer 
   7457  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# fp2 IS S*(A2+S*(A4+S*A6))
   7458  1.1.6.2  bouyer 	or.w		&0x8000,%d1		# signed/expo. of -2^(-M)
   7459  1.1.6.2  bouyer 	mov.w		%d1,ONEBYSC(%a6)	# OnebySc is -2^(-M)
   7460  1.1.6.2  bouyer 	mov.l		&0x80000000,ONEBYSC+4(%a6)
   7461  1.1.6.2  bouyer 	clr.l		ONEBYSC+8(%a6)
   7462  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# fp1 IS S*(A1+S*(A3+S*A5))
   7463  1.1.6.2  bouyer 
   7464  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# fp2 IS R*S*(A2+S*(A4+S*A6))
   7465  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# fp0 IS R+S*(A1+S*(A3+S*A5))
   7466  1.1.6.2  bouyer 
   7467  1.1.6.2  bouyer 	fadd.x		%fp2,%fp0		# fp0 IS EXP(R)-1
   7468  1.1.6.2  bouyer 
   7469  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7470  1.1.6.2  bouyer 
   7471  1.1.6.2  bouyer #--Step 5
   7472  1.1.6.2  bouyer #--Compute 2^(J/64)*p
   7473  1.1.6.2  bouyer 
   7474  1.1.6.2  bouyer 	fmul.x		(%a1),%fp0		# 2^(J/64)*(Exp(R)-1)
   7475  1.1.6.2  bouyer 
   7476  1.1.6.2  bouyer #--Step 6
   7477  1.1.6.2  bouyer #--Step 6.1
   7478  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d1		# retrieve M
   7479  1.1.6.2  bouyer 	cmp.l		%d1,&63
   7480  1.1.6.2  bouyer 	ble.b		MLE63
   7481  1.1.6.2  bouyer #--Step 6.2	M >= 64
   7482  1.1.6.2  bouyer 	fmov.s		12(%a1),%fp1		# fp1 is t
   7483  1.1.6.2  bouyer 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is t+OnebySc
   7484  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# p+(t+OnebySc), fp1 released
   7485  1.1.6.2  bouyer 	fadd.x		(%a1),%fp0		# T+(p+(t+OnebySc))
   7486  1.1.6.2  bouyer 	bra		EM1SCALE
   7487  1.1.6.2  bouyer MLE63:
   7488  1.1.6.2  bouyer #--Step 6.3	M <= 63
   7489  1.1.6.2  bouyer 	cmp.l		%d1,&-3
   7490  1.1.6.2  bouyer 	bge.b		MGEN3
   7491  1.1.6.2  bouyer MLTN3:
   7492  1.1.6.2  bouyer #--Step 6.4	M <= -4
   7493  1.1.6.2  bouyer 	fadd.s		12(%a1),%fp0		# p+t
   7494  1.1.6.2  bouyer 	fadd.x		(%a1),%fp0		# T+(p+t)
   7495  1.1.6.2  bouyer 	fadd.x		ONEBYSC(%a6),%fp0	# OnebySc + (T+(p+t))
   7496  1.1.6.2  bouyer 	bra		EM1SCALE
   7497  1.1.6.2  bouyer MGEN3:
   7498  1.1.6.2  bouyer #--Step 6.5	-3 <= M <= 63
   7499  1.1.6.2  bouyer 	fmov.x		(%a1)+,%fp1		# fp1 is T
   7500  1.1.6.2  bouyer 	fadd.s		(%a1),%fp0		# fp0 is p+t
   7501  1.1.6.2  bouyer 	fadd.x		ONEBYSC(%a6),%fp1	# fp1 is T+OnebySc
   7502  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# (T+OnebySc)+(p+t)
   7503  1.1.6.2  bouyer 
   7504  1.1.6.2  bouyer EM1SCALE:
   7505  1.1.6.2  bouyer #--Step 6.6
   7506  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7507  1.1.6.2  bouyer 	fmul.x		SC(%a6),%fp0
   7508  1.1.6.2  bouyer 	bra		t_inx2
   7509  1.1.6.2  bouyer 
   7510  1.1.6.2  bouyer EM1SM:
   7511  1.1.6.2  bouyer #--Step 7	|X| < 1/4.
   7512  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FBE0000		# 2^(-65)
   7513  1.1.6.2  bouyer 	bge.b		EM1POLY
   7514  1.1.6.2  bouyer 
   7515  1.1.6.2  bouyer EM1TINY:
   7516  1.1.6.2  bouyer #--Step 8	|X| < 2^(-65)
   7517  1.1.6.2  bouyer 	cmp.l		%d1,&0x00330000		# 2^(-16312)
   7518  1.1.6.2  bouyer 	blt.b		EM12TINY
   7519  1.1.6.2  bouyer #--Step 8.2
   7520  1.1.6.2  bouyer 	mov.l		&0x80010000,SC(%a6)	# SC is -2^(-16382)
   7521  1.1.6.2  bouyer 	mov.l		&0x80000000,SC+4(%a6)
   7522  1.1.6.2  bouyer 	clr.l		SC+8(%a6)
   7523  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0
   7524  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7525  1.1.6.2  bouyer 	mov.b		&FADD_OP,%d1		# last inst is ADD
   7526  1.1.6.2  bouyer 	fadd.x		SC(%a6),%fp0
   7527  1.1.6.2  bouyer 	bra		t_catch
   7528  1.1.6.2  bouyer 
   7529  1.1.6.2  bouyer EM12TINY:
   7530  1.1.6.2  bouyer #--Step 8.3
   7531  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0
   7532  1.1.6.2  bouyer 	fmul.d		TWO140(%pc),%fp0
   7533  1.1.6.2  bouyer 	mov.l		&0x80010000,SC(%a6)
   7534  1.1.6.2  bouyer 	mov.l		&0x80000000,SC+4(%a6)
   7535  1.1.6.2  bouyer 	clr.l		SC+8(%a6)
   7536  1.1.6.2  bouyer 	fadd.x		SC(%a6),%fp0
   7537  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7538  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7539  1.1.6.2  bouyer 	fmul.d		TWON140(%pc),%fp0
   7540  1.1.6.2  bouyer 	bra		t_catch
   7541  1.1.6.2  bouyer 
   7542  1.1.6.2  bouyer EM1POLY:
   7543  1.1.6.2  bouyer #--Step 9	exp(X)-1 by a simple polynomial
   7544  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# fp0 is X
   7545  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# fp0 is S := X*X
   7546  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# save fp2 {%fp2/%fp3}
   7547  1.1.6.2  bouyer 	fmov.s		&0x2F30CAA8,%fp1	# fp1 is B12
   7548  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# fp1 is S*B12
   7549  1.1.6.2  bouyer 	fmov.s		&0x310F8290,%fp2	# fp2 is B11
   7550  1.1.6.2  bouyer 	fadd.s		&0x32D73220,%fp1	# fp1 is B10+S*B12
   7551  1.1.6.2  bouyer 
   7552  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# fp2 is S*B11
   7553  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# fp1 is S*(B10 + ...
   7554  1.1.6.2  bouyer 
   7555  1.1.6.2  bouyer 	fadd.s		&0x3493F281,%fp2	# fp2 is B9+S*...
   7556  1.1.6.2  bouyer 	fadd.d		EM1B8(%pc),%fp1		# fp1 is B8+S*...
   7557  1.1.6.2  bouyer 
   7558  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# fp2 is S*(B9+...
   7559  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# fp1 is S*(B8+...
   7560  1.1.6.2  bouyer 
   7561  1.1.6.2  bouyer 	fadd.d		EM1B7(%pc),%fp2		# fp2 is B7+S*...
   7562  1.1.6.2  bouyer 	fadd.d		EM1B6(%pc),%fp1		# fp1 is B6+S*...
   7563  1.1.6.2  bouyer 
   7564  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# fp2 is S*(B7+...
   7565  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# fp1 is S*(B6+...
   7566  1.1.6.2  bouyer 
   7567  1.1.6.2  bouyer 	fadd.d		EM1B5(%pc),%fp2		# fp2 is B5+S*...
   7568  1.1.6.2  bouyer 	fadd.d		EM1B4(%pc),%fp1		# fp1 is B4+S*...
   7569  1.1.6.2  bouyer 
   7570  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# fp2 is S*(B5+...
   7571  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# fp1 is S*(B4+...
   7572  1.1.6.2  bouyer 
   7573  1.1.6.2  bouyer 	fadd.d		EM1B3(%pc),%fp2		# fp2 is B3+S*...
   7574  1.1.6.2  bouyer 	fadd.x		EM1B2(%pc),%fp1		# fp1 is B2+S*...
   7575  1.1.6.2  bouyer 
   7576  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# fp2 is S*(B3+...
   7577  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# fp1 is S*(B2+...
   7578  1.1.6.2  bouyer 
   7579  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# fp2 is S*S*(B3+...)
   7580  1.1.6.2  bouyer 	fmul.x		(%a0),%fp1		# fp1 is X*S*(B2...
   7581  1.1.6.2  bouyer 
   7582  1.1.6.2  bouyer 	fmul.s		&0x3F000000,%fp0	# fp0 is S*B1
   7583  1.1.6.2  bouyer 	fadd.x		%fp2,%fp1		# fp1 is Q
   7584  1.1.6.2  bouyer 
   7585  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# fp2 restored {%fp2/%fp3}
   7586  1.1.6.2  bouyer 
   7587  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# fp0 is S*B1+Q
   7588  1.1.6.2  bouyer 
   7589  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7590  1.1.6.2  bouyer 	fadd.x		(%a0),%fp0
   7591  1.1.6.2  bouyer 	bra		t_inx2
   7592  1.1.6.2  bouyer 
   7593  1.1.6.2  bouyer EM1BIG:
   7594  1.1.6.2  bouyer #--Step 10	|X| > 70 log2
   7595  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   7596  1.1.6.2  bouyer 	cmp.l		%d1,&0
   7597  1.1.6.2  bouyer 	bgt.w		EXPC1
   7598  1.1.6.2  bouyer #--Step 10.2
   7599  1.1.6.2  bouyer 	fmov.s		&0xBF800000,%fp0	# fp0 is -1
   7600  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7601  1.1.6.2  bouyer 	fadd.s		&0x00800000,%fp0	# -1 + 2^(-126)
   7602  1.1.6.2  bouyer 	bra		t_minx2
   7603  1.1.6.2  bouyer 
   7604  1.1.6.2  bouyer 	global		setoxm1d
   7605  1.1.6.2  bouyer setoxm1d:
   7606  1.1.6.2  bouyer #--entry point for EXPM1(X), here X is denormalized
   7607  1.1.6.2  bouyer #--Step 0.
   7608  1.1.6.2  bouyer 	bra		t_extdnrm
   7609  1.1.6.2  bouyer 
   7610  1.1.6.2  bouyer #########################################################################
   7611  1.1.6.2  bouyer # sgetexp():  returns the exponent portion of the input argument.	#
   7612  1.1.6.2  bouyer #	      The exponent bias is removed and the exponent value is	#
   7613  1.1.6.2  bouyer #	      returned as an extended precision number in fp0.		#
   7614  1.1.6.2  bouyer # sgetexpd(): handles denormalized numbers. 				#
   7615  1.1.6.2  bouyer #									#
   7616  1.1.6.2  bouyer # sgetman():  extracts the mantissa of the input argument. The 		#
   7617  1.1.6.2  bouyer #	      mantissa is converted to an extended precision number w/ 	#
   7618  1.1.6.2  bouyer #	      an exponent of $3fff and is returned in fp0. The range of #
   7619  1.1.6.2  bouyer #	      the result is [1.0 - 2.0).				#
   7620  1.1.6.2  bouyer # sgetmand(): handles denormalized numbers.				#
   7621  1.1.6.2  bouyer #									#
   7622  1.1.6.2  bouyer # INPUT *************************************************************** #
   7623  1.1.6.2  bouyer #	a0  = pointer to extended precision input			#
   7624  1.1.6.2  bouyer #									#
   7625  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   7626  1.1.6.2  bouyer #	fp0 = exponent(X) or mantissa(X)				#
   7627  1.1.6.2  bouyer #									#
   7628  1.1.6.2  bouyer #########################################################################
   7629  1.1.6.2  bouyer 
   7630  1.1.6.2  bouyer 	global		sgetexp
   7631  1.1.6.2  bouyer sgetexp:
   7632  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0		# get the exponent
   7633  1.1.6.2  bouyer 	bclr		&0xf,%d0		# clear the sign bit
   7634  1.1.6.2  bouyer 	subi.w		&0x3fff,%d0		# subtract off the bias
   7635  1.1.6.2  bouyer 	fmov.w		%d0,%fp0		# return exp in fp0
   7636  1.1.6.2  bouyer 	blt.b		sgetexpn		# it's negative
   7637  1.1.6.2  bouyer 	rts
   7638  1.1.6.2  bouyer 
   7639  1.1.6.2  bouyer sgetexpn:
   7640  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7641  1.1.6.2  bouyer 	rts
   7642  1.1.6.2  bouyer 
   7643  1.1.6.2  bouyer 	global		sgetexpd
   7644  1.1.6.2  bouyer sgetexpd:
   7645  1.1.6.2  bouyer 	bsr.l		norm			# normalize
   7646  1.1.6.2  bouyer 	neg.w		%d0			# new exp = -(shft amt)
   7647  1.1.6.2  bouyer 	subi.w		&0x3fff,%d0		# subtract off the bias
   7648  1.1.6.2  bouyer 	fmov.w		%d0,%fp0		# return exp in fp0
   7649  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7650  1.1.6.2  bouyer 	rts
   7651  1.1.6.2  bouyer 
   7652  1.1.6.2  bouyer 	global		sgetman
   7653  1.1.6.2  bouyer sgetman:
   7654  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0		# get the exp
   7655  1.1.6.2  bouyer 	ori.w		&0x7fff,%d0		# clear old exp
   7656  1.1.6.2  bouyer 	bclr		&0xe,%d0		# make it the new exp +-3fff
   7657  1.1.6.2  bouyer 
   7658  1.1.6.2  bouyer # here, we build the result in a tmp location so as not to disturb the input
   7659  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
   7660  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
   7661  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   7662  1.1.6.2  bouyer 	fmov.x		FP_SCR0(%a6),%fp0	# put new value back in fp0
   7663  1.1.6.2  bouyer 	bmi.b		sgetmann		# it's negative
   7664  1.1.6.2  bouyer 	rts
   7665  1.1.6.2  bouyer 
   7666  1.1.6.2  bouyer sgetmann:
   7667  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   7668  1.1.6.2  bouyer 	rts
   7669  1.1.6.2  bouyer 
   7670  1.1.6.2  bouyer #
   7671  1.1.6.2  bouyer # For denormalized numbers, shift the mantissa until the j-bit = 1,
   7672  1.1.6.2  bouyer # then load the exponent with +/1 $3fff.
   7673  1.1.6.2  bouyer #
   7674  1.1.6.2  bouyer 	global		sgetmand
   7675  1.1.6.2  bouyer sgetmand:
   7676  1.1.6.2  bouyer 	bsr.l		norm			# normalize exponent
   7677  1.1.6.2  bouyer 	bra.b		sgetman
   7678  1.1.6.2  bouyer 
   7679  1.1.6.2  bouyer #########################################################################
   7680  1.1.6.2  bouyer # scosh():  computes the hyperbolic cosine of a normalized input	#
   7681  1.1.6.2  bouyer # scoshd(): computes the hyperbolic cosine of a denormalized input	#
   7682  1.1.6.2  bouyer #									#
   7683  1.1.6.2  bouyer # INPUT ***************************************************************	#
   7684  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   7685  1.1.6.2  bouyer #	d0 = round precision,mode					#
   7686  1.1.6.2  bouyer #									#
   7687  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   7688  1.1.6.2  bouyer #	fp0 = cosh(X)							#
   7689  1.1.6.2  bouyer #									#
   7690  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   7691  1.1.6.2  bouyer #	The returned result is within 3 ulps in 64 significant bit, 	#
   7692  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   7693  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic 	#
   7694  1.1.6.2  bouyer #	in double precision.						#
   7695  1.1.6.2  bouyer #									#
   7696  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   7697  1.1.6.2  bouyer #									#
   7698  1.1.6.2  bouyer #	COSH								#
   7699  1.1.6.2  bouyer #	1. If |X| > 16380 log2, go to 3.				#
   7700  1.1.6.2  bouyer #									#
   7701  1.1.6.2  bouyer #	2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae	#
   7702  1.1.6.2  bouyer #		y = |X|, z = exp(Y), and				#
   7703  1.1.6.2  bouyer #		cosh(X) = (1/2)*( z + 1/z ).				#
   7704  1.1.6.2  bouyer #		Exit.							#
   7705  1.1.6.2  bouyer #									#
   7706  1.1.6.2  bouyer #	3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5.		#
   7707  1.1.6.2  bouyer #									#
   7708  1.1.6.2  bouyer #	4. (16380 log2 < |X| <= 16480 log2)				#
   7709  1.1.6.2  bouyer #		cosh(X) = sign(X) * exp(|X|)/2.				#
   7710  1.1.6.2  bouyer #		However, invoking exp(|X|) may cause premature 		#
   7711  1.1.6.2  bouyer #		overflow. Thus, we calculate sinh(X) as follows:	#
   7712  1.1.6.2  bouyer #		Y	:= |X|						#
   7713  1.1.6.2  bouyer #		Fact	:=	2**(16380)				#
   7714  1.1.6.2  bouyer #		Y'	:= Y - 16381 log2				#
   7715  1.1.6.2  bouyer #		cosh(X) := Fact * exp(Y').				#
   7716  1.1.6.2  bouyer #		Exit.							#
   7717  1.1.6.2  bouyer #									#
   7718  1.1.6.2  bouyer #	5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
   7719  1.1.6.2  bouyer #		Huge*Huge to generate overflow and an infinity with	#
   7720  1.1.6.2  bouyer #		the appropriate sign. Huge is the largest finite number	#
   7721  1.1.6.2  bouyer #		in extended format. Exit.				#
   7722  1.1.6.2  bouyer #									#
   7723  1.1.6.2  bouyer #########################################################################
   7724  1.1.6.2  bouyer 
   7725  1.1.6.2  bouyer TWO16380:
   7726  1.1.6.2  bouyer 	long		0x7FFB0000,0x80000000,0x00000000,0x00000000
   7727  1.1.6.2  bouyer 
   7728  1.1.6.2  bouyer 	global		scosh
   7729  1.1.6.2  bouyer scosh:
   7730  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7731  1.1.6.2  bouyer 
   7732  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   7733  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   7734  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   7735  1.1.6.2  bouyer 	cmp.l		%d1,&0x400CB167
   7736  1.1.6.2  bouyer 	bgt.b		COSHBIG
   7737  1.1.6.2  bouyer 
   7738  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
   7739  1.1.6.2  bouyer #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
   7740  1.1.6.2  bouyer 
   7741  1.1.6.2  bouyer 	fabs.x		%fp0			# |X|
   7742  1.1.6.2  bouyer 
   7743  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   7744  1.1.6.2  bouyer 	clr.l		%d0
   7745  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save |X| to stack
   7746  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to |X|
   7747  1.1.6.2  bouyer 	bsr		setox			# FP0 IS EXP(|X|)
   7748  1.1.6.2  bouyer 	add.l		&0xc,%sp		# erase |X| from stack
   7749  1.1.6.2  bouyer 	fmul.s		&0x3F000000,%fp0	# (1/2)EXP(|X|)
   7750  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   7751  1.1.6.2  bouyer 
   7752  1.1.6.2  bouyer 	fmov.s		&0x3E800000,%fp1	# (1/4)
   7753  1.1.6.2  bouyer 	fdiv.x		%fp0,%fp1		# 1/(2 EXP(|X|))
   7754  1.1.6.2  bouyer 
   7755  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7756  1.1.6.2  bouyer 	mov.b		&FADD_OP,%d1		# last inst is ADD
   7757  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0
   7758  1.1.6.2  bouyer 	bra		t_catch
   7759  1.1.6.2  bouyer 
   7760  1.1.6.2  bouyer COSHBIG:
   7761  1.1.6.2  bouyer 	cmp.l		%d1,&0x400CB2B3
   7762  1.1.6.2  bouyer 	bgt.b		COSHHUGE
   7763  1.1.6.2  bouyer 
   7764  1.1.6.2  bouyer 	fabs.x		%fp0
   7765  1.1.6.2  bouyer 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
   7766  1.1.6.2  bouyer 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
   7767  1.1.6.2  bouyer 
   7768  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   7769  1.1.6.2  bouyer 	clr.l		%d0
   7770  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save fp0 to stack
   7771  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to fp0
   7772  1.1.6.2  bouyer 	bsr		setox
   7773  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear fp0 from stack
   7774  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   7775  1.1.6.2  bouyer 
   7776  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7777  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7778  1.1.6.2  bouyer 	fmul.x		TWO16380(%pc),%fp0
   7779  1.1.6.2  bouyer 	bra		t_catch
   7780  1.1.6.2  bouyer 
   7781  1.1.6.2  bouyer COSHHUGE:
   7782  1.1.6.2  bouyer 	bra		t_ovfl2
   7783  1.1.6.2  bouyer 
   7784  1.1.6.2  bouyer 	global		scoshd
   7785  1.1.6.2  bouyer #--COSH(X) = 1 FOR DENORMALIZED X
   7786  1.1.6.2  bouyer scoshd:
   7787  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp0
   7788  1.1.6.2  bouyer 
   7789  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7790  1.1.6.2  bouyer 	fadd.s		&0x00800000,%fp0
   7791  1.1.6.2  bouyer 	bra		t_pinx2
   7792  1.1.6.2  bouyer 
   7793  1.1.6.2  bouyer #########################################################################
   7794  1.1.6.2  bouyer # ssinh():  computes the hyperbolic sine of a normalized input		#
   7795  1.1.6.2  bouyer # ssinhd(): computes the hyperbolic sine of a denormalized input	#
   7796  1.1.6.2  bouyer #									#
   7797  1.1.6.2  bouyer # INPUT *************************************************************** #
   7798  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   7799  1.1.6.2  bouyer #	d0 = round precision,mode					#
   7800  1.1.6.2  bouyer #									#
   7801  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   7802  1.1.6.2  bouyer #	fp0 = sinh(X)							#
   7803  1.1.6.2  bouyer #									#
   7804  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   7805  1.1.6.2  bouyer #	The returned result is within 3 ulps in 64 significant bit, 	#
   7806  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   7807  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   7808  1.1.6.2  bouyer #	in double precision.						#
   7809  1.1.6.2  bouyer #									#
   7810  1.1.6.2  bouyer # ALGORITHM *********************************************************** #
   7811  1.1.6.2  bouyer #									#
   7812  1.1.6.2  bouyer #       SINH								#
   7813  1.1.6.2  bouyer #       1. If |X| > 16380 log2, go to 3.				#
   7814  1.1.6.2  bouyer #									#
   7815  1.1.6.2  bouyer #       2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula	#
   7816  1.1.6.2  bouyer #               y = |X|, sgn = sign(X), and z = expm1(Y),		#
   7817  1.1.6.2  bouyer #               sinh(X) = sgn*(1/2)*( z + z/(1+z) ).			#
   7818  1.1.6.2  bouyer #          Exit.							#
   7819  1.1.6.2  bouyer #									#
   7820  1.1.6.2  bouyer #       3. If |X| > 16480 log2, go to 5.				#
   7821  1.1.6.2  bouyer #									#
   7822  1.1.6.2  bouyer #       4. (16380 log2 < |X| <= 16480 log2)				#
   7823  1.1.6.2  bouyer #               sinh(X) = sign(X) * exp(|X|)/2.				#
   7824  1.1.6.2  bouyer #          However, invoking exp(|X|) may cause premature overflow.	#
   7825  1.1.6.2  bouyer #          Thus, we calculate sinh(X) as follows:			#
   7826  1.1.6.2  bouyer #             Y       := |X|						#
   7827  1.1.6.2  bouyer #             sgn     := sign(X)					#
   7828  1.1.6.2  bouyer #             sgnFact := sgn * 2**(16380)				#
   7829  1.1.6.2  bouyer #             Y'      := Y - 16381 log2					#
   7830  1.1.6.2  bouyer #             sinh(X) := sgnFact * exp(Y').				#
   7831  1.1.6.2  bouyer #          Exit.							#
   7832  1.1.6.2  bouyer #									#
   7833  1.1.6.2  bouyer #       5. (|X| > 16480 log2) sinh(X) must overflow. Return		#
   7834  1.1.6.2  bouyer #          sign(X)*Huge*Huge to generate overflow and an infinity with	#
   7835  1.1.6.2  bouyer #          the appropriate sign. Huge is the largest finite number in	#
   7836  1.1.6.2  bouyer #          extended format. Exit.					#
   7837  1.1.6.2  bouyer #									#
   7838  1.1.6.2  bouyer #########################################################################
   7839  1.1.6.2  bouyer 
   7840  1.1.6.2  bouyer 	global		ssinh
   7841  1.1.6.2  bouyer ssinh:
   7842  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7843  1.1.6.2  bouyer 
   7844  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   7845  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   7846  1.1.6.2  bouyer 	mov.l		%d1,%a1			# save (compacted) operand
   7847  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   7848  1.1.6.2  bouyer 	cmp.l		%d1,&0x400CB167
   7849  1.1.6.2  bouyer 	bgt.b		SINHBIG
   7850  1.1.6.2  bouyer 
   7851  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
   7852  1.1.6.2  bouyer #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
   7853  1.1.6.2  bouyer 
   7854  1.1.6.2  bouyer 	fabs.x		%fp0			# Y = |X|
   7855  1.1.6.2  bouyer 
   7856  1.1.6.2  bouyer 	movm.l		&0x8040,-(%sp)		# {a1/d0}
   7857  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save Y on stack
   7858  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to Y
   7859  1.1.6.2  bouyer 	clr.l		%d0
   7860  1.1.6.2  bouyer 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
   7861  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear Y from stack
   7862  1.1.6.2  bouyer 	fmov.l		&0,%fpcr
   7863  1.1.6.2  bouyer 	movm.l		(%sp)+,&0x0201		# {a1/d0}
   7864  1.1.6.2  bouyer 
   7865  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   7866  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp1	# 1+Z
   7867  1.1.6.2  bouyer 	fmov.x		%fp0,-(%sp)
   7868  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# Z/(1+Z)
   7869  1.1.6.2  bouyer 	mov.l		%a1,%d1
   7870  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   7871  1.1.6.2  bouyer 	or.l		&0x3F000000,%d1
   7872  1.1.6.2  bouyer 	fadd.x		(%sp)+,%fp0
   7873  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)
   7874  1.1.6.2  bouyer 
   7875  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7876  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7877  1.1.6.2  bouyer 	fmul.s		(%sp)+,%fp0		# last fp inst - possible exceptions set
   7878  1.1.6.2  bouyer 	bra		t_catch
   7879  1.1.6.2  bouyer 
   7880  1.1.6.2  bouyer SINHBIG:
   7881  1.1.6.2  bouyer 	cmp.l		%d1,&0x400CB2B3
   7882  1.1.6.2  bouyer 	bgt		t_ovfl
   7883  1.1.6.2  bouyer 	fabs.x		%fp0
   7884  1.1.6.2  bouyer 	fsub.d		T1(%pc),%fp0		# (|X|-16381LOG2_LEAD)
   7885  1.1.6.2  bouyer 	mov.l		&0,-(%sp)
   7886  1.1.6.2  bouyer 	mov.l		&0x80000000,-(%sp)
   7887  1.1.6.2  bouyer 	mov.l		%a1,%d1
   7888  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   7889  1.1.6.2  bouyer 	or.l		&0x7FFB0000,%d1
   7890  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# EXTENDED FMT
   7891  1.1.6.2  bouyer 	fsub.d		T2(%pc),%fp0		# |X| - 16381 LOG2, ACCURATE
   7892  1.1.6.2  bouyer 
   7893  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   7894  1.1.6.2  bouyer 	clr.l		%d0
   7895  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save fp0 on stack
   7896  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to fp0
   7897  1.1.6.2  bouyer 	bsr		setox
   7898  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear fp0 from stack
   7899  1.1.6.2  bouyer 
   7900  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   7901  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   7902  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   7903  1.1.6.2  bouyer 	fmul.x		(%sp)+,%fp0		# possible exception
   7904  1.1.6.2  bouyer 	bra		t_catch
   7905  1.1.6.2  bouyer 
   7906  1.1.6.2  bouyer 	global		ssinhd
   7907  1.1.6.2  bouyer #--SINH(X) = X FOR DENORMALIZED X
   7908  1.1.6.2  bouyer ssinhd:
   7909  1.1.6.2  bouyer 	bra		t_extdnrm
   7910  1.1.6.2  bouyer 
   7911  1.1.6.2  bouyer #########################################################################
   7912  1.1.6.2  bouyer # stanh():  computes the hyperbolic tangent of a normalized input	#
   7913  1.1.6.2  bouyer # stanhd(): computes the hyperbolic tangent of a denormalized input	#
   7914  1.1.6.2  bouyer #									#
   7915  1.1.6.2  bouyer # INPUT ***************************************************************	#
   7916  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   7917  1.1.6.2  bouyer #	d0 = round precision,mode					#
   7918  1.1.6.2  bouyer #									#
   7919  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   7920  1.1.6.2  bouyer #	fp0 = tanh(X)							#
   7921  1.1.6.2  bouyer #									#
   7922  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   7923  1.1.6.2  bouyer #	The returned result is within 3 ulps in 64 significant bit, 	#
   7924  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
   7925  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   7926  1.1.6.2  bouyer #	in double precision.						#
   7927  1.1.6.2  bouyer #									#
   7928  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   7929  1.1.6.2  bouyer #									#
   7930  1.1.6.2  bouyer #	TANH								#
   7931  1.1.6.2  bouyer #	1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3.		#
   7932  1.1.6.2  bouyer #									#
   7933  1.1.6.2  bouyer #	2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by		#
   7934  1.1.6.2  bouyer #		sgn := sign(X), y := 2|X|, z := expm1(Y), and		#
   7935  1.1.6.2  bouyer #		tanh(X) = sgn*( z/(2+z) ).				#
   7936  1.1.6.2  bouyer #		Exit.							#
   7937  1.1.6.2  bouyer #									#
   7938  1.1.6.2  bouyer #	3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1,		#
   7939  1.1.6.2  bouyer #		go to 7.						#
   7940  1.1.6.2  bouyer #									#
   7941  1.1.6.2  bouyer #	4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6.		#
   7942  1.1.6.2  bouyer #									#
   7943  1.1.6.2  bouyer #	5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by		#
   7944  1.1.6.2  bouyer #		sgn := sign(X), y := 2|X|, z := exp(Y),			#
   7945  1.1.6.2  bouyer #		tanh(X) = sgn - [ sgn*2/(1+z) ].			#
   7946  1.1.6.2  bouyer #		Exit.							#
   7947  1.1.6.2  bouyer #									#
   7948  1.1.6.2  bouyer #	6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we	#
   7949  1.1.6.2  bouyer #		calculate Tanh(X) by					#
   7950  1.1.6.2  bouyer #		sgn := sign(X), Tiny := 2**(-126),			#
   7951  1.1.6.2  bouyer #		tanh(X) := sgn - sgn*Tiny.				#
   7952  1.1.6.2  bouyer #		Exit.							#
   7953  1.1.6.2  bouyer #									#
   7954  1.1.6.2  bouyer #	7. (|X| < 2**(-40)). Tanh(X) = X.	Exit.			#
   7955  1.1.6.2  bouyer #									#
   7956  1.1.6.2  bouyer #########################################################################
   7957  1.1.6.2  bouyer 
   7958  1.1.6.2  bouyer 	set		X,FP_SCR0
   7959  1.1.6.2  bouyer 	set		XFRAC,X+4
   7960  1.1.6.2  bouyer 
   7961  1.1.6.2  bouyer 	set		SGN,L_SCR3
   7962  1.1.6.2  bouyer 
   7963  1.1.6.2  bouyer 	set		V,FP_SCR0
   7964  1.1.6.2  bouyer 
   7965  1.1.6.2  bouyer 	global		stanh
   7966  1.1.6.2  bouyer stanh:
   7967  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   7968  1.1.6.2  bouyer 
   7969  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)
   7970  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   7971  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   7972  1.1.6.2  bouyer 	mov.l		%d1,X(%a6)
   7973  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   7974  1.1.6.2  bouyer 	cmp.l		%d1, &0x3fd78000	# is |X| < 2^(-40)?
   7975  1.1.6.2  bouyer 	blt.w		TANHBORS		# yes
   7976  1.1.6.2  bouyer 	cmp.l		%d1, &0x3fffddce	# is |X| > (5/2)LOG2?
   7977  1.1.6.2  bouyer 	bgt.w		TANHBORS		# yes
   7978  1.1.6.2  bouyer 
   7979  1.1.6.2  bouyer #--THIS IS THE USUAL CASE
   7980  1.1.6.2  bouyer #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
   7981  1.1.6.2  bouyer 
   7982  1.1.6.2  bouyer 	mov.l		X(%a6),%d1
   7983  1.1.6.2  bouyer 	mov.l		%d1,SGN(%a6)
   7984  1.1.6.2  bouyer 	and.l		&0x7FFF0000,%d1
   7985  1.1.6.2  bouyer 	add.l		&0x00010000,%d1		# EXPONENT OF 2|X|
   7986  1.1.6.2  bouyer 	mov.l		%d1,X(%a6)
   7987  1.1.6.2  bouyer 	and.l		&0x80000000,SGN(%a6)
   7988  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0		# FP0 IS Y = 2|X|
   7989  1.1.6.2  bouyer 
   7990  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   7991  1.1.6.2  bouyer 	clr.l		%d0
   7992  1.1.6.2  bouyer 	fmovm.x		&0x1,-(%sp)		# save Y on stack
   7993  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to Y
   7994  1.1.6.2  bouyer 	bsr		setoxm1			# FP0 IS Z = EXPM1(Y)
   7995  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear Y from stack
   7996  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   7997  1.1.6.2  bouyer 
   7998  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   7999  1.1.6.2  bouyer 	fadd.s		&0x40000000,%fp1	# Z+2
   8000  1.1.6.2  bouyer 	mov.l		SGN(%a6),%d1
   8001  1.1.6.2  bouyer 	fmov.x		%fp1,V(%a6)
   8002  1.1.6.2  bouyer 	eor.l		%d1,V(%a6)
   8003  1.1.6.2  bouyer 
   8004  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8005  1.1.6.2  bouyer 	fdiv.x		V(%a6),%fp0
   8006  1.1.6.2  bouyer 	bra		t_inx2
   8007  1.1.6.2  bouyer 
   8008  1.1.6.2  bouyer TANHBORS:
   8009  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   8010  1.1.6.2  bouyer 	blt.w		TANHSM
   8011  1.1.6.2  bouyer 
   8012  1.1.6.2  bouyer 	cmp.l		%d1,&0x40048AA1
   8013  1.1.6.2  bouyer 	bgt.w		TANHHUGE
   8014  1.1.6.2  bouyer 
   8015  1.1.6.2  bouyer #-- (5/2) LOG2 < |X| < 50 LOG2,
   8016  1.1.6.2  bouyer #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
   8017  1.1.6.2  bouyer #--TANH(X) = SGN -	SGN*2/[EXP(Y)+1].
   8018  1.1.6.2  bouyer 
   8019  1.1.6.2  bouyer 	mov.l		X(%a6),%d1
   8020  1.1.6.2  bouyer 	mov.l		%d1,SGN(%a6)
   8021  1.1.6.2  bouyer 	and.l		&0x7FFF0000,%d1
   8022  1.1.6.2  bouyer 	add.l		&0x00010000,%d1		# EXPO OF 2|X|
   8023  1.1.6.2  bouyer 	mov.l		%d1,X(%a6)		# Y = 2|X|
   8024  1.1.6.2  bouyer 	and.l		&0x80000000,SGN(%a6)
   8025  1.1.6.2  bouyer 	mov.l		SGN(%a6),%d1
   8026  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0		# Y = 2|X|
   8027  1.1.6.2  bouyer 
   8028  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   8029  1.1.6.2  bouyer 	clr.l		%d0
   8030  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save Y on stack
   8031  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to Y
   8032  1.1.6.2  bouyer 	bsr		setox			# FP0 IS EXP(Y)
   8033  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear Y from stack
   8034  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   8035  1.1.6.2  bouyer 	mov.l		SGN(%a6),%d1
   8036  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp0	# EXP(Y)+1
   8037  1.1.6.2  bouyer 
   8038  1.1.6.2  bouyer 	eor.l		&0xC0000000,%d1		# -SIGN(X)*2
   8039  1.1.6.2  bouyer 	fmov.s		%d1,%fp1		# -SIGN(X)*2 IN SGL FMT
   8040  1.1.6.2  bouyer 	fdiv.x		%fp0,%fp1		# -SIGN(X)2 / [EXP(Y)+1 ]
   8041  1.1.6.2  bouyer 
   8042  1.1.6.2  bouyer 	mov.l		SGN(%a6),%d1
   8043  1.1.6.2  bouyer 	or.l		&0x3F800000,%d1		# SGN
   8044  1.1.6.2  bouyer 	fmov.s		%d1,%fp0		# SGN IN SGL FMT
   8045  1.1.6.2  bouyer 
   8046  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8047  1.1.6.2  bouyer 	mov.b		&FADD_OP,%d1		# last inst is ADD
   8048  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0
   8049  1.1.6.2  bouyer 	bra		t_inx2
   8050  1.1.6.2  bouyer 
   8051  1.1.6.2  bouyer TANHSM:
   8052  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8053  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   8054  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0		# last inst - possible exception set
   8055  1.1.6.2  bouyer 	bra		t_catch
   8056  1.1.6.2  bouyer 
   8057  1.1.6.2  bouyer #---RETURN SGN(X) - SGN(X)EPS
   8058  1.1.6.2  bouyer TANHHUGE:
   8059  1.1.6.2  bouyer 	mov.l		X(%a6),%d1
   8060  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   8061  1.1.6.2  bouyer 	or.l		&0x3F800000,%d1
   8062  1.1.6.2  bouyer 	fmov.s		%d1,%fp0
   8063  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   8064  1.1.6.2  bouyer 	eor.l		&0x80800000,%d1		# -SIGN(X)*EPS
   8065  1.1.6.2  bouyer 
   8066  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   8067  1.1.6.2  bouyer 	fadd.s		%d1,%fp0
   8068  1.1.6.2  bouyer 	bra		t_inx2
   8069  1.1.6.2  bouyer 
   8070  1.1.6.2  bouyer 	global		stanhd
   8071  1.1.6.2  bouyer #--TANH(X) = X FOR DENORMALIZED X
   8072  1.1.6.2  bouyer stanhd:
   8073  1.1.6.2  bouyer 	bra		t_extdnrm
   8074  1.1.6.2  bouyer 
   8075  1.1.6.2  bouyer #########################################################################
   8076  1.1.6.2  bouyer # slogn():    computes the natural logarithm of a normalized input	#
   8077  1.1.6.2  bouyer # slognd():   computes the natural logarithm of a denormalized input	#
   8078  1.1.6.2  bouyer # slognp1():  computes the log(1+X) of a normalized input		#
   8079  1.1.6.2  bouyer # slognp1d(): computes the log(1+X) of a denormalized input		#
   8080  1.1.6.2  bouyer #									#
   8081  1.1.6.2  bouyer # INPUT ***************************************************************	#
   8082  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   8083  1.1.6.2  bouyer #	d0 = round precision,mode					#
   8084  1.1.6.2  bouyer #									#
   8085  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   8086  1.1.6.2  bouyer #	fp0 = log(X) or log(1+X)					#
   8087  1.1.6.2  bouyer #									#
   8088  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   8089  1.1.6.2  bouyer #	The returned result is within 2 ulps in 64 significant bit, 	#
   8090  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8091  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   8092  1.1.6.2  bouyer #	in double precision.						#
   8093  1.1.6.2  bouyer #									#
   8094  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   8095  1.1.6.2  bouyer #	LOGN:								#
   8096  1.1.6.2  bouyer #	Step 1. If |X-1| < 1/16, approximate log(X) by an odd 		#
   8097  1.1.6.2  bouyer #		polynomial in u, where u = 2(X-1)/(X+1). Otherwise, 	#
   8098  1.1.6.2  bouyer #		move on to Step 2.					#
   8099  1.1.6.2  bouyer #									#
   8100  1.1.6.2  bouyer #	Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first	#
   8101  1.1.6.2  bouyer #		seven significant bits of Y plus 2**(-7), i.e. 		#
   8102  1.1.6.2  bouyer #		F = 1.xxxxxx1 in base 2 where the six "x" match those 	#
   8103  1.1.6.2  bouyer #		of Y. Note that |Y-F| <= 2**(-7).			#
   8104  1.1.6.2  bouyer #									#
   8105  1.1.6.2  bouyer #	Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a 		#
   8106  1.1.6.2  bouyer #		polynomial in u, log(1+u) = poly.			#
   8107  1.1.6.2  bouyer #									#
   8108  1.1.6.2  bouyer #	Step 4. Reconstruct 						#
   8109  1.1.6.2  bouyer #		log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u)	#
   8110  1.1.6.2  bouyer #		by k*log(2) + (log(F) + poly). The values of log(F) are	#
   8111  1.1.6.2  bouyer #		calculated beforehand and stored in the program.	#
   8112  1.1.6.2  bouyer #									#
   8113  1.1.6.2  bouyer #	lognp1:								#
   8114  1.1.6.2  bouyer #	Step 1: If |X| < 1/16, approximate log(1+X) by an odd 		#
   8115  1.1.6.2  bouyer #		polynomial in u where u = 2X/(2+X). Otherwise, move on	#
   8116  1.1.6.2  bouyer #		to Step 2.						#
   8117  1.1.6.2  bouyer #									#
   8118  1.1.6.2  bouyer #	Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done	#
   8119  1.1.6.2  bouyer #		in Step 2 of the algorithm for LOGN and compute 	#
   8120  1.1.6.2  bouyer #		log(1+X) as k*log(2) + log(F) + poly where poly 	#
   8121  1.1.6.2  bouyer #		approximates log(1+u), u = (Y-F)/F. 			#
   8122  1.1.6.2  bouyer #									#
   8123  1.1.6.2  bouyer #	Implementation Notes:						#
   8124  1.1.6.2  bouyer #	Note 1. There are 64 different possible values for F, thus 64 	#
   8125  1.1.6.2  bouyer #		log(F)'s need to be tabulated. Moreover, the values of	#
   8126  1.1.6.2  bouyer #		1/F are also tabulated so that the division in (Y-F)/F	#
   8127  1.1.6.2  bouyer #		can be performed by a multiplication.			#
   8128  1.1.6.2  bouyer #									#
   8129  1.1.6.2  bouyer #	Note 2. In Step 2 of lognp1, in order to preserved accuracy, 	#
   8130  1.1.6.2  bouyer #		the value Y-F has to be calculated carefully when 	#
   8131  1.1.6.2  bouyer #		1/2 <= X < 3/2. 					#
   8132  1.1.6.2  bouyer #									#
   8133  1.1.6.2  bouyer #	Note 3. To fully exploit the pipeline, polynomials are usually 	#
   8134  1.1.6.2  bouyer #		separated into two parts evaluated independently before	#
   8135  1.1.6.2  bouyer #		being added up.						#
   8136  1.1.6.2  bouyer #									#
   8137  1.1.6.2  bouyer #########################################################################
   8138  1.1.6.2  bouyer LOGOF2:
   8139  1.1.6.2  bouyer 	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
   8140  1.1.6.2  bouyer 
   8141  1.1.6.2  bouyer one:
   8142  1.1.6.2  bouyer 	long		0x3F800000
   8143  1.1.6.2  bouyer zero:
   8144  1.1.6.2  bouyer 	long		0x00000000
   8145  1.1.6.2  bouyer infty:
   8146  1.1.6.2  bouyer 	long		0x7F800000
   8147  1.1.6.2  bouyer negone:
   8148  1.1.6.2  bouyer 	long		0xBF800000
   8149  1.1.6.2  bouyer 
   8150  1.1.6.2  bouyer LOGA6:
   8151  1.1.6.2  bouyer 	long		0x3FC2499A,0xB5E4040B
   8152  1.1.6.2  bouyer LOGA5:
   8153  1.1.6.2  bouyer 	long		0xBFC555B5,0x848CB7DB
   8154  1.1.6.2  bouyer 
   8155  1.1.6.2  bouyer LOGA4:
   8156  1.1.6.2  bouyer 	long		0x3FC99999,0x987D8730
   8157  1.1.6.2  bouyer LOGA3:
   8158  1.1.6.2  bouyer 	long		0xBFCFFFFF,0xFF6F7E97
   8159  1.1.6.2  bouyer 
   8160  1.1.6.2  bouyer LOGA2:
   8161  1.1.6.2  bouyer 	long		0x3FD55555,0x555555A4
   8162  1.1.6.2  bouyer LOGA1:
   8163  1.1.6.2  bouyer 	long		0xBFE00000,0x00000008
   8164  1.1.6.2  bouyer 
   8165  1.1.6.2  bouyer LOGB5:
   8166  1.1.6.2  bouyer 	long		0x3F175496,0xADD7DAD6
   8167  1.1.6.2  bouyer LOGB4:
   8168  1.1.6.2  bouyer 	long		0x3F3C71C2,0xFE80C7E0
   8169  1.1.6.2  bouyer 
   8170  1.1.6.2  bouyer LOGB3:
   8171  1.1.6.2  bouyer 	long		0x3F624924,0x928BCCFF
   8172  1.1.6.2  bouyer LOGB2:
   8173  1.1.6.2  bouyer 	long		0x3F899999,0x999995EC
   8174  1.1.6.2  bouyer 
   8175  1.1.6.2  bouyer LOGB1:
   8176  1.1.6.2  bouyer 	long		0x3FB55555,0x55555555
   8177  1.1.6.2  bouyer TWO:
   8178  1.1.6.2  bouyer 	long		0x40000000,0x00000000
   8179  1.1.6.2  bouyer 
   8180  1.1.6.2  bouyer LTHOLD:
   8181  1.1.6.2  bouyer 	long		0x3f990000,0x80000000,0x00000000,0x00000000
   8182  1.1.6.2  bouyer 
   8183  1.1.6.2  bouyer LOGTBL:
   8184  1.1.6.2  bouyer 	long		0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
   8185  1.1.6.2  bouyer 	long		0x3FF70000,0xFF015358,0x833C47E2,0x00000000
   8186  1.1.6.2  bouyer 	long		0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
   8187  1.1.6.2  bouyer 	long		0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
   8188  1.1.6.2  bouyer 	long		0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
   8189  1.1.6.2  bouyer 	long		0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
   8190  1.1.6.2  bouyer 	long		0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
   8191  1.1.6.2  bouyer 	long		0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
   8192  1.1.6.2  bouyer 	long		0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
   8193  1.1.6.2  bouyer 	long		0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
   8194  1.1.6.2  bouyer 	long		0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
   8195  1.1.6.2  bouyer 	long		0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
   8196  1.1.6.2  bouyer 	long		0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
   8197  1.1.6.2  bouyer 	long		0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
   8198  1.1.6.2  bouyer 	long		0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
   8199  1.1.6.2  bouyer 	long		0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
   8200  1.1.6.2  bouyer 	long		0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
   8201  1.1.6.2  bouyer 	long		0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
   8202  1.1.6.2  bouyer 	long		0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
   8203  1.1.6.2  bouyer 	long		0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
   8204  1.1.6.2  bouyer 	long		0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
   8205  1.1.6.2  bouyer 	long		0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
   8206  1.1.6.2  bouyer 	long		0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
   8207  1.1.6.2  bouyer 	long		0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
   8208  1.1.6.2  bouyer 	long		0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
   8209  1.1.6.2  bouyer 	long		0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
   8210  1.1.6.2  bouyer 	long		0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
   8211  1.1.6.2  bouyer 	long		0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
   8212  1.1.6.2  bouyer 	long		0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
   8213  1.1.6.2  bouyer 	long		0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
   8214  1.1.6.2  bouyer 	long		0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
   8215  1.1.6.2  bouyer 	long		0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
   8216  1.1.6.2  bouyer 	long		0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
   8217  1.1.6.2  bouyer 	long		0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
   8218  1.1.6.2  bouyer 	long		0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
   8219  1.1.6.2  bouyer 	long		0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
   8220  1.1.6.2  bouyer 	long		0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
   8221  1.1.6.2  bouyer 	long		0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
   8222  1.1.6.2  bouyer 	long		0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
   8223  1.1.6.2  bouyer 	long		0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
   8224  1.1.6.2  bouyer 	long		0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
   8225  1.1.6.2  bouyer 	long		0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
   8226  1.1.6.2  bouyer 	long		0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
   8227  1.1.6.2  bouyer 	long		0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
   8228  1.1.6.2  bouyer 	long		0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
   8229  1.1.6.2  bouyer 	long		0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
   8230  1.1.6.2  bouyer 	long		0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
   8231  1.1.6.2  bouyer 	long		0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
   8232  1.1.6.2  bouyer 	long		0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
   8233  1.1.6.2  bouyer 	long		0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
   8234  1.1.6.2  bouyer 	long		0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
   8235  1.1.6.2  bouyer 	long		0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
   8236  1.1.6.2  bouyer 	long		0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
   8237  1.1.6.2  bouyer 	long		0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
   8238  1.1.6.2  bouyer 	long		0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
   8239  1.1.6.2  bouyer 	long		0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
   8240  1.1.6.2  bouyer 	long		0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
   8241  1.1.6.2  bouyer 	long		0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
   8242  1.1.6.2  bouyer 	long		0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
   8243  1.1.6.2  bouyer 	long		0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
   8244  1.1.6.2  bouyer 	long		0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
   8245  1.1.6.2  bouyer 	long		0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
   8246  1.1.6.2  bouyer 	long		0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
   8247  1.1.6.2  bouyer 	long		0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
   8248  1.1.6.2  bouyer 	long		0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
   8249  1.1.6.2  bouyer 	long		0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
   8250  1.1.6.2  bouyer 	long		0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
   8251  1.1.6.2  bouyer 	long		0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
   8252  1.1.6.2  bouyer 	long		0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
   8253  1.1.6.2  bouyer 	long		0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
   8254  1.1.6.2  bouyer 	long		0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
   8255  1.1.6.2  bouyer 	long		0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
   8256  1.1.6.2  bouyer 	long		0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
   8257  1.1.6.2  bouyer 	long		0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
   8258  1.1.6.2  bouyer 	long		0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
   8259  1.1.6.2  bouyer 	long		0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
   8260  1.1.6.2  bouyer 	long		0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
   8261  1.1.6.2  bouyer 	long		0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
   8262  1.1.6.2  bouyer 	long		0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
   8263  1.1.6.2  bouyer 	long		0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
   8264  1.1.6.2  bouyer 	long		0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
   8265  1.1.6.2  bouyer 	long		0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
   8266  1.1.6.2  bouyer 	long		0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
   8267  1.1.6.2  bouyer 	long		0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
   8268  1.1.6.2  bouyer 	long		0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
   8269  1.1.6.2  bouyer 	long		0x3FFE0000,0x825EFCED,0x49369330,0x00000000
   8270  1.1.6.2  bouyer 	long		0x3FFE0000,0x9868C809,0x868C8098,0x00000000
   8271  1.1.6.2  bouyer 	long		0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
   8272  1.1.6.2  bouyer 	long		0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
   8273  1.1.6.2  bouyer 	long		0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
   8274  1.1.6.2  bouyer 	long		0x3FFE0000,0x95A02568,0x095A0257,0x00000000
   8275  1.1.6.2  bouyer 	long		0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
   8276  1.1.6.2  bouyer 	long		0x3FFE0000,0x94458094,0x45809446,0x00000000
   8277  1.1.6.2  bouyer 	long		0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
   8278  1.1.6.2  bouyer 	long		0x3FFE0000,0x92F11384,0x0497889C,0x00000000
   8279  1.1.6.2  bouyer 	long		0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
   8280  1.1.6.2  bouyer 	long		0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
   8281  1.1.6.2  bouyer 	long		0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
   8282  1.1.6.2  bouyer 	long		0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
   8283  1.1.6.2  bouyer 	long		0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
   8284  1.1.6.2  bouyer 	long		0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
   8285  1.1.6.2  bouyer 	long		0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
   8286  1.1.6.2  bouyer 	long		0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
   8287  1.1.6.2  bouyer 	long		0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
   8288  1.1.6.2  bouyer 	long		0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
   8289  1.1.6.2  bouyer 	long		0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
   8290  1.1.6.2  bouyer 	long		0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
   8291  1.1.6.2  bouyer 	long		0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
   8292  1.1.6.2  bouyer 	long		0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
   8293  1.1.6.2  bouyer 	long		0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
   8294  1.1.6.2  bouyer 	long		0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
   8295  1.1.6.2  bouyer 	long		0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
   8296  1.1.6.2  bouyer 	long		0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
   8297  1.1.6.2  bouyer 	long		0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
   8298  1.1.6.2  bouyer 	long		0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
   8299  1.1.6.2  bouyer 	long		0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
   8300  1.1.6.2  bouyer 	long		0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
   8301  1.1.6.2  bouyer 	long		0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
   8302  1.1.6.2  bouyer 	long		0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
   8303  1.1.6.2  bouyer 	long		0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
   8304  1.1.6.2  bouyer 	long		0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
   8305  1.1.6.2  bouyer 	long		0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
   8306  1.1.6.2  bouyer 	long		0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
   8307  1.1.6.2  bouyer 	long		0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
   8308  1.1.6.2  bouyer 	long		0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
   8309  1.1.6.2  bouyer 	long		0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
   8310  1.1.6.2  bouyer 	long		0x3FFE0000,0x80808080,0x80808081,0x00000000
   8311  1.1.6.2  bouyer 	long		0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
   8312  1.1.6.2  bouyer 
   8313  1.1.6.2  bouyer 	set		ADJK,L_SCR1
   8314  1.1.6.2  bouyer 
   8315  1.1.6.2  bouyer 	set		X,FP_SCR0
   8316  1.1.6.2  bouyer 	set		XDCARE,X+2
   8317  1.1.6.2  bouyer 	set		XFRAC,X+4
   8318  1.1.6.2  bouyer 
   8319  1.1.6.2  bouyer 	set		F,FP_SCR1
   8320  1.1.6.2  bouyer 	set		FFRAC,F+4
   8321  1.1.6.2  bouyer 
   8322  1.1.6.2  bouyer 	set		KLOG2,FP_SCR0
   8323  1.1.6.2  bouyer 
   8324  1.1.6.2  bouyer 	set		SAVEU,FP_SCR0
   8325  1.1.6.2  bouyer 
   8326  1.1.6.2  bouyer 	global		slogn
   8327  1.1.6.2  bouyer #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
   8328  1.1.6.2  bouyer slogn:
   8329  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8330  1.1.6.2  bouyer 	mov.l		&0x00000000,ADJK(%a6)
   8331  1.1.6.2  bouyer 
   8332  1.1.6.2  bouyer LOGBGN:
   8333  1.1.6.2  bouyer #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
   8334  1.1.6.2  bouyer #--A FINITE, NON-ZERO, NORMALIZED NUMBER.
   8335  1.1.6.2  bouyer 
   8336  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   8337  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   8338  1.1.6.2  bouyer 
   8339  1.1.6.2  bouyer 	mov.l		(%a0),X(%a6)
   8340  1.1.6.2  bouyer 	mov.l		4(%a0),X+4(%a6)
   8341  1.1.6.2  bouyer 	mov.l		8(%a0),X+8(%a6)
   8342  1.1.6.2  bouyer 
   8343  1.1.6.2  bouyer 	cmp.l		%d1,&0			# CHECK IF X IS NEGATIVE
   8344  1.1.6.2  bouyer 	blt.w		LOGNEG			# LOG OF NEGATIVE ARGUMENT IS INVALID
   8345  1.1.6.2  bouyer # X IS POSITIVE, CHECK IF X IS NEAR 1
   8346  1.1.6.2  bouyer 	cmp.l		%d1,&0x3ffef07d 	# IS X < 15/16?
   8347  1.1.6.2  bouyer 	blt.b		LOGMAIN			# YES
   8348  1.1.6.2  bouyer 	cmp.l		%d1,&0x3fff8841 	# IS X > 17/16?
   8349  1.1.6.2  bouyer 	ble.w		LOGNEAR1		# NO
   8350  1.1.6.2  bouyer 
   8351  1.1.6.2  bouyer LOGMAIN:
   8352  1.1.6.2  bouyer #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
   8353  1.1.6.2  bouyer 
   8354  1.1.6.2  bouyer #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
   8355  1.1.6.2  bouyer #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
   8356  1.1.6.2  bouyer #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
   8357  1.1.6.2  bouyer #--			 = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
   8358  1.1.6.2  bouyer #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
   8359  1.1.6.2  bouyer #--LOG(1+U) CAN BE VERY EFFICIENT.
   8360  1.1.6.2  bouyer #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
   8361  1.1.6.2  bouyer #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
   8362  1.1.6.2  bouyer 
   8363  1.1.6.2  bouyer #--GET K, Y, F, AND ADDRESS OF 1/F.
   8364  1.1.6.2  bouyer 	asr.l		&8,%d1
   8365  1.1.6.2  bouyer 	asr.l		&8,%d1			# SHIFTED 16 BITS, BIASED EXPO. OF X
   8366  1.1.6.2  bouyer 	sub.l		&0x3FFF,%d1		# THIS IS K
   8367  1.1.6.2  bouyer 	add.l		ADJK(%a6),%d1		# ADJUST K, ORIGINAL INPUT MAY BE  DENORM.
   8368  1.1.6.2  bouyer 	lea		LOGTBL(%pc),%a0		# BASE ADDRESS OF 1/F AND LOG(F)
   8369  1.1.6.2  bouyer 	fmov.l		%d1,%fp1		# CONVERT K TO FLOATING-POINT FORMAT
   8370  1.1.6.2  bouyer 
   8371  1.1.6.2  bouyer #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
   8372  1.1.6.2  bouyer 	mov.l		&0x3FFF0000,X(%a6)	# X IS NOW Y, I.E. 2^(-K)*X
   8373  1.1.6.2  bouyer 	mov.l		XFRAC(%a6),FFRAC(%a6)
   8374  1.1.6.2  bouyer 	and.l		&0xFE000000,FFRAC(%a6)	# FIRST 7 BITS OF Y
   8375  1.1.6.2  bouyer 	or.l		&0x01000000,FFRAC(%a6)	# GET F: ATTACH A 1 AT THE EIGHTH BIT
   8376  1.1.6.2  bouyer 	mov.l		FFRAC(%a6),%d1	# READY TO GET ADDRESS OF 1/F
   8377  1.1.6.2  bouyer 	and.l		&0x7E000000,%d1
   8378  1.1.6.2  bouyer 	asr.l		&8,%d1
   8379  1.1.6.2  bouyer 	asr.l		&8,%d1
   8380  1.1.6.2  bouyer 	asr.l		&4,%d1			# SHIFTED 20, D0 IS THE DISPLACEMENT
   8381  1.1.6.2  bouyer 	add.l		%d1,%a0			# A0 IS THE ADDRESS FOR 1/F
   8382  1.1.6.2  bouyer 
   8383  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0
   8384  1.1.6.2  bouyer 	mov.l		&0x3fff0000,F(%a6)
   8385  1.1.6.2  bouyer 	clr.l		F+8(%a6)
   8386  1.1.6.2  bouyer 	fsub.x		F(%a6),%fp0		# Y-F
   8387  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3 WHILE FP0 IS NOT READY
   8388  1.1.6.2  bouyer #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
   8389  1.1.6.2  bouyer #--REGISTERS SAVED: FPCR, FP1, FP2
   8390  1.1.6.2  bouyer 
   8391  1.1.6.2  bouyer LP1CONT1:
   8392  1.1.6.2  bouyer #--AN RE-ENTRY POINT FOR LOGNP1
   8393  1.1.6.2  bouyer 	fmul.x		(%a0),%fp0		# FP0 IS U = (Y-F)/F
   8394  1.1.6.2  bouyer 	fmul.x		LOGOF2(%pc),%fp1	# GET K*LOG2 WHILE FP0 IS NOT READY
   8395  1.1.6.2  bouyer 	fmov.x		%fp0,%fp2
   8396  1.1.6.2  bouyer 	fmul.x		%fp2,%fp2		# FP2 IS V=U*U
   8397  1.1.6.2  bouyer 	fmov.x		%fp1,KLOG2(%a6)		# PUT K*LOG2 IN MEMEORY, FREE FP1
   8398  1.1.6.2  bouyer 
   8399  1.1.6.2  bouyer #--LOG(1+U) IS APPROXIMATED BY
   8400  1.1.6.2  bouyer #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
   8401  1.1.6.2  bouyer #--[U + V*(A1+V*(A3+V*A5))]  +  [U*V*(A2+V*(A4+V*A6))]
   8402  1.1.6.2  bouyer 
   8403  1.1.6.2  bouyer 	fmov.x		%fp2,%fp3
   8404  1.1.6.2  bouyer 	fmov.x		%fp2,%fp1
   8405  1.1.6.2  bouyer 
   8406  1.1.6.2  bouyer 	fmul.d		LOGA6(%pc),%fp1		# V*A6
   8407  1.1.6.2  bouyer 	fmul.d		LOGA5(%pc),%fp2		# V*A5
   8408  1.1.6.2  bouyer 
   8409  1.1.6.2  bouyer 	fadd.d		LOGA4(%pc),%fp1		# A4+V*A6
   8410  1.1.6.2  bouyer 	fadd.d		LOGA3(%pc),%fp2		# A3+V*A5
   8411  1.1.6.2  bouyer 
   8412  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# V*(A4+V*A6)
   8413  1.1.6.2  bouyer 	fmul.x		%fp3,%fp2		# V*(A3+V*A5)
   8414  1.1.6.2  bouyer 
   8415  1.1.6.2  bouyer 	fadd.d		LOGA2(%pc),%fp1		# A2+V*(A4+V*A6)
   8416  1.1.6.2  bouyer 	fadd.d		LOGA1(%pc),%fp2		# A1+V*(A3+V*A5)
   8417  1.1.6.2  bouyer 
   8418  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# V*(A2+V*(A4+V*A6))
   8419  1.1.6.2  bouyer 	add.l		&16,%a0			# ADDRESS OF LOG(F)
   8420  1.1.6.2  bouyer 	fmul.x		%fp3,%fp2		# V*(A1+V*(A3+V*A5))
   8421  1.1.6.2  bouyer 
   8422  1.1.6.2  bouyer 	fmul.x		%fp0,%fp1		# U*V*(A2+V*(A4+V*A6))
   8423  1.1.6.2  bouyer 	fadd.x		%fp2,%fp0		# U+V*(A1+V*(A3+V*A5))
   8424  1.1.6.2  bouyer 
   8425  1.1.6.2  bouyer 	fadd.x		(%a0),%fp1		# LOG(F)+U*V*(A2+V*(A4+V*A6))
   8426  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# RESTORE FP2-3
   8427  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# FP0 IS LOG(F) + LOG(1+U)
   8428  1.1.6.2  bouyer 
   8429  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   8430  1.1.6.2  bouyer 	fadd.x		KLOG2(%a6),%fp0		# FINAL ADD
   8431  1.1.6.2  bouyer 	bra		t_inx2
   8432  1.1.6.2  bouyer 
   8433  1.1.6.2  bouyer 
   8434  1.1.6.2  bouyer LOGNEAR1:
   8435  1.1.6.2  bouyer 
   8436  1.1.6.2  bouyer # if the input is exactly equal to one, then exit through ld_pzero.
   8437  1.1.6.2  bouyer # if these 2 lines weren't here, the correct answer would be returned
   8438  1.1.6.2  bouyer # but the INEX2 bit would be set.
   8439  1.1.6.2  bouyer 	fcmp.b		%fp0,&0x1		# is it equal to one?
   8440  1.1.6.2  bouyer 	fbeq.l		ld_pzero		# yes
   8441  1.1.6.2  bouyer 
   8442  1.1.6.2  bouyer #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
   8443  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   8444  1.1.6.2  bouyer 	fsub.s		one(%pc),%fp1		# FP1 IS X-1
   8445  1.1.6.2  bouyer 	fadd.s		one(%pc),%fp0		# FP0 IS X+1
   8446  1.1.6.2  bouyer 	fadd.x		%fp1,%fp1		# FP1 IS 2(X-1)
   8447  1.1.6.2  bouyer #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
   8448  1.1.6.2  bouyer #--IN U, U = 2(X-1)/(X+1) = FP1/FP0
   8449  1.1.6.2  bouyer 
   8450  1.1.6.2  bouyer LP1CONT2:
   8451  1.1.6.2  bouyer #--THIS IS AN RE-ENTRY POINT FOR LOGNP1
   8452  1.1.6.2  bouyer 	fdiv.x		%fp0,%fp1		# FP1 IS U
   8453  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# SAVE FP2-3
   8454  1.1.6.2  bouyer #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
   8455  1.1.6.2  bouyer #--LET V=U*U, W=V*V, CALCULATE
   8456  1.1.6.2  bouyer #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
   8457  1.1.6.2  bouyer #--U + U*V*(  [B1 + W*(B3 + W*B5)]  +  [V*(B2 + W*B4)]  )
   8458  1.1.6.2  bouyer 	fmov.x		%fp1,%fp0
   8459  1.1.6.2  bouyer 	fmul.x		%fp0,%fp0		# FP0 IS V
   8460  1.1.6.2  bouyer 	fmov.x		%fp1,SAVEU(%a6)		# STORE U IN MEMORY, FREE FP1
   8461  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   8462  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# FP1 IS W
   8463  1.1.6.2  bouyer 
   8464  1.1.6.2  bouyer 	fmov.d		LOGB5(%pc),%fp3
   8465  1.1.6.2  bouyer 	fmov.d		LOGB4(%pc),%fp2
   8466  1.1.6.2  bouyer 
   8467  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# W*B5
   8468  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# W*B4
   8469  1.1.6.2  bouyer 
   8470  1.1.6.2  bouyer 	fadd.d		LOGB3(%pc),%fp3		# B3+W*B5
   8471  1.1.6.2  bouyer 	fadd.d		LOGB2(%pc),%fp2		# B2+W*B4
   8472  1.1.6.2  bouyer 
   8473  1.1.6.2  bouyer 	fmul.x		%fp3,%fp1		# W*(B3+W*B5), FP3 RELEASED
   8474  1.1.6.2  bouyer 
   8475  1.1.6.2  bouyer 	fmul.x		%fp0,%fp2		# V*(B2+W*B4)
   8476  1.1.6.2  bouyer 
   8477  1.1.6.2  bouyer 	fadd.d		LOGB1(%pc),%fp1		# B1+W*(B3+W*B5)
   8478  1.1.6.2  bouyer 	fmul.x		SAVEU(%a6),%fp0		# FP0 IS U*V
   8479  1.1.6.2  bouyer 
   8480  1.1.6.2  bouyer 	fadd.x		%fp2,%fp1		# B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
   8481  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# FP2-3 RESTORED
   8482  1.1.6.2  bouyer 
   8483  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0		# U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
   8484  1.1.6.2  bouyer 
   8485  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   8486  1.1.6.2  bouyer 	fadd.x		SAVEU(%a6),%fp0
   8487  1.1.6.2  bouyer 	bra		t_inx2
   8488  1.1.6.2  bouyer 
   8489  1.1.6.2  bouyer #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
   8490  1.1.6.2  bouyer LOGNEG:
   8491  1.1.6.2  bouyer 	bra		t_operr
   8492  1.1.6.2  bouyer 
   8493  1.1.6.2  bouyer 	global		slognd
   8494  1.1.6.2  bouyer slognd:
   8495  1.1.6.2  bouyer #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
   8496  1.1.6.2  bouyer 
   8497  1.1.6.2  bouyer 	mov.l		&-100,ADJK(%a6)		# INPUT = 2^(ADJK) * FP0
   8498  1.1.6.2  bouyer 
   8499  1.1.6.2  bouyer #----normalize the input value by left shifting k bits (k to be determined
   8500  1.1.6.2  bouyer #----below), adjusting exponent and storing -k to  ADJK
   8501  1.1.6.2  bouyer #----the value TWOTO100 is no longer needed.
   8502  1.1.6.2  bouyer #----Note that this code assumes the denormalized input is NON-ZERO.
   8503  1.1.6.2  bouyer 
   8504  1.1.6.2  bouyer 	movm.l		&0x3f00,-(%sp)		# save some registers  {d2-d7}
   8505  1.1.6.2  bouyer 	mov.l		(%a0),%d3		# D3 is exponent of smallest norm. #
   8506  1.1.6.2  bouyer 	mov.l		4(%a0),%d4
   8507  1.1.6.2  bouyer 	mov.l		8(%a0),%d5		# (D4,D5) is (Hi_X,Lo_X)
   8508  1.1.6.2  bouyer 	clr.l		%d2			# D2 used for holding K
   8509  1.1.6.2  bouyer 
   8510  1.1.6.2  bouyer 	tst.l		%d4
   8511  1.1.6.2  bouyer 	bne.b		Hi_not0
   8512  1.1.6.2  bouyer 
   8513  1.1.6.2  bouyer Hi_0:
   8514  1.1.6.2  bouyer 	mov.l		%d5,%d4
   8515  1.1.6.2  bouyer 	clr.l		%d5
   8516  1.1.6.2  bouyer 	mov.l		&32,%d2
   8517  1.1.6.2  bouyer 	clr.l		%d6
   8518  1.1.6.2  bouyer 	bfffo		%d4{&0:&32},%d6
   8519  1.1.6.2  bouyer 	lsl.l		%d6,%d4
   8520  1.1.6.2  bouyer 	add.l		%d6,%d2			# (D3,D4,D5) is normalized
   8521  1.1.6.2  bouyer 
   8522  1.1.6.2  bouyer 	mov.l		%d3,X(%a6)
   8523  1.1.6.2  bouyer 	mov.l		%d4,XFRAC(%a6)
   8524  1.1.6.2  bouyer 	mov.l		%d5,XFRAC+4(%a6)
   8525  1.1.6.2  bouyer 	neg.l		%d2
   8526  1.1.6.2  bouyer 	mov.l		%d2,ADJK(%a6)
   8527  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0
   8528  1.1.6.2  bouyer 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
   8529  1.1.6.2  bouyer 	lea		X(%a6),%a0
   8530  1.1.6.2  bouyer 	bra.w		LOGBGN			# begin regular log(X)
   8531  1.1.6.2  bouyer 
   8532  1.1.6.2  bouyer Hi_not0:
   8533  1.1.6.2  bouyer 	clr.l		%d6
   8534  1.1.6.2  bouyer 	bfffo		%d4{&0:&32},%d6		# find first 1
   8535  1.1.6.2  bouyer 	mov.l		%d6,%d2			# get k
   8536  1.1.6.2  bouyer 	lsl.l		%d6,%d4
   8537  1.1.6.2  bouyer 	mov.l		%d5,%d7			# a copy of D5
   8538  1.1.6.2  bouyer 	lsl.l		%d6,%d5
   8539  1.1.6.2  bouyer 	neg.l		%d6
   8540  1.1.6.2  bouyer 	add.l		&32,%d6
   8541  1.1.6.2  bouyer 	lsr.l		%d6,%d7
   8542  1.1.6.2  bouyer 	or.l		%d7,%d4			# (D3,D4,D5) normalized
   8543  1.1.6.2  bouyer 
   8544  1.1.6.2  bouyer 	mov.l		%d3,X(%a6)
   8545  1.1.6.2  bouyer 	mov.l		%d4,XFRAC(%a6)
   8546  1.1.6.2  bouyer 	mov.l		%d5,XFRAC+4(%a6)
   8547  1.1.6.2  bouyer 	neg.l		%d2
   8548  1.1.6.2  bouyer 	mov.l		%d2,ADJK(%a6)
   8549  1.1.6.2  bouyer 	fmov.x		X(%a6),%fp0
   8550  1.1.6.2  bouyer 	movm.l		(%sp)+,&0xfc		# restore registers {d2-d7}
   8551  1.1.6.2  bouyer 	lea		X(%a6),%a0
   8552  1.1.6.2  bouyer 	bra.w		LOGBGN			# begin regular log(X)
   8553  1.1.6.2  bouyer 
   8554  1.1.6.2  bouyer 	global		slognp1
   8555  1.1.6.2  bouyer #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
   8556  1.1.6.2  bouyer slognp1:
   8557  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8558  1.1.6.2  bouyer 	fabs.x		%fp0			# test magnitude
   8559  1.1.6.2  bouyer 	fcmp.x		%fp0,LTHOLD(%pc)	# compare with min threshold
   8560  1.1.6.2  bouyer 	fbgt.w		LP1REAL			# if greater, continue
   8561  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   8562  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   8563  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# return signed argument
   8564  1.1.6.2  bouyer 	bra		t_catch
   8565  1.1.6.2  bouyer 
   8566  1.1.6.2  bouyer LP1REAL:
   8567  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0		# LOAD INPUT
   8568  1.1.6.2  bouyer 	mov.l		&0x00000000,ADJK(%a6)
   8569  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1		# FP1 IS INPUT Z
   8570  1.1.6.2  bouyer 	fadd.s		one(%pc),%fp0		# X := ROUND(1+Z)
   8571  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)
   8572  1.1.6.2  bouyer 	mov.w		XFRAC(%a6),XDCARE(%a6)
   8573  1.1.6.2  bouyer 	mov.l		X(%a6),%d1
   8574  1.1.6.2  bouyer 	cmp.l		%d1,&0
   8575  1.1.6.2  bouyer 	ble.w		LP1NEG0			# LOG OF ZERO OR -VE
   8576  1.1.6.2  bouyer 	cmp.l		%d1,&0x3ffe8000 	# IS BOUNDS [1/2,3/2]?
   8577  1.1.6.2  bouyer 	blt.w		LOGMAIN
   8578  1.1.6.2  bouyer 	cmp.l		%d1,&0x3fffc000
   8579  1.1.6.2  bouyer 	bgt.w		LOGMAIN
   8580  1.1.6.2  bouyer #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
   8581  1.1.6.2  bouyer #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
   8582  1.1.6.2  bouyer #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
   8583  1.1.6.2  bouyer 
   8584  1.1.6.2  bouyer LP1NEAR1:
   8585  1.1.6.2  bouyer #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
   8586  1.1.6.2  bouyer 	cmp.l		%d1,&0x3ffef07d
   8587  1.1.6.2  bouyer 	blt.w		LP1CARE
   8588  1.1.6.2  bouyer 	cmp.l		%d1,&0x3fff8841
   8589  1.1.6.2  bouyer 	bgt.w		LP1CARE
   8590  1.1.6.2  bouyer 
   8591  1.1.6.2  bouyer LP1ONE16:
   8592  1.1.6.2  bouyer #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
   8593  1.1.6.2  bouyer #--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
   8594  1.1.6.2  bouyer 	fadd.x		%fp1,%fp1		# FP1 IS 2Z
   8595  1.1.6.2  bouyer 	fadd.s		one(%pc),%fp0		# FP0 IS 1+X
   8596  1.1.6.2  bouyer #--U = FP1/FP0
   8597  1.1.6.2  bouyer 	bra.w		LP1CONT2
   8598  1.1.6.2  bouyer 
   8599  1.1.6.2  bouyer LP1CARE:
   8600  1.1.6.2  bouyer #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
   8601  1.1.6.2  bouyer #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
   8602  1.1.6.2  bouyer #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
   8603  1.1.6.2  bouyer #--THERE ARE ONLY TWO CASES.
   8604  1.1.6.2  bouyer #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
   8605  1.1.6.2  bouyer #--CASE 2: 1+Z > 1, THEN K = 0  AND Y-F = (1-F) + Z
   8606  1.1.6.2  bouyer #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
   8607  1.1.6.2  bouyer #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
   8608  1.1.6.2  bouyer 
   8609  1.1.6.2  bouyer 	mov.l		XFRAC(%a6),FFRAC(%a6)
   8610  1.1.6.2  bouyer 	and.l		&0xFE000000,FFRAC(%a6)
   8611  1.1.6.2  bouyer 	or.l		&0x01000000,FFRAC(%a6)	# F OBTAINED
   8612  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000		# SEE IF 1+Z > 1
   8613  1.1.6.2  bouyer 	bge.b		KISZERO
   8614  1.1.6.2  bouyer 
   8615  1.1.6.2  bouyer KISNEG1:
   8616  1.1.6.2  bouyer 	fmov.s		TWO(%pc),%fp0
   8617  1.1.6.2  bouyer 	mov.l		&0x3fff0000,F(%a6)
   8618  1.1.6.2  bouyer 	clr.l		F+8(%a6)
   8619  1.1.6.2  bouyer 	fsub.x		F(%a6),%fp0		# 2-F
   8620  1.1.6.2  bouyer 	mov.l		FFRAC(%a6),%d1
   8621  1.1.6.2  bouyer 	and.l		&0x7E000000,%d1
   8622  1.1.6.2  bouyer 	asr.l		&8,%d1
   8623  1.1.6.2  bouyer 	asr.l		&8,%d1
   8624  1.1.6.2  bouyer 	asr.l		&4,%d1			# D0 CONTAINS DISPLACEMENT FOR 1/F
   8625  1.1.6.2  bouyer 	fadd.x		%fp1,%fp1		# GET 2Z
   8626  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# SAVE FP2  {%fp2/%fp3}
   8627  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# FP0 IS Y-F = (2-F)+2Z
   8628  1.1.6.2  bouyer 	lea		LOGTBL(%pc),%a0		# A0 IS ADDRESS OF 1/F
   8629  1.1.6.2  bouyer 	add.l		%d1,%a0
   8630  1.1.6.2  bouyer 	fmov.s		negone(%pc),%fp1	# FP1 IS K = -1
   8631  1.1.6.2  bouyer 	bra.w		LP1CONT1
   8632  1.1.6.2  bouyer 
   8633  1.1.6.2  bouyer KISZERO:
   8634  1.1.6.2  bouyer 	fmov.s		one(%pc),%fp0
   8635  1.1.6.2  bouyer 	mov.l		&0x3fff0000,F(%a6)
   8636  1.1.6.2  bouyer 	clr.l		F+8(%a6)
   8637  1.1.6.2  bouyer 	fsub.x		F(%a6),%fp0		# 1-F
   8638  1.1.6.2  bouyer 	mov.l		FFRAC(%a6),%d1
   8639  1.1.6.2  bouyer 	and.l		&0x7E000000,%d1
   8640  1.1.6.2  bouyer 	asr.l		&8,%d1
   8641  1.1.6.2  bouyer 	asr.l		&8,%d1
   8642  1.1.6.2  bouyer 	asr.l		&4,%d1
   8643  1.1.6.2  bouyer 	fadd.x		%fp1,%fp0		# FP0 IS Y-F
   8644  1.1.6.2  bouyer 	fmovm.x		&0xc,-(%sp)		# FP2 SAVED {%fp2/%fp3}
   8645  1.1.6.2  bouyer 	lea		LOGTBL(%pc),%a0
   8646  1.1.6.2  bouyer 	add.l		%d1,%a0			# A0 IS ADDRESS OF 1/F
   8647  1.1.6.2  bouyer 	fmov.s		zero(%pc),%fp1		# FP1 IS K = 0
   8648  1.1.6.2  bouyer 	bra.w		LP1CONT1
   8649  1.1.6.2  bouyer 
   8650  1.1.6.2  bouyer LP1NEG0:
   8651  1.1.6.2  bouyer #--FPCR SAVED. D0 IS X IN COMPACT FORM.
   8652  1.1.6.2  bouyer 	cmp.l		%d1,&0
   8653  1.1.6.2  bouyer 	blt.b		LP1NEG
   8654  1.1.6.2  bouyer LP1ZERO:
   8655  1.1.6.2  bouyer 	fmov.s		negone(%pc),%fp0
   8656  1.1.6.2  bouyer 
   8657  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   8658  1.1.6.2  bouyer 	bra		t_dz
   8659  1.1.6.2  bouyer 
   8660  1.1.6.2  bouyer LP1NEG:
   8661  1.1.6.2  bouyer 	fmov.s		zero(%pc),%fp0
   8662  1.1.6.2  bouyer 
   8663  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   8664  1.1.6.2  bouyer 	bra		t_operr
   8665  1.1.6.2  bouyer 
   8666  1.1.6.2  bouyer 	global		slognp1d
   8667  1.1.6.2  bouyer #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
   8668  1.1.6.2  bouyer # Simply return the denorm
   8669  1.1.6.2  bouyer slognp1d:
   8670  1.1.6.2  bouyer 	bra		t_extdnrm
   8671  1.1.6.2  bouyer 
   8672  1.1.6.2  bouyer #########################################################################
   8673  1.1.6.2  bouyer # satanh():  computes the inverse hyperbolic tangent of a norm input	#
   8674  1.1.6.2  bouyer # satanhd(): computes the inverse hyperbolic tangent of a denorm input	#
   8675  1.1.6.2  bouyer #									#
   8676  1.1.6.2  bouyer # INPUT ***************************************************************	#
   8677  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   8678  1.1.6.2  bouyer #	d0 = round precision,mode					#
   8679  1.1.6.2  bouyer #									#
   8680  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   8681  1.1.6.2  bouyer #	fp0 = arctanh(X)						#
   8682  1.1.6.2  bouyer #									#
   8683  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   8684  1.1.6.2  bouyer #	The returned result is within 3 ulps in	64 significant bit,	#
   8685  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8686  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   8687  1.1.6.2  bouyer #	in double precision.						#
   8688  1.1.6.2  bouyer #									#
   8689  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   8690  1.1.6.2  bouyer #									#
   8691  1.1.6.2  bouyer #	ATANH								#
   8692  1.1.6.2  bouyer #	1. If |X| >= 1, go to 3.					#
   8693  1.1.6.2  bouyer #									#
   8694  1.1.6.2  bouyer #	2. (|X| < 1) Calculate atanh(X) by				#
   8695  1.1.6.2  bouyer #		sgn := sign(X)						#
   8696  1.1.6.2  bouyer #		y := |X|						#
   8697  1.1.6.2  bouyer #		z := 2y/(1-y)						#
   8698  1.1.6.2  bouyer #		atanh(X) := sgn * (1/2) * logp1(z)			#
   8699  1.1.6.2  bouyer #		Exit.							#
   8700  1.1.6.2  bouyer #									#
   8701  1.1.6.2  bouyer #	3. If |X| > 1, go to 5.						#
   8702  1.1.6.2  bouyer #									#
   8703  1.1.6.2  bouyer #	4. (|X| = 1) Generate infinity with an appropriate sign and	#
   8704  1.1.6.2  bouyer #		divide-by-zero by					#
   8705  1.1.6.2  bouyer #		sgn := sign(X)						#
   8706  1.1.6.2  bouyer #		atan(X) := sgn / (+0).					#
   8707  1.1.6.2  bouyer #		Exit.							#
   8708  1.1.6.2  bouyer #									#
   8709  1.1.6.2  bouyer #	5. (|X| > 1) Generate an invalid operation by 0 * infinity.	#
   8710  1.1.6.2  bouyer #		Exit.							#
   8711  1.1.6.2  bouyer #									#
   8712  1.1.6.2  bouyer #########################################################################
   8713  1.1.6.2  bouyer 
   8714  1.1.6.2  bouyer 	global		satanh
   8715  1.1.6.2  bouyer satanh:
   8716  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   8717  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   8718  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   8719  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   8720  1.1.6.2  bouyer 	bge.b		ATANHBIG
   8721  1.1.6.2  bouyer 
   8722  1.1.6.2  bouyer #--THIS IS THE USUAL CASE, |X| < 1
   8723  1.1.6.2  bouyer #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
   8724  1.1.6.2  bouyer 
   8725  1.1.6.2  bouyer 	fabs.x		(%a0),%fp0		# Y = |X|
   8726  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   8727  1.1.6.2  bouyer 	fneg.x		%fp1			# -Y
   8728  1.1.6.2  bouyer 	fadd.x		%fp0,%fp0		# 2Y
   8729  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp1	# 1-Y
   8730  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# 2Y/(1-Y)
   8731  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   8732  1.1.6.2  bouyer 	and.l		&0x80000000,%d1
   8733  1.1.6.2  bouyer 	or.l		&0x3F000000,%d1		# SIGN(X)*HALF
   8734  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)
   8735  1.1.6.2  bouyer 
   8736  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save rnd prec,mode
   8737  1.1.6.2  bouyer 	clr.l		%d0			# pass ext prec,RN
   8738  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save Z on stack
   8739  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass ptr to Z
   8740  1.1.6.2  bouyer 	bsr		slognp1			# LOG1P(Z)
   8741  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear Z from stack
   8742  1.1.6.2  bouyer 
   8743  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# fetch old prec,mode
   8744  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# load it
   8745  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   8746  1.1.6.2  bouyer 	fmul.s		(%sp)+,%fp0
   8747  1.1.6.2  bouyer 	bra		t_catch
   8748  1.1.6.2  bouyer 
   8749  1.1.6.2  bouyer ATANHBIG:
   8750  1.1.6.2  bouyer 	fabs.x		(%a0),%fp0		# |X|
   8751  1.1.6.2  bouyer 	fcmp.s		%fp0,&0x3F800000
   8752  1.1.6.2  bouyer 	fbgt		t_operr
   8753  1.1.6.2  bouyer 	bra		t_dz
   8754  1.1.6.2  bouyer 
   8755  1.1.6.2  bouyer 	global		satanhd
   8756  1.1.6.2  bouyer #--ATANH(X) = X FOR DENORMALIZED X
   8757  1.1.6.2  bouyer satanhd:
   8758  1.1.6.2  bouyer 	bra		t_extdnrm
   8759  1.1.6.2  bouyer 
   8760  1.1.6.2  bouyer #########################################################################
   8761  1.1.6.2  bouyer # slog10():  computes the base-10 logarithm of a normalized input	#
   8762  1.1.6.2  bouyer # slog10d(): computes the base-10 logarithm of a denormalized input	#
   8763  1.1.6.2  bouyer # slog2():   computes the base-2 logarithm of a normalized input	#
   8764  1.1.6.2  bouyer # slog2d():  computes the base-2 logarithm of a denormalized input	#
   8765  1.1.6.2  bouyer #									#
   8766  1.1.6.2  bouyer # INPUT *************************************************************** #
   8767  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   8768  1.1.6.2  bouyer #	d0 = round precision,mode					#
   8769  1.1.6.2  bouyer #									#
   8770  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   8771  1.1.6.2  bouyer #	fp0 = log_10(X) or log_2(X)					#
   8772  1.1.6.2  bouyer #									#
   8773  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   8774  1.1.6.2  bouyer #	The returned result is within 1.7 ulps in 64 significant bit,	#
   8775  1.1.6.2  bouyer #	i.e. within 0.5003 ulp to 53 bits if the result is subsequently	#
   8776  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   8777  1.1.6.2  bouyer #	in double precision.						#
   8778  1.1.6.2  bouyer #									#
   8779  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   8780  1.1.6.2  bouyer #									#
   8781  1.1.6.2  bouyer #       slog10d:							#
   8782  1.1.6.2  bouyer #									#
   8783  1.1.6.2  bouyer #       Step 0.	If X < 0, create a NaN and raise the invalid operation	#
   8784  1.1.6.2  bouyer #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8785  1.1.6.2  bouyer #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8786  1.1.6.2  bouyer #               traps, and precision control = double extended.		#
   8787  1.1.6.2  bouyer #									#
   8788  1.1.6.2  bouyer #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
   8789  1.1.6.2  bouyer #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
   8790  1.1.6.2  bouyer #									#
   8791  1.1.6.2  bouyer #       Step 2.  Compute log_10(X) = log(X) * (1/log(10)).		#
   8792  1.1.6.2  bouyer #            2.1 Restore the user FPCR					#
   8793  1.1.6.2  bouyer #            2.2 Return ans := Y * INV_L10.				#
   8794  1.1.6.2  bouyer #									#
   8795  1.1.6.2  bouyer #       slog10: 							#
   8796  1.1.6.2  bouyer #									#
   8797  1.1.6.2  bouyer #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8798  1.1.6.2  bouyer #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8799  1.1.6.2  bouyer #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8800  1.1.6.2  bouyer #               traps, and precision control = double extended.		#
   8801  1.1.6.2  bouyer #									#
   8802  1.1.6.2  bouyer #       Step 1. Call sLogN to obtain Y = log(X), the natural log of X.	#
   8803  1.1.6.2  bouyer #									#
   8804  1.1.6.2  bouyer #       Step 2.   Compute log_10(X) = log(X) * (1/log(10)).		#
   8805  1.1.6.2  bouyer #            2.1  Restore the user FPCR					#
   8806  1.1.6.2  bouyer #            2.2  Return ans := Y * INV_L10.				#
   8807  1.1.6.2  bouyer #									#
   8808  1.1.6.2  bouyer #       sLog2d:								#
   8809  1.1.6.2  bouyer #									#
   8810  1.1.6.2  bouyer #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8811  1.1.6.2  bouyer #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8812  1.1.6.2  bouyer #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8813  1.1.6.2  bouyer #               traps, and precision control = double extended.		#
   8814  1.1.6.2  bouyer #									#
   8815  1.1.6.2  bouyer #       Step 1. Call slognd to obtain Y = log(X), the natural log of X.	#
   8816  1.1.6.2  bouyer #       Notes:  Even if X is denormalized, log(X) is always normalized.	#
   8817  1.1.6.2  bouyer #									#
   8818  1.1.6.2  bouyer #       Step 2.   Compute log_10(X) = log(X) * (1/log(2)).		#
   8819  1.1.6.2  bouyer #            2.1  Restore the user FPCR					#
   8820  1.1.6.2  bouyer #            2.2  Return ans := Y * INV_L2.				#
   8821  1.1.6.2  bouyer #									#
   8822  1.1.6.2  bouyer #       sLog2:								#
   8823  1.1.6.2  bouyer #									#
   8824  1.1.6.2  bouyer #       Step 0. If X < 0, create a NaN and raise the invalid operation	#
   8825  1.1.6.2  bouyer #               flag. Otherwise, save FPCR in D1; set FpCR to default.	#
   8826  1.1.6.2  bouyer #       Notes:  Default means round-to-nearest mode, no floating-point	#
   8827  1.1.6.2  bouyer #               traps, and precision control = double extended.		#
   8828  1.1.6.2  bouyer #									#
   8829  1.1.6.2  bouyer #       Step 1. If X is not an integer power of two, i.e., X != 2^k,	#
   8830  1.1.6.2  bouyer #               go to Step 3.						#
   8831  1.1.6.2  bouyer #									#
   8832  1.1.6.2  bouyer #       Step 2.   Return k.						#
   8833  1.1.6.2  bouyer #            2.1  Get integer k, X = 2^k.				#
   8834  1.1.6.2  bouyer #            2.2  Restore the user FPCR.				#
   8835  1.1.6.2  bouyer #            2.3  Return ans := convert-to-double-extended(k).		#
   8836  1.1.6.2  bouyer #									#
   8837  1.1.6.2  bouyer #       Step 3. Call sLogN to obtain Y = log(X), the natural log of X.	#
   8838  1.1.6.2  bouyer #									#
   8839  1.1.6.2  bouyer #       Step 4.   Compute log_2(X) = log(X) * (1/log(2)).		#
   8840  1.1.6.2  bouyer #            4.1  Restore the user FPCR					#
   8841  1.1.6.2  bouyer #            4.2  Return ans := Y * INV_L2.				#
   8842  1.1.6.2  bouyer #									#
   8843  1.1.6.2  bouyer #########################################################################
   8844  1.1.6.2  bouyer 
   8845  1.1.6.2  bouyer INV_L10:
   8846  1.1.6.2  bouyer 	long		0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
   8847  1.1.6.2  bouyer 
   8848  1.1.6.2  bouyer INV_L2:
   8849  1.1.6.2  bouyer 	long		0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
   8850  1.1.6.2  bouyer 
   8851  1.1.6.2  bouyer 	global		slog10
   8852  1.1.6.2  bouyer #--entry point for Log10(X), X is normalized
   8853  1.1.6.2  bouyer slog10:
   8854  1.1.6.2  bouyer 	fmov.b		&0x1,%fp0
   8855  1.1.6.2  bouyer 	fcmp.x		%fp0,(%a0)		# if operand == 1,
   8856  1.1.6.2  bouyer 	fbeq.l		ld_pzero		# return an EXACT zero
   8857  1.1.6.2  bouyer 
   8858  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   8859  1.1.6.2  bouyer 	blt.w		invalid
   8860  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   8861  1.1.6.2  bouyer 	clr.l		%d0
   8862  1.1.6.2  bouyer 	bsr		slogn			# log(X), X normal.
   8863  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr
   8864  1.1.6.2  bouyer 	fmul.x		INV_L10(%pc),%fp0
   8865  1.1.6.2  bouyer 	bra		t_inx2
   8866  1.1.6.2  bouyer 
   8867  1.1.6.2  bouyer 	global		slog10d
   8868  1.1.6.2  bouyer #--entry point for Log10(X), X is denormalized
   8869  1.1.6.2  bouyer slog10d:
   8870  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   8871  1.1.6.2  bouyer 	blt.w		invalid
   8872  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   8873  1.1.6.2  bouyer 	clr.l		%d0
   8874  1.1.6.2  bouyer 	bsr		slognd			# log(X), X denorm.
   8875  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr
   8876  1.1.6.2  bouyer 	fmul.x		INV_L10(%pc),%fp0
   8877  1.1.6.2  bouyer 	bra		t_minx2
   8878  1.1.6.2  bouyer 
   8879  1.1.6.2  bouyer 	global		slog2
   8880  1.1.6.2  bouyer #--entry point for Log2(X), X is normalized
   8881  1.1.6.2  bouyer slog2:
   8882  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   8883  1.1.6.2  bouyer 	blt.w		invalid
   8884  1.1.6.2  bouyer 
   8885  1.1.6.2  bouyer 	mov.l		8(%a0),%d1
   8886  1.1.6.2  bouyer 	bne.b		continue		# X is not 2^k
   8887  1.1.6.2  bouyer 
   8888  1.1.6.2  bouyer 	mov.l		4(%a0),%d1
   8889  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   8890  1.1.6.2  bouyer 	bne.b		continue
   8891  1.1.6.2  bouyer 
   8892  1.1.6.2  bouyer #--X = 2^k.
   8893  1.1.6.2  bouyer 	mov.w		(%a0),%d1
   8894  1.1.6.2  bouyer 	and.l		&0x00007FFF,%d1
   8895  1.1.6.2  bouyer 	sub.l		&0x3FFF,%d1
   8896  1.1.6.2  bouyer 	beq.l		ld_pzero
   8897  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   8898  1.1.6.2  bouyer 	fmov.l		%d1,%fp0
   8899  1.1.6.2  bouyer 	bra		t_inx2
   8900  1.1.6.2  bouyer 
   8901  1.1.6.2  bouyer continue:
   8902  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   8903  1.1.6.2  bouyer 	clr.l		%d0
   8904  1.1.6.2  bouyer 	bsr		slogn			# log(X), X normal.
   8905  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr
   8906  1.1.6.2  bouyer 	fmul.x		INV_L2(%pc),%fp0
   8907  1.1.6.2  bouyer 	bra		t_inx2
   8908  1.1.6.2  bouyer 
   8909  1.1.6.2  bouyer invalid:
   8910  1.1.6.2  bouyer 	bra		t_operr
   8911  1.1.6.2  bouyer 
   8912  1.1.6.2  bouyer 	global		slog2d
   8913  1.1.6.2  bouyer #--entry point for Log2(X), X is denormalized
   8914  1.1.6.2  bouyer slog2d:
   8915  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   8916  1.1.6.2  bouyer 	blt.w		invalid
   8917  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   8918  1.1.6.2  bouyer 	clr.l		%d0
   8919  1.1.6.2  bouyer 	bsr		slognd			# log(X), X denorm.
   8920  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr
   8921  1.1.6.2  bouyer 	fmul.x		INV_L2(%pc),%fp0
   8922  1.1.6.2  bouyer 	bra		t_minx2
   8923  1.1.6.2  bouyer 
   8924  1.1.6.2  bouyer #########################################################################
   8925  1.1.6.2  bouyer # stwotox():  computes 2**X for a normalized input			#
   8926  1.1.6.2  bouyer # stwotoxd(): computes 2**X for a denormalized input			#
   8927  1.1.6.2  bouyer # stentox():  computes 10**X for a normalized input			#
   8928  1.1.6.2  bouyer # stentoxd(): computes 10**X for a denormalized input			#
   8929  1.1.6.2  bouyer #									#
   8930  1.1.6.2  bouyer # INPUT ***************************************************************	#
   8931  1.1.6.2  bouyer #	a0 = pointer to extended precision input			#
   8932  1.1.6.2  bouyer #	d0 = round precision,mode					#
   8933  1.1.6.2  bouyer #									#
   8934  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   8935  1.1.6.2  bouyer #	fp0 = 2**X or 10**X						#
   8936  1.1.6.2  bouyer #									#
   8937  1.1.6.2  bouyer # ACCURACY and MONOTONICITY *******************************************	#
   8938  1.1.6.2  bouyer #	The returned result is within 2 ulps in 64 significant bit, 	#
   8939  1.1.6.2  bouyer #	i.e. within 0.5001 ulp to 53 bits if the result is subsequently	#
   8940  1.1.6.2  bouyer #	rounded to double precision. The result is provably monotonic	#
   8941  1.1.6.2  bouyer #	in double precision.						#
   8942  1.1.6.2  bouyer #									#
   8943  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   8944  1.1.6.2  bouyer #									#
   8945  1.1.6.2  bouyer #	twotox								#
   8946  1.1.6.2  bouyer #	1. If |X| > 16480, go to ExpBig.				#
   8947  1.1.6.2  bouyer #									#
   8948  1.1.6.2  bouyer #	2. If |X| < 2**(-70), go to ExpSm.				#
   8949  1.1.6.2  bouyer #									#
   8950  1.1.6.2  bouyer #	3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore	#
   8951  1.1.6.2  bouyer #		decompose N as						#
   8952  1.1.6.2  bouyer #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
   8953  1.1.6.2  bouyer #									#
   8954  1.1.6.2  bouyer #	4. Overwrite r := r * log2. Then				#
   8955  1.1.6.2  bouyer #		2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
   8956  1.1.6.2  bouyer #		Go to expr to compute that expression.			#
   8957  1.1.6.2  bouyer #									#
   8958  1.1.6.2  bouyer #	tentox								#
   8959  1.1.6.2  bouyer #	1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig.	#
   8960  1.1.6.2  bouyer #									#
   8961  1.1.6.2  bouyer #	2. If |X| < 2**(-70), go to ExpSm.				#
   8962  1.1.6.2  bouyer #									#
   8963  1.1.6.2  bouyer #	3. Set y := X*log_2(10)*64 (base 2 log of 10). Set		#
   8964  1.1.6.2  bouyer #		N := round-to-int(y). Decompose N as			#
   8965  1.1.6.2  bouyer #		 N = 64(M + M') + j,  j = 0,1,2,...,63.			#
   8966  1.1.6.2  bouyer #									#
   8967  1.1.6.2  bouyer #	4. Define r as							#
   8968  1.1.6.2  bouyer #		r := ((X - N*L1)-N*L2) * L10				#
   8969  1.1.6.2  bouyer #		where L1, L2 are the leading and trailing parts of 	#
   8970  1.1.6.2  bouyer #		log_10(2)/64 and L10 is the natural log of 10. Then	#
   8971  1.1.6.2  bouyer #		10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r).		#
   8972  1.1.6.2  bouyer #		Go to expr to compute that expression.			#
   8973  1.1.6.2  bouyer #									#
   8974  1.1.6.2  bouyer #	expr								#
   8975  1.1.6.2  bouyer #	1. Fetch 2**(j/64) from table as Fact1 and Fact2.		#
   8976  1.1.6.2  bouyer #									#
   8977  1.1.6.2  bouyer #	2. Overwrite Fact1 and Fact2 by					#
   8978  1.1.6.2  bouyer #		Fact1 := 2**(M) * Fact1					#
   8979  1.1.6.2  bouyer #		Fact2 := 2**(M) * Fact2					#
   8980  1.1.6.2  bouyer #		Thus Fact1 + Fact2 = 2**(M) * 2**(j/64).		#
   8981  1.1.6.2  bouyer #									#
   8982  1.1.6.2  bouyer #	3. Calculate P where 1 + P approximates exp(r):			#
   8983  1.1.6.2  bouyer #		P = r + r*r*(A1+r*(A2+...+r*A5)).			#
   8984  1.1.6.2  bouyer #									#
   8985  1.1.6.2  bouyer #	4. Let AdjFact := 2**(M'). Return				#
   8986  1.1.6.2  bouyer #		AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ).		#
   8987  1.1.6.2  bouyer #		Exit.							#
   8988  1.1.6.2  bouyer #									#
   8989  1.1.6.2  bouyer #	ExpBig								#
   8990  1.1.6.2  bouyer #	1. Generate overflow by Huge * Huge if X > 0; otherwise, 	#
   8991  1.1.6.2  bouyer #	        generate underflow by Tiny * Tiny.			#
   8992  1.1.6.2  bouyer #									#
   8993  1.1.6.2  bouyer #	ExpSm								#
   8994  1.1.6.2  bouyer #	1. Return 1 + X.						#
   8995  1.1.6.2  bouyer #									#
   8996  1.1.6.2  bouyer #########################################################################
   8997  1.1.6.2  bouyer 
   8998  1.1.6.2  bouyer L2TEN64:
   8999  1.1.6.2  bouyer 	long		0x406A934F,0x0979A371	# 64LOG10/LOG2
   9000  1.1.6.2  bouyer L10TWO1:
   9001  1.1.6.2  bouyer 	long		0x3F734413,0x509F8000	# LOG2/64LOG10
   9002  1.1.6.2  bouyer 
   9003  1.1.6.2  bouyer L10TWO2:
   9004  1.1.6.2  bouyer 	long		0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
   9005  1.1.6.2  bouyer 
   9006  1.1.6.2  bouyer LOG10:	long		0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
   9007  1.1.6.2  bouyer 
   9008  1.1.6.2  bouyer LOG2:	long		0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
   9009  1.1.6.2  bouyer 
   9010  1.1.6.2  bouyer EXPA5:	long		0x3F56C16D,0x6F7BD0B2
   9011  1.1.6.2  bouyer EXPA4:	long		0x3F811112,0x302C712C
   9012  1.1.6.2  bouyer EXPA3:	long		0x3FA55555,0x55554CC1
   9013  1.1.6.2  bouyer EXPA2:	long		0x3FC55555,0x55554A54
   9014  1.1.6.2  bouyer EXPA1:	long		0x3FE00000,0x00000000,0x00000000,0x00000000
   9015  1.1.6.2  bouyer 
   9016  1.1.6.2  bouyer TEXPTBL:
   9017  1.1.6.2  bouyer 	long		0x3FFF0000,0x80000000,0x00000000,0x3F738000
   9018  1.1.6.2  bouyer 	long		0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
   9019  1.1.6.2  bouyer 	long		0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
   9020  1.1.6.2  bouyer 	long		0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
   9021  1.1.6.2  bouyer 	long		0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
   9022  1.1.6.2  bouyer 	long		0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
   9023  1.1.6.2  bouyer 	long		0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
   9024  1.1.6.2  bouyer 	long		0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
   9025  1.1.6.2  bouyer 	long		0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
   9026  1.1.6.2  bouyer 	long		0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
   9027  1.1.6.2  bouyer 	long		0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
   9028  1.1.6.2  bouyer 	long		0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
   9029  1.1.6.2  bouyer 	long		0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
   9030  1.1.6.2  bouyer 	long		0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
   9031  1.1.6.2  bouyer 	long		0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
   9032  1.1.6.2  bouyer 	long		0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
   9033  1.1.6.2  bouyer 	long		0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
   9034  1.1.6.2  bouyer 	long		0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
   9035  1.1.6.2  bouyer 	long		0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
   9036  1.1.6.2  bouyer 	long		0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
   9037  1.1.6.2  bouyer 	long		0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
   9038  1.1.6.2  bouyer 	long		0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
   9039  1.1.6.2  bouyer 	long		0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
   9040  1.1.6.2  bouyer 	long		0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
   9041  1.1.6.2  bouyer 	long		0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
   9042  1.1.6.2  bouyer 	long		0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
   9043  1.1.6.2  bouyer 	long		0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
   9044  1.1.6.2  bouyer 	long		0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
   9045  1.1.6.2  bouyer 	long		0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
   9046  1.1.6.2  bouyer 	long		0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
   9047  1.1.6.2  bouyer 	long		0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
   9048  1.1.6.2  bouyer 	long		0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
   9049  1.1.6.2  bouyer 	long		0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
   9050  1.1.6.2  bouyer 	long		0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
   9051  1.1.6.2  bouyer 	long		0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
   9052  1.1.6.2  bouyer 	long		0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
   9053  1.1.6.2  bouyer 	long		0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
   9054  1.1.6.2  bouyer 	long		0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
   9055  1.1.6.2  bouyer 	long		0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
   9056  1.1.6.2  bouyer 	long		0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
   9057  1.1.6.2  bouyer 	long		0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
   9058  1.1.6.2  bouyer 	long		0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
   9059  1.1.6.2  bouyer 	long		0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
   9060  1.1.6.2  bouyer 	long		0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
   9061  1.1.6.2  bouyer 	long		0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
   9062  1.1.6.2  bouyer 	long		0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
   9063  1.1.6.2  bouyer 	long		0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
   9064  1.1.6.2  bouyer 	long		0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
   9065  1.1.6.2  bouyer 	long		0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
   9066  1.1.6.2  bouyer 	long		0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
   9067  1.1.6.2  bouyer 	long		0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
   9068  1.1.6.2  bouyer 	long		0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
   9069  1.1.6.2  bouyer 	long		0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
   9070  1.1.6.2  bouyer 	long		0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
   9071  1.1.6.2  bouyer 	long		0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
   9072  1.1.6.2  bouyer 	long		0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
   9073  1.1.6.2  bouyer 	long		0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
   9074  1.1.6.2  bouyer 	long		0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
   9075  1.1.6.2  bouyer 	long		0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
   9076  1.1.6.2  bouyer 	long		0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
   9077  1.1.6.2  bouyer 	long		0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
   9078  1.1.6.2  bouyer 	long		0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
   9079  1.1.6.2  bouyer 	long		0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
   9080  1.1.6.2  bouyer 	long		0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
   9081  1.1.6.2  bouyer 
   9082  1.1.6.2  bouyer 	set		INT,L_SCR1
   9083  1.1.6.2  bouyer 
   9084  1.1.6.2  bouyer 	set		X,FP_SCR0
   9085  1.1.6.2  bouyer 	set		XDCARE,X+2
   9086  1.1.6.2  bouyer 	set		XFRAC,X+4
   9087  1.1.6.2  bouyer 
   9088  1.1.6.2  bouyer 	set		ADJFACT,FP_SCR0
   9089  1.1.6.2  bouyer 
   9090  1.1.6.2  bouyer 	set		FACT1,FP_SCR0
   9091  1.1.6.2  bouyer 	set		FACT1HI,FACT1+4
   9092  1.1.6.2  bouyer 	set		FACT1LOW,FACT1+8
   9093  1.1.6.2  bouyer 
   9094  1.1.6.2  bouyer 	set		FACT2,FP_SCR1
   9095  1.1.6.2  bouyer 	set		FACT2HI,FACT2+4
   9096  1.1.6.2  bouyer 	set		FACT2LOW,FACT2+8
   9097  1.1.6.2  bouyer 
   9098  1.1.6.2  bouyer 	global		stwotox
   9099  1.1.6.2  bouyer #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   9100  1.1.6.2  bouyer stwotox:
   9101  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# LOAD INPUT
   9102  1.1.6.2  bouyer 
   9103  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   9104  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   9105  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)
   9106  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   9107  1.1.6.2  bouyer 
   9108  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
   9109  1.1.6.2  bouyer 	bge.b		TWOOK1
   9110  1.1.6.2  bouyer 	bra.w		EXPBORS
   9111  1.1.6.2  bouyer 
   9112  1.1.6.2  bouyer TWOOK1:
   9113  1.1.6.2  bouyer 	cmp.l		%d1,&0x400D80C0		# |X| > 16480?
   9114  1.1.6.2  bouyer 	ble.b		TWOMAIN
   9115  1.1.6.2  bouyer 	bra.w		EXPBORS
   9116  1.1.6.2  bouyer 
   9117  1.1.6.2  bouyer TWOMAIN:
   9118  1.1.6.2  bouyer #--USUAL CASE, 2^(-70) <= |X| <= 16480
   9119  1.1.6.2  bouyer 
   9120  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   9121  1.1.6.2  bouyer 	fmul.s		&0x42800000,%fp1	# 64 * X
   9122  1.1.6.2  bouyer 	fmov.l		%fp1,INT(%a6)		# N = ROUND-TO-INT(64 X)
   9123  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)
   9124  1.1.6.2  bouyer 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
   9125  1.1.6.2  bouyer 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
   9126  1.1.6.2  bouyer 	mov.l		INT(%a6),%d1
   9127  1.1.6.2  bouyer 	mov.l		%d1,%d2
   9128  1.1.6.2  bouyer 	and.l		&0x3F,%d1		# D0 IS J
   9129  1.1.6.2  bouyer 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
   9130  1.1.6.2  bouyer 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
   9131  1.1.6.2  bouyer 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
   9132  1.1.6.2  bouyer 	mov.l		%d2,%d1
   9133  1.1.6.2  bouyer 	asr.l		&1,%d1			# D0 IS M
   9134  1.1.6.2  bouyer 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
   9135  1.1.6.2  bouyer 	add.l		&0x3FFF,%d2
   9136  1.1.6.2  bouyer 
   9137  1.1.6.2  bouyer #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
   9138  1.1.6.2  bouyer #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
   9139  1.1.6.2  bouyer #--ADJFACT = 2^(M').
   9140  1.1.6.2  bouyer #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
   9141  1.1.6.2  bouyer 
   9142  1.1.6.2  bouyer 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   9143  1.1.6.2  bouyer 
   9144  1.1.6.2  bouyer 	fmul.s		&0x3C800000,%fp1	# (1/64)*N
   9145  1.1.6.2  bouyer 	mov.l		(%a1)+,FACT1(%a6)
   9146  1.1.6.2  bouyer 	mov.l		(%a1)+,FACT1HI(%a6)
   9147  1.1.6.2  bouyer 	mov.l		(%a1)+,FACT1LOW(%a6)
   9148  1.1.6.2  bouyer 	mov.w		(%a1)+,FACT2(%a6)
   9149  1.1.6.2  bouyer 
   9150  1.1.6.2  bouyer 	fsub.x		%fp1,%fp0		# X - (1/64)*INT(64 X)
   9151  1.1.6.2  bouyer 
   9152  1.1.6.2  bouyer 	mov.w		(%a1)+,FACT2HI(%a6)
   9153  1.1.6.2  bouyer 	clr.w		FACT2HI+2(%a6)
   9154  1.1.6.2  bouyer 	clr.l		FACT2LOW(%a6)
   9155  1.1.6.2  bouyer 	add.w		%d1,FACT1(%a6)
   9156  1.1.6.2  bouyer 	fmul.x		LOG2(%pc),%fp0		# FP0 IS R
   9157  1.1.6.2  bouyer 	add.w		%d1,FACT2(%a6)
   9158  1.1.6.2  bouyer 
   9159  1.1.6.2  bouyer 	bra.w		expr
   9160  1.1.6.2  bouyer 
   9161  1.1.6.2  bouyer EXPBORS:
   9162  1.1.6.2  bouyer #--FPCR, D0 SAVED
   9163  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FFF8000
   9164  1.1.6.2  bouyer 	bgt.b		TEXPBIG
   9165  1.1.6.2  bouyer 
   9166  1.1.6.2  bouyer #--|X| IS SMALL, RETURN 1 + X
   9167  1.1.6.2  bouyer 
   9168  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   9169  1.1.6.2  bouyer 	fadd.s		&0x3F800000,%fp0	# RETURN 1 + X
   9170  1.1.6.2  bouyer 	bra		t_pinx2
   9171  1.1.6.2  bouyer 
   9172  1.1.6.2  bouyer TEXPBIG:
   9173  1.1.6.2  bouyer #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
   9174  1.1.6.2  bouyer #--REGISTERS SAVE SO FAR ARE FPCR AND  D0
   9175  1.1.6.2  bouyer 	mov.l		X(%a6),%d1
   9176  1.1.6.2  bouyer 	cmp.l		%d1,&0
   9177  1.1.6.2  bouyer 	blt.b		EXPNEG
   9178  1.1.6.2  bouyer 
   9179  1.1.6.2  bouyer 	bra		t_ovfl2			# t_ovfl expects positive value
   9180  1.1.6.2  bouyer 
   9181  1.1.6.2  bouyer EXPNEG:
   9182  1.1.6.2  bouyer 	bra		t_unfl2			# t_unfl expects positive value
   9183  1.1.6.2  bouyer 
   9184  1.1.6.2  bouyer 	global		stwotoxd
   9185  1.1.6.2  bouyer stwotoxd:
   9186  1.1.6.2  bouyer #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
   9187  1.1.6.2  bouyer 
   9188  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
   9189  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
   9190  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   9191  1.1.6.2  bouyer 	or.l		&0x00800001,%d1
   9192  1.1.6.2  bouyer 	fadd.s		%d1,%fp0
   9193  1.1.6.2  bouyer 	bra		t_pinx2
   9194  1.1.6.2  bouyer 
   9195  1.1.6.2  bouyer 	global		stentox
   9196  1.1.6.2  bouyer #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
   9197  1.1.6.2  bouyer stentox:
   9198  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# LOAD INPUT
   9199  1.1.6.2  bouyer 
   9200  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   9201  1.1.6.2  bouyer 	mov.w		4(%a0),%d1
   9202  1.1.6.2  bouyer 	fmov.x		%fp0,X(%a6)
   9203  1.1.6.2  bouyer 	and.l		&0x7FFFFFFF,%d1
   9204  1.1.6.2  bouyer 
   9205  1.1.6.2  bouyer 	cmp.l		%d1,&0x3FB98000		# |X| >= 2**(-70)?
   9206  1.1.6.2  bouyer 	bge.b		TENOK1
   9207  1.1.6.2  bouyer 	bra.w		EXPBORS
   9208  1.1.6.2  bouyer 
   9209  1.1.6.2  bouyer TENOK1:
   9210  1.1.6.2  bouyer 	cmp.l		%d1,&0x400B9B07		# |X| <= 16480*log2/log10 ?
   9211  1.1.6.2  bouyer 	ble.b		TENMAIN
   9212  1.1.6.2  bouyer 	bra.w		EXPBORS
   9213  1.1.6.2  bouyer 
   9214  1.1.6.2  bouyer TENMAIN:
   9215  1.1.6.2  bouyer #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
   9216  1.1.6.2  bouyer 
   9217  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   9218  1.1.6.2  bouyer 	fmul.d		L2TEN64(%pc),%fp1	# X*64*LOG10/LOG2
   9219  1.1.6.2  bouyer 	fmov.l		%fp1,INT(%a6)		# N=INT(X*64*LOG10/LOG2)
   9220  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)
   9221  1.1.6.2  bouyer 	lea		TEXPTBL(%pc),%a1	# LOAD ADDRESS OF TABLE OF 2^(J/64)
   9222  1.1.6.2  bouyer 	fmov.l		INT(%a6),%fp1		# N --> FLOATING FMT
   9223  1.1.6.2  bouyer 	mov.l		INT(%a6),%d1
   9224  1.1.6.2  bouyer 	mov.l		%d1,%d2
   9225  1.1.6.2  bouyer 	and.l		&0x3F,%d1		# D0 IS J
   9226  1.1.6.2  bouyer 	asl.l		&4,%d1			# DISPLACEMENT FOR 2^(J/64)
   9227  1.1.6.2  bouyer 	add.l		%d1,%a1			# ADDRESS FOR 2^(J/64)
   9228  1.1.6.2  bouyer 	asr.l		&6,%d2			# d2 IS L, N = 64L + J
   9229  1.1.6.2  bouyer 	mov.l		%d2,%d1
   9230  1.1.6.2  bouyer 	asr.l		&1,%d1			# D0 IS M
   9231  1.1.6.2  bouyer 	sub.l		%d1,%d2			# d2 IS M', N = 64(M+M') + J
   9232  1.1.6.2  bouyer 	add.l		&0x3FFF,%d2
   9233  1.1.6.2  bouyer 
   9234  1.1.6.2  bouyer #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
   9235  1.1.6.2  bouyer #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
   9236  1.1.6.2  bouyer #--ADJFACT = 2^(M').
   9237  1.1.6.2  bouyer #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
   9238  1.1.6.2  bouyer 	fmovm.x		&0x0c,-(%sp)		# save fp2/fp3
   9239  1.1.6.2  bouyer 
   9240  1.1.6.2  bouyer 	fmov.x		%fp1,%fp2
   9241  1.1.6.2  bouyer 
   9242  1.1.6.2  bouyer 	fmul.d		L10TWO1(%pc),%fp1	# N*(LOG2/64LOG10)_LEAD
   9243  1.1.6.2  bouyer 	mov.l		(%a1)+,FACT1(%a6)
   9244  1.1.6.2  bouyer 
   9245  1.1.6.2  bouyer 	fmul.x		L10TWO2(%pc),%fp2	# N*(LOG2/64LOG10)_TRAIL
   9246  1.1.6.2  bouyer 
   9247  1.1.6.2  bouyer 	mov.l		(%a1)+,FACT1HI(%a6)
   9248  1.1.6.2  bouyer 	mov.l		(%a1)+,FACT1LOW(%a6)
   9249  1.1.6.2  bouyer 	fsub.x		%fp1,%fp0		# X - N L_LEAD
   9250  1.1.6.2  bouyer 	mov.w		(%a1)+,FACT2(%a6)
   9251  1.1.6.2  bouyer 
   9252  1.1.6.2  bouyer 	fsub.x		%fp2,%fp0		# X - N L_TRAIL
   9253  1.1.6.2  bouyer 
   9254  1.1.6.2  bouyer 	mov.w		(%a1)+,FACT2HI(%a6)
   9255  1.1.6.2  bouyer 	clr.w		FACT2HI+2(%a6)
   9256  1.1.6.2  bouyer 	clr.l		FACT2LOW(%a6)
   9257  1.1.6.2  bouyer 
   9258  1.1.6.2  bouyer 	fmul.x		LOG10(%pc),%fp0		# FP0 IS R
   9259  1.1.6.2  bouyer 	add.w		%d1,FACT1(%a6)
   9260  1.1.6.2  bouyer 	add.w		%d1,FACT2(%a6)
   9261  1.1.6.2  bouyer 
   9262  1.1.6.2  bouyer expr:
   9263  1.1.6.2  bouyer #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
   9264  1.1.6.2  bouyer #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
   9265  1.1.6.2  bouyer #--FP0 IS R. THE FOLLOWING CODE COMPUTES
   9266  1.1.6.2  bouyer #--	2**(M'+M) * 2**(J/64) * EXP(R)
   9267  1.1.6.2  bouyer 
   9268  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1
   9269  1.1.6.2  bouyer 	fmul.x		%fp1,%fp1		# FP1 IS S = R*R
   9270  1.1.6.2  bouyer 
   9271  1.1.6.2  bouyer 	fmov.d		EXPA5(%pc),%fp2		# FP2 IS A5
   9272  1.1.6.2  bouyer 	fmov.d		EXPA4(%pc),%fp3		# FP3 IS A4
   9273  1.1.6.2  bouyer 
   9274  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# FP2 IS S*A5
   9275  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# FP3 IS S*A4
   9276  1.1.6.2  bouyer 
   9277  1.1.6.2  bouyer 	fadd.d		EXPA3(%pc),%fp2		# FP2 IS A3+S*A5
   9278  1.1.6.2  bouyer 	fadd.d		EXPA2(%pc),%fp3		# FP3 IS A2+S*A4
   9279  1.1.6.2  bouyer 
   9280  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# FP2 IS S*(A3+S*A5)
   9281  1.1.6.2  bouyer 	fmul.x		%fp1,%fp3		# FP3 IS S*(A2+S*A4)
   9282  1.1.6.2  bouyer 
   9283  1.1.6.2  bouyer 	fadd.d		EXPA1(%pc),%fp2		# FP2 IS A1+S*(A3+S*A5)
   9284  1.1.6.2  bouyer 	fmul.x		%fp0,%fp3		# FP3 IS R*S*(A2+S*A4)
   9285  1.1.6.2  bouyer 
   9286  1.1.6.2  bouyer 	fmul.x		%fp1,%fp2		# FP2 IS S*(A1+S*(A3+S*A5))
   9287  1.1.6.2  bouyer 	fadd.x		%fp3,%fp0		# FP0 IS R+R*S*(A2+S*A4)
   9288  1.1.6.2  bouyer 	fadd.x		%fp2,%fp0		# FP0 IS EXP(R) - 1
   9289  1.1.6.2  bouyer 
   9290  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x30		# restore fp2/fp3
   9291  1.1.6.2  bouyer 
   9292  1.1.6.2  bouyer #--FINAL RECONSTRUCTION PROCESS
   9293  1.1.6.2  bouyer #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1)  -  (1 OR 0)
   9294  1.1.6.2  bouyer 
   9295  1.1.6.2  bouyer 	fmul.x		FACT1(%a6),%fp0
   9296  1.1.6.2  bouyer 	fadd.x		FACT2(%a6),%fp0
   9297  1.1.6.2  bouyer 	fadd.x		FACT1(%a6),%fp0
   9298  1.1.6.2  bouyer 
   9299  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# restore users round prec,mode
   9300  1.1.6.2  bouyer 	mov.w		%d2,ADJFACT(%a6)	# INSERT EXPONENT
   9301  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2
   9302  1.1.6.2  bouyer 	mov.l		&0x80000000,ADJFACT+4(%a6)
   9303  1.1.6.2  bouyer 	clr.l		ADJFACT+8(%a6)
   9304  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   9305  1.1.6.2  bouyer 	fmul.x		ADJFACT(%a6),%fp0	# FINAL ADJUSTMENT
   9306  1.1.6.2  bouyer 	bra		t_catch
   9307  1.1.6.2  bouyer 
   9308  1.1.6.2  bouyer 	global		stentoxd
   9309  1.1.6.2  bouyer stentoxd:
   9310  1.1.6.2  bouyer #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
   9311  1.1.6.2  bouyer 
   9312  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# set user's rounding mode/precision
   9313  1.1.6.2  bouyer 	fmov.s		&0x3F800000,%fp0	# RETURN 1 + X
   9314  1.1.6.2  bouyer 	mov.l		(%a0),%d1
   9315  1.1.6.2  bouyer 	or.l		&0x00800001,%d1
   9316  1.1.6.2  bouyer 	fadd.s		%d1,%fp0
   9317  1.1.6.2  bouyer 	bra		t_pinx2
   9318  1.1.6.2  bouyer 
   9319  1.1.6.2  bouyer #########################################################################
   9320  1.1.6.2  bouyer # smovcr(): returns the ROM constant at the offset specified in d1	#
   9321  1.1.6.2  bouyer #	    rounded to the mode and precision specified in d0. 		#
   9322  1.1.6.2  bouyer #									#
   9323  1.1.6.2  bouyer # INPUT	***************************************************************	#
   9324  1.1.6.2  bouyer # 	d0 = rnd prec,mode						#
   9325  1.1.6.2  bouyer #	d1 = ROM offset							#
   9326  1.1.6.2  bouyer #									#
   9327  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   9328  1.1.6.2  bouyer #	fp0 = the ROM constant rounded to the user's rounding mode,prec	#
   9329  1.1.6.2  bouyer #									#
   9330  1.1.6.2  bouyer #########################################################################
   9331  1.1.6.2  bouyer 
   9332  1.1.6.2  bouyer 	global		smovcr
   9333  1.1.6.2  bouyer smovcr:
   9334  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# save rom offset for a sec
   9335  1.1.6.2  bouyer 
   9336  1.1.6.2  bouyer 	lsr.b		&0x4,%d0		# shift ctrl bits to lo
   9337  1.1.6.2  bouyer 	mov.l		%d0,%d1			# make a copy
   9338  1.1.6.2  bouyer 	andi.w		&0x3,%d1		# extract rnd mode
   9339  1.1.6.2  bouyer 	andi.w		&0xc,%d0		# extract rnd prec
   9340  1.1.6.2  bouyer 	swap		%d0			# put rnd prec in hi
   9341  1.1.6.2  bouyer 	mov.w		%d1,%d0			# put rnd mode in lo
   9342  1.1.6.2  bouyer 
   9343  1.1.6.2  bouyer 	mov.l		(%sp)+,%d1		# get rom offset
   9344  1.1.6.2  bouyer 
   9345  1.1.6.2  bouyer #
   9346  1.1.6.2  bouyer # check range of offset
   9347  1.1.6.2  bouyer #
   9348  1.1.6.2  bouyer 	tst.b		%d1			# if zero, offset is to pi
   9349  1.1.6.2  bouyer 	beq.b		pi_tbl			# it is pi
   9350  1.1.6.2  bouyer 	cmpi.b		%d1,&0x0a		# check range $01 - $0a
   9351  1.1.6.2  bouyer 	ble.b		z_val			# if in this range, return zero
   9352  1.1.6.2  bouyer 	cmpi.b		%d1,&0x0e		# check range $0b - $0e
   9353  1.1.6.2  bouyer 	ble.b		sm_tbl			# valid constants in this range
   9354  1.1.6.2  bouyer 	cmpi.b		%d1,&0x2f		# check range $10 - $2f
   9355  1.1.6.2  bouyer 	ble.b		z_val			# if in this range, return zero
   9356  1.1.6.2  bouyer 	cmpi.b		%d1,&0x3f		# check range $30 - $3f
   9357  1.1.6.2  bouyer 	ble.b		bg_tbl			# valid constants in this range
   9358  1.1.6.2  bouyer 
   9359  1.1.6.2  bouyer z_val:
   9360  1.1.6.2  bouyer 	bra.l		ld_pzero		# return a zero
   9361  1.1.6.2  bouyer 
   9362  1.1.6.2  bouyer #
   9363  1.1.6.2  bouyer # the answer is PI rounded to the proper precision.
   9364  1.1.6.2  bouyer #
   9365  1.1.6.2  bouyer # fetch a pointer to the answer table relating to the proper rounding
   9366  1.1.6.2  bouyer # precision.
   9367  1.1.6.2  bouyer #
   9368  1.1.6.2  bouyer pi_tbl:
   9369  1.1.6.2  bouyer 	tst.b		%d0			# is rmode RN?
   9370  1.1.6.2  bouyer 	bne.b		pi_not_rn		# no
   9371  1.1.6.2  bouyer pi_rn:
   9372  1.1.6.2  bouyer 	lea.l		PIRN(%pc),%a0		# yes; load PI RN table addr
   9373  1.1.6.2  bouyer 	bra.w		set_finx
   9374  1.1.6.2  bouyer pi_not_rn:
   9375  1.1.6.2  bouyer 	cmpi.b		%d0,&rp_mode		# is rmode RP?
   9376  1.1.6.2  bouyer 	beq.b		pi_rp			# yes
   9377  1.1.6.2  bouyer pi_rzrm:
   9378  1.1.6.2  bouyer 	lea.l		PIRZRM(%pc),%a0		# no; load PI RZ,RM table addr
   9379  1.1.6.2  bouyer 	bra.b		set_finx
   9380  1.1.6.2  bouyer pi_rp:
   9381  1.1.6.2  bouyer 	lea.l		PIRP(%pc),%a0		# load PI RP table addr
   9382  1.1.6.2  bouyer 	bra.b		set_finx
   9383  1.1.6.2  bouyer 
   9384  1.1.6.2  bouyer #
   9385  1.1.6.2  bouyer # the answer is one of:
   9386  1.1.6.2  bouyer #	$0B	log10(2)	(inexact)
   9387  1.1.6.2  bouyer #	$0C	e		(inexact)
   9388  1.1.6.2  bouyer #	$0D	log2(e)		(inexact)
   9389  1.1.6.2  bouyer #	$0E	log10(e)	(exact)
   9390  1.1.6.2  bouyer #
   9391  1.1.6.2  bouyer # fetch a pointer to the answer table relating to the proper rounding
   9392  1.1.6.2  bouyer # precision.
   9393  1.1.6.2  bouyer #
   9394  1.1.6.2  bouyer sm_tbl:
   9395  1.1.6.2  bouyer 	subi.b		&0xb,%d1		# make offset in 0-4 range
   9396  1.1.6.2  bouyer 	tst.b		%d0			# is rmode RN?
   9397  1.1.6.2  bouyer 	bne.b		sm_not_rn		# no
   9398  1.1.6.2  bouyer sm_rn:
   9399  1.1.6.2  bouyer 	lea.l		SMALRN(%pc),%a0		# yes; load RN table addr
   9400  1.1.6.2  bouyer sm_tbl_cont:
   9401  1.1.6.2  bouyer 	cmpi.b		%d1,&0x2		# is result log10(e)?
   9402  1.1.6.2  bouyer 	ble.b		set_finx		# no; answer is inexact
   9403  1.1.6.2  bouyer 	bra.b		no_finx			# yes; answer is exact
   9404  1.1.6.2  bouyer sm_not_rn:
   9405  1.1.6.2  bouyer 	cmpi.b		%d0,&rp_mode		# is rmode RP?
   9406  1.1.6.2  bouyer 	beq.b		sm_rp			# yes
   9407  1.1.6.2  bouyer sm_rzrm:
   9408  1.1.6.2  bouyer 	lea.l		SMALRZRM(%pc),%a0	# no; load RZ,RM table addr
   9409  1.1.6.2  bouyer 	bra.b		sm_tbl_cont
   9410  1.1.6.2  bouyer sm_rp:
   9411  1.1.6.2  bouyer 	lea.l		SMALRP(%pc),%a0		# load RP table addr
   9412  1.1.6.2  bouyer 	bra.b		sm_tbl_cont
   9413  1.1.6.2  bouyer 
   9414  1.1.6.2  bouyer #
   9415  1.1.6.2  bouyer # the answer is one of:
   9416  1.1.6.2  bouyer #	$30	ln(2)		(inexact)
   9417  1.1.6.2  bouyer #	$31	ln(10)		(inexact)
   9418  1.1.6.2  bouyer #	$32	10^0		(exact)
   9419  1.1.6.2  bouyer #	$33	10^1		(exact)
   9420  1.1.6.2  bouyer #	$34	10^2		(exact)
   9421  1.1.6.2  bouyer #	$35	10^4		(exact)
   9422  1.1.6.2  bouyer #	$36	10^8		(exact)
   9423  1.1.6.2  bouyer #	$37	10^16		(exact)
   9424  1.1.6.2  bouyer #	$38	10^32		(inexact)
   9425  1.1.6.2  bouyer #	$39	10^64		(inexact)
   9426  1.1.6.2  bouyer #	$3A	10^128		(inexact)
   9427  1.1.6.2  bouyer #	$3B	10^256		(inexact)
   9428  1.1.6.2  bouyer #	$3C	10^512		(inexact)
   9429  1.1.6.2  bouyer #	$3D	10^1024		(inexact)
   9430  1.1.6.2  bouyer #	$3E	10^2048		(inexact)
   9431  1.1.6.2  bouyer #	$3F	10^4096		(inexact)
   9432  1.1.6.2  bouyer #
   9433  1.1.6.2  bouyer # fetch a pointer to the answer table relating to the proper rounding
   9434  1.1.6.2  bouyer # precision.
   9435  1.1.6.2  bouyer #
   9436  1.1.6.2  bouyer bg_tbl:
   9437  1.1.6.2  bouyer 	subi.b		&0x30,%d1		# make offset in 0-f range
   9438  1.1.6.2  bouyer 	tst.b		%d0			# is rmode RN?
   9439  1.1.6.2  bouyer 	bne.b		bg_not_rn		# no
   9440  1.1.6.2  bouyer bg_rn:
   9441  1.1.6.2  bouyer 	lea.l		BIGRN(%pc),%a0		# yes; load RN table addr
   9442  1.1.6.2  bouyer bg_tbl_cont:
   9443  1.1.6.2  bouyer 	cmpi.b		%d1,&0x1		# is offset <= $31?
   9444  1.1.6.2  bouyer 	ble.b		set_finx		# yes; answer is inexact
   9445  1.1.6.2  bouyer 	cmpi.b		%d1,&0x7		# is $32 <= offset <= $37?
   9446  1.1.6.2  bouyer 	ble.b		no_finx			# yes; answer is exact
   9447  1.1.6.2  bouyer 	bra.b		set_finx		# no; answer is inexact
   9448  1.1.6.2  bouyer bg_not_rn:
   9449  1.1.6.2  bouyer 	cmpi.b		%d0,&rp_mode		# is rmode RP?
   9450  1.1.6.2  bouyer 	beq.b		bg_rp			# yes
   9451  1.1.6.2  bouyer bg_rzrm:
   9452  1.1.6.2  bouyer 	lea.l		BIGRZRM(%pc),%a0	# no; load RZ,RM table addr
   9453  1.1.6.2  bouyer 	bra.b		bg_tbl_cont
   9454  1.1.6.2  bouyer bg_rp:
   9455  1.1.6.2  bouyer 	lea.l		BIGRP(%pc),%a0		# load RP table addr
   9456  1.1.6.2  bouyer 	bra.b		bg_tbl_cont
   9457  1.1.6.2  bouyer 
   9458  1.1.6.2  bouyer # answer is inexact, so set INEX2 and AINEX in the user's FPSR.
   9459  1.1.6.2  bouyer set_finx:
   9460  1.1.6.2  bouyer 	ori.l		&inx2a_mask,USER_FPSR(%a6) # set INEX2/AINEX
   9461  1.1.6.2  bouyer no_finx:
   9462  1.1.6.2  bouyer 	mulu.w		&0xc,%d1		# offset points into tables
   9463  1.1.6.2  bouyer 	swap		%d0			# put rnd prec in lo word
   9464  1.1.6.2  bouyer 	tst.b		%d0			# is precision extended?
   9465  1.1.6.2  bouyer 
   9466  1.1.6.2  bouyer 	bne.b		not_ext			# if xprec, do not call round
   9467  1.1.6.2  bouyer 
   9468  1.1.6.2  bouyer # Precision is extended
   9469  1.1.6.2  bouyer 	fmovm.x		(%a0,%d1.w),&0x80	# return result in fp0
   9470  1.1.6.2  bouyer 	rts
   9471  1.1.6.2  bouyer 
   9472  1.1.6.2  bouyer # Precision is single or double
   9473  1.1.6.2  bouyer not_ext:
   9474  1.1.6.2  bouyer 	swap		%d0			# rnd prec in upper word
   9475  1.1.6.2  bouyer 
   9476  1.1.6.2  bouyer # call round() to round the answer to the proper precision.
   9477  1.1.6.2  bouyer # exponents out of range for single or double DO NOT cause underflow
   9478  1.1.6.2  bouyer # or overflow.
   9479  1.1.6.2  bouyer 	mov.w		0x0(%a0,%d1.w),FP_SCR1_EX(%a6) # load first word
   9480  1.1.6.2  bouyer 	mov.l		0x4(%a0,%d1.w),FP_SCR1_HI(%a6) # load second word
   9481  1.1.6.2  bouyer 	mov.l		0x8(%a0,%d1.w),FP_SCR1_LO(%a6) # load third word
   9482  1.1.6.2  bouyer 	mov.l		%d0,%d1
   9483  1.1.6.2  bouyer 	clr.l		%d0			# clear g,r,s
   9484  1.1.6.2  bouyer 	lea		FP_SCR1(%a6),%a0	# pass ptr to answer
   9485  1.1.6.2  bouyer 	clr.w		LOCAL_SGN(%a0)		# sign always positive
   9486  1.1.6.2  bouyer 	bsr.l		_round			# round the mantissa
   9487  1.1.6.2  bouyer 
   9488  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return rounded result in fp0
   9489  1.1.6.2  bouyer 	rts
   9490  1.1.6.2  bouyer 
   9491  1.1.6.2  bouyer 	align		0x4
   9492  1.1.6.2  bouyer 
   9493  1.1.6.2  bouyer PIRN:	long		0x40000000,0xc90fdaa2,0x2168c235	# pi
   9494  1.1.6.2  bouyer PIRZRM:	long		0x40000000,0xc90fdaa2,0x2168c234	# pi
   9495  1.1.6.2  bouyer PIRP:	long		0x40000000,0xc90fdaa2,0x2168c235	# pi
   9496  1.1.6.2  bouyer 
   9497  1.1.6.2  bouyer SMALRN:	long		0x3ffd0000,0x9a209a84,0xfbcff798	# log10(2)
   9498  1.1.6.2  bouyer 	long		0x40000000,0xadf85458,0xa2bb4a9a	# e
   9499  1.1.6.2  bouyer 	long		0x3fff0000,0xb8aa3b29,0x5c17f0bc	# log2(e)
   9500  1.1.6.2  bouyer 	long		0x3ffd0000,0xde5bd8a9,0x37287195	# log10(e)
   9501  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000	# 0.0
   9502  1.1.6.2  bouyer 
   9503  1.1.6.2  bouyer SMALRZRM:
   9504  1.1.6.2  bouyer 	long		0x3ffd0000,0x9a209a84,0xfbcff798	# log10(2)
   9505  1.1.6.2  bouyer 	long		0x40000000,0xadf85458,0xa2bb4a9a	# e
   9506  1.1.6.2  bouyer 	long		0x3fff0000,0xb8aa3b29,0x5c17f0bb	# log2(e)
   9507  1.1.6.2  bouyer 	long		0x3ffd0000,0xde5bd8a9,0x37287195	# log10(e)
   9508  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000	# 0.0
   9509  1.1.6.2  bouyer 
   9510  1.1.6.2  bouyer SMALRP:	long		0x3ffd0000,0x9a209a84,0xfbcff799	# log10(2)
   9511  1.1.6.2  bouyer 	long		0x40000000,0xadf85458,0xa2bb4a9b	# e
   9512  1.1.6.2  bouyer 	long		0x3fff0000,0xb8aa3b29,0x5c17f0bc	# log2(e)
   9513  1.1.6.2  bouyer 	long		0x3ffd0000,0xde5bd8a9,0x37287195	# log10(e)
   9514  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000	# 0.0
   9515  1.1.6.2  bouyer 
   9516  1.1.6.2  bouyer BIGRN:	long		0x3ffe0000,0xb17217f7,0xd1cf79ac	# ln(2)
   9517  1.1.6.2  bouyer 	long		0x40000000,0x935d8ddd,0xaaa8ac17	# ln(10)
   9518  1.1.6.2  bouyer 
   9519  1.1.6.2  bouyer 	long		0x3fff0000,0x80000000,0x00000000	# 10 ^ 0
   9520  1.1.6.2  bouyer 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   9521  1.1.6.2  bouyer 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   9522  1.1.6.2  bouyer 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   9523  1.1.6.2  bouyer 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   9524  1.1.6.2  bouyer 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   9525  1.1.6.2  bouyer 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   9526  1.1.6.2  bouyer 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   9527  1.1.6.2  bouyer 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   9528  1.1.6.2  bouyer 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   9529  1.1.6.2  bouyer 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   9530  1.1.6.2  bouyer 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   9531  1.1.6.2  bouyer 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   9532  1.1.6.2  bouyer 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   9533  1.1.6.2  bouyer 
   9534  1.1.6.2  bouyer BIGRZRM:
   9535  1.1.6.2  bouyer 	long		0x3ffe0000,0xb17217f7,0xd1cf79ab	# ln(2)
   9536  1.1.6.2  bouyer 	long		0x40000000,0x935d8ddd,0xaaa8ac16	# ln(10)
   9537  1.1.6.2  bouyer 
   9538  1.1.6.2  bouyer 	long		0x3fff0000,0x80000000,0x00000000	# 10 ^ 0
   9539  1.1.6.2  bouyer 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   9540  1.1.6.2  bouyer 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   9541  1.1.6.2  bouyer 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   9542  1.1.6.2  bouyer 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   9543  1.1.6.2  bouyer 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   9544  1.1.6.2  bouyer 	long		0x40690000,0x9DC5ADA8,0x2B70B59D	# 10 ^ 32
   9545  1.1.6.2  bouyer 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   9546  1.1.6.2  bouyer 	long		0x41A80000,0x93BA47C9,0x80E98CDF	# 10 ^ 128
   9547  1.1.6.2  bouyer 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8D	# 10 ^ 256
   9548  1.1.6.2  bouyer 	long		0x46A30000,0xE319A0AE,0xA60E91C6	# 10 ^ 512
   9549  1.1.6.2  bouyer 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   9550  1.1.6.2  bouyer 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE4	# 10 ^ 2048
   9551  1.1.6.2  bouyer 	long		0x75250000,0xC4605202,0x8A20979A	# 10 ^ 4096
   9552  1.1.6.2  bouyer 
   9553  1.1.6.2  bouyer BIGRP:
   9554  1.1.6.2  bouyer 	long		0x3ffe0000,0xb17217f7,0xd1cf79ac	# ln(2)
   9555  1.1.6.2  bouyer 	long		0x40000000,0x935d8ddd,0xaaa8ac17	# ln(10)
   9556  1.1.6.2  bouyer 
   9557  1.1.6.2  bouyer 	long		0x3fff0000,0x80000000,0x00000000	# 10 ^ 0
   9558  1.1.6.2  bouyer 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   9559  1.1.6.2  bouyer 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   9560  1.1.6.2  bouyer 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   9561  1.1.6.2  bouyer 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   9562  1.1.6.2  bouyer 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   9563  1.1.6.2  bouyer 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   9564  1.1.6.2  bouyer 	long		0x40D30000,0xC2781F49,0xFFCFA6D6	# 10 ^ 64
   9565  1.1.6.2  bouyer 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   9566  1.1.6.2  bouyer 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   9567  1.1.6.2  bouyer 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   9568  1.1.6.2  bouyer 	long		0x4D480000,0xC9767586,0x81750C18	# 10 ^ 1024
   9569  1.1.6.2  bouyer 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   9570  1.1.6.2  bouyer 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   9571  1.1.6.2  bouyer 
   9572  1.1.6.2  bouyer #########################################################################
   9573  1.1.6.2  bouyer # sscale(): computes the destination operand scaled by the source	#
   9574  1.1.6.2  bouyer #	    operand. If the absoulute value of the source operand is 	#
   9575  1.1.6.2  bouyer #	    >= 2^14, an overflow or underflow is returned.		#
   9576  1.1.6.2  bouyer #									#
   9577  1.1.6.2  bouyer # INPUT *************************************************************** #
   9578  1.1.6.2  bouyer #	a0  = pointer to double-extended source operand X		#
   9579  1.1.6.2  bouyer #	a1  = pointer to double-extended destination operand Y		#
   9580  1.1.6.2  bouyer #									#
   9581  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   9582  1.1.6.2  bouyer #	fp0 =  scale(X,Y)						#
   9583  1.1.6.2  bouyer #									#
   9584  1.1.6.2  bouyer #########################################################################
   9585  1.1.6.2  bouyer 
   9586  1.1.6.2  bouyer set	SIGN,		L_SCR1
   9587  1.1.6.2  bouyer 
   9588  1.1.6.2  bouyer 	global		sscale
   9589  1.1.6.2  bouyer sscale:
   9590  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# store off ctrl bits for now
   9591  1.1.6.2  bouyer 
   9592  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),%d1		# get dst exponent
   9593  1.1.6.2  bouyer 	smi.b		SIGN(%a6)		# use SIGN to hold dst sign
   9594  1.1.6.2  bouyer 	andi.l		&0x00007fff,%d1		# strip sign from dst exp
   9595  1.1.6.2  bouyer 
   9596  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0		# check src bounds
   9597  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# clr src sign bit
   9598  1.1.6.2  bouyer 	cmpi.w		%d0,&0x3fff		# is src ~ ZERO?
   9599  1.1.6.2  bouyer 	blt.w		src_small		# yes
   9600  1.1.6.2  bouyer 	cmpi.w		%d0,&0x400c		# no; is src too big?
   9601  1.1.6.2  bouyer 	bgt.w		src_out			# yes
   9602  1.1.6.2  bouyer 
   9603  1.1.6.2  bouyer #
   9604  1.1.6.2  bouyer # Source is within 2^14 range.
   9605  1.1.6.2  bouyer #
   9606  1.1.6.2  bouyer src_ok:
   9607  1.1.6.2  bouyer 	fintrz.x	SRC(%a0),%fp0		# calc int of src
   9608  1.1.6.2  bouyer 	fmov.l		%fp0,%d0		# int src to d0
   9609  1.1.6.2  bouyer # don't want any accrued bits from the fintrz showing up later since
   9610  1.1.6.2  bouyer # we may need to read the fpsr for the last fp op in t_catch2().
   9611  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   9612  1.1.6.2  bouyer 
   9613  1.1.6.2  bouyer 	tst.b		DST_HI(%a1)		# is dst denormalized?
   9614  1.1.6.2  bouyer 	bmi.b		sok_norm
   9615  1.1.6.2  bouyer 
   9616  1.1.6.2  bouyer # the dst is a DENORM. normalize the DENORM and add the adjustment to
   9617  1.1.6.2  bouyer # the src value. then, jump to the norm part of the routine.
   9618  1.1.6.2  bouyer sok_dnrm:
   9619  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save src for now
   9620  1.1.6.2  bouyer 
   9621  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
   9622  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR0_HI(%a6)
   9623  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
   9624  1.1.6.2  bouyer 
   9625  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass ptr to DENORM
   9626  1.1.6.2  bouyer 	bsr.l		norm			# normalize the DENORM
   9627  1.1.6.2  bouyer 	neg.l		%d0
   9628  1.1.6.2  bouyer 	add.l		(%sp)+,%d0		# add adjustment to src
   9629  1.1.6.2  bouyer 
   9630  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# load normalized DENORM
   9631  1.1.6.2  bouyer 
   9632  1.1.6.2  bouyer 	cmpi.w		%d0,&-0x3fff		# is the shft amt really low?
   9633  1.1.6.2  bouyer 	bge.b		sok_norm2		# thank goodness no
   9634  1.1.6.2  bouyer 
   9635  1.1.6.2  bouyer # the multiply factor that we're trying to create should be a denorm
   9636  1.1.6.2  bouyer # for the multiply to work. therefore, we're going to actually do a
   9637  1.1.6.2  bouyer # multiply with a denorm which will cause an unimplemented data type
   9638  1.1.6.2  bouyer # exception to be put into the machine which will be caught and corrected
   9639  1.1.6.2  bouyer # later. we don't do this with the DENORMs above because this method
   9640  1.1.6.2  bouyer # is slower. but, don't fret, I don't see it being used much either.
   9641  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
   9642  1.1.6.2  bouyer 	mov.l		&0x80000000,%d1		# load normalized mantissa
   9643  1.1.6.2  bouyer 	subi.l		&-0x3fff,%d0		# how many should we shift?
   9644  1.1.6.2  bouyer 	neg.l		%d0			# make it positive
   9645  1.1.6.2  bouyer 	cmpi.b		%d0,&0x20		# is it > 32?
   9646  1.1.6.2  bouyer 	bge.b		sok_dnrm_32		# yes
   9647  1.1.6.2  bouyer 	lsr.l		%d0,%d1			# no; bit stays in upper lw
   9648  1.1.6.2  bouyer 	clr.l		-(%sp)			# insert zero low mantissa
   9649  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# insert new high mantissa
   9650  1.1.6.2  bouyer 	clr.l		-(%sp)			# make zero exponent
   9651  1.1.6.2  bouyer 	bra.b		sok_norm_cont
   9652  1.1.6.2  bouyer sok_dnrm_32:
   9653  1.1.6.2  bouyer 	subi.b		&0x20,%d0		# get shift count
   9654  1.1.6.2  bouyer 	lsr.l		%d0,%d1			# make low mantissa longword
   9655  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# insert new low mantissa
   9656  1.1.6.2  bouyer 	clr.l		-(%sp)			# insert zero high mantissa
   9657  1.1.6.2  bouyer 	clr.l		-(%sp)			# make zero exponent
   9658  1.1.6.2  bouyer 	bra.b		sok_norm_cont
   9659  1.1.6.2  bouyer 
   9660  1.1.6.2  bouyer # the src will force the dst to a DENORM value or worse. so, let's
   9661  1.1.6.2  bouyer # create an fp multiply that will create the result.
   9662  1.1.6.2  bouyer sok_norm:
   9663  1.1.6.2  bouyer 	fmovm.x		DST(%a1),&0x80		# load fp0 with normalized src
   9664  1.1.6.2  bouyer sok_norm2:
   9665  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr		# restore user fpcr
   9666  1.1.6.2  bouyer 
   9667  1.1.6.2  bouyer 	addi.w		&0x3fff,%d0		# turn src amt into exp value
   9668  1.1.6.2  bouyer 	swap		%d0			# put exponent in high word
   9669  1.1.6.2  bouyer 	clr.l		-(%sp)			# insert new exponent
   9670  1.1.6.2  bouyer 	mov.l		&0x80000000,-(%sp)	# insert new high mantissa
   9671  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# insert new lo mantissa
   9672  1.1.6.2  bouyer 
   9673  1.1.6.2  bouyer sok_norm_cont:
   9674  1.1.6.2  bouyer 	fmov.l		%fpcr,%d0		# d0 needs fpcr for t_catch2
   9675  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   9676  1.1.6.2  bouyer 	fmul.x		(%sp)+,%fp0		# do the multiply
   9677  1.1.6.2  bouyer 	bra		t_catch2		# catch any exceptions
   9678  1.1.6.2  bouyer 
   9679  1.1.6.2  bouyer #
   9680  1.1.6.2  bouyer # Source is outside of 2^14 range.  Test the sign and branch
   9681  1.1.6.2  bouyer # to the appropriate exception handler.
   9682  1.1.6.2  bouyer #
   9683  1.1.6.2  bouyer src_out:
   9684  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore ctrl bits
   9685  1.1.6.2  bouyer 	exg		%a0,%a1			# swap src,dst ptrs
   9686  1.1.6.2  bouyer 	tst.b		SRC_EX(%a1)		# is src negative?
   9687  1.1.6.2  bouyer 	bmi		t_unfl			# yes; underflow
   9688  1.1.6.2  bouyer 	bra		t_ovfl_sc		# no; overflow
   9689  1.1.6.2  bouyer 
   9690  1.1.6.2  bouyer #
   9691  1.1.6.2  bouyer # The source input is below 1, so we check for denormalized numbers
   9692  1.1.6.2  bouyer # and set unfl.
   9693  1.1.6.2  bouyer #
   9694  1.1.6.2  bouyer src_small:
   9695  1.1.6.2  bouyer 	tst.b		DST_HI(%a1)		# is dst denormalized?
   9696  1.1.6.2  bouyer 	bpl.b		ssmall_done		# yes
   9697  1.1.6.2  bouyer 
   9698  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   9699  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# no; load control bits
   9700  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   9701  1.1.6.2  bouyer 	fmov.x		DST(%a1),%fp0		# simply return dest
   9702  1.1.6.2  bouyer 	bra		t_catch2
   9703  1.1.6.2  bouyer ssmall_done:
   9704  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# load control bits into d1
   9705  1.1.6.2  bouyer 	mov.l		%a1,%a0			# pass ptr to dst
   9706  1.1.6.2  bouyer 	bra		t_resdnrm
   9707  1.1.6.2  bouyer 
   9708  1.1.6.2  bouyer #########################################################################
   9709  1.1.6.2  bouyer # smod(): computes the fp MOD of the input values X,Y.			#
   9710  1.1.6.2  bouyer # srem(): computes the fp (IEEE) REM of the input values X,Y.		#
   9711  1.1.6.2  bouyer #									#
   9712  1.1.6.2  bouyer # INPUT *************************************************************** #
   9713  1.1.6.2  bouyer #	a0 = pointer to extended precision input X			#
   9714  1.1.6.2  bouyer #	a1 = pointer to extended precision input Y			#
   9715  1.1.6.2  bouyer #	d0 = round precision,mode					#
   9716  1.1.6.2  bouyer #									#
   9717  1.1.6.2  bouyer # 	The input operands X and Y can be either normalized or 		#
   9718  1.1.6.2  bouyer #	denormalized.							#
   9719  1.1.6.2  bouyer #									#
   9720  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   9721  1.1.6.2  bouyer #      fp0 = FREM(X,Y) or FMOD(X,Y)					#
   9722  1.1.6.2  bouyer #									#
   9723  1.1.6.2  bouyer # ALGORITHM *********************************************************** #
   9724  1.1.6.2  bouyer #									#
   9725  1.1.6.2  bouyer #       Step 1.  Save and strip signs of X and Y: signX := sign(X),	#
   9726  1.1.6.2  bouyer #                signY := sign(Y), X := |X|, Y := |Y|, 			#
   9727  1.1.6.2  bouyer #                signQ := signX EOR signY. Record whether MOD or REM	#
   9728  1.1.6.2  bouyer #                is requested.						#
   9729  1.1.6.2  bouyer #									#
   9730  1.1.6.2  bouyer #       Step 2.  Set L := expo(X)-expo(Y), k := 0, Q := 0.		#
   9731  1.1.6.2  bouyer #                If (L < 0) then					#
   9732  1.1.6.2  bouyer #                   R := X, go to Step 4.				#
   9733  1.1.6.2  bouyer #                else							#
   9734  1.1.6.2  bouyer #                   R := 2^(-L)X, j := L.				#
   9735  1.1.6.2  bouyer #                endif							#
   9736  1.1.6.2  bouyer #									#
   9737  1.1.6.2  bouyer #       Step 3.  Perform MOD(X,Y)					#
   9738  1.1.6.2  bouyer #            3.1 If R = Y, go to Step 9.				#
   9739  1.1.6.2  bouyer #            3.2 If R > Y, then { R := R - Y, Q := Q + 1}		#
   9740  1.1.6.2  bouyer #            3.3 If j = 0, go to Step 4.				#
   9741  1.1.6.2  bouyer #            3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to	#
   9742  1.1.6.2  bouyer #                Step 3.1.						#
   9743  1.1.6.2  bouyer #									#
   9744  1.1.6.2  bouyer #       Step 4.  At this point, R = X - QY = MOD(X,Y). Set		#
   9745  1.1.6.2  bouyer #                Last_Subtract := false (used in Step 7 below). If	#
   9746  1.1.6.2  bouyer #                MOD is requested, go to Step 6. 			#
   9747  1.1.6.2  bouyer #									#
   9748  1.1.6.2  bouyer #       Step 5.  R = MOD(X,Y), but REM(X,Y) is requested.		#
   9749  1.1.6.2  bouyer #            5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to	#
   9750  1.1.6.2  bouyer #                Step 6.						#
   9751  1.1.6.2  bouyer #            5.2 If R > Y/2, then { set Last_Subtract := true,		#
   9752  1.1.6.2  bouyer #                Q := Q + 1, Y := signY*Y }. Go to Step 6.		#
   9753  1.1.6.2  bouyer #            5.3 This is the tricky case of R = Y/2. If Q is odd,	#
   9754  1.1.6.2  bouyer #                then { Q := Q + 1, signX := -signX }.			#
   9755  1.1.6.2  bouyer #									#
   9756  1.1.6.2  bouyer #       Step 6.  R := signX*R.						#
   9757  1.1.6.2  bouyer #									#
   9758  1.1.6.2  bouyer #       Step 7.  If Last_Subtract = true, R := R - Y.			#
   9759  1.1.6.2  bouyer #									#
   9760  1.1.6.2  bouyer #       Step 8.  Return signQ, last 7 bits of Q, and R as required.	#
   9761  1.1.6.2  bouyer #									#
   9762  1.1.6.2  bouyer #       Step 9.  At this point, R = 2^(-j)*X - Q Y = Y. Thus,		#
   9763  1.1.6.2  bouyer #                X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),		#
   9764  1.1.6.2  bouyer #                R := 0. Return signQ, last 7 bits of Q, and R.		#
   9765  1.1.6.2  bouyer #									#
   9766  1.1.6.2  bouyer #########################################################################
   9767  1.1.6.2  bouyer 
   9768  1.1.6.2  bouyer 	set		Mod_Flag,L_SCR3
   9769  1.1.6.2  bouyer 	set		Sc_Flag,L_SCR3+1
   9770  1.1.6.2  bouyer 
   9771  1.1.6.2  bouyer 	set		SignY,L_SCR2
   9772  1.1.6.2  bouyer 	set		SignX,L_SCR2+2
   9773  1.1.6.2  bouyer 	set		SignQ,L_SCR3+2
   9774  1.1.6.2  bouyer 
   9775  1.1.6.2  bouyer 	set		Y,FP_SCR0
   9776  1.1.6.2  bouyer 	set		Y_Hi,Y+4
   9777  1.1.6.2  bouyer 	set		Y_Lo,Y+8
   9778  1.1.6.2  bouyer 
   9779  1.1.6.2  bouyer 	set		R,FP_SCR1
   9780  1.1.6.2  bouyer 	set		R_Hi,R+4
   9781  1.1.6.2  bouyer 	set		R_Lo,R+8
   9782  1.1.6.2  bouyer 
   9783  1.1.6.2  bouyer Scale:
   9784  1.1.6.2  bouyer 	long		0x00010000,0x80000000,0x00000000,0x00000000
   9785  1.1.6.2  bouyer 
   9786  1.1.6.2  bouyer 	global		smod
   9787  1.1.6.2  bouyer smod:
   9788  1.1.6.2  bouyer 	clr.b		FPSR_QBYTE(%a6)
   9789  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save ctrl bits
   9790  1.1.6.2  bouyer 	clr.b		Mod_Flag(%a6)
   9791  1.1.6.2  bouyer 	bra.b		Mod_Rem
   9792  1.1.6.2  bouyer 
   9793  1.1.6.2  bouyer 	global		srem
   9794  1.1.6.2  bouyer srem:
   9795  1.1.6.2  bouyer 	clr.b		FPSR_QBYTE(%a6)
   9796  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save ctrl bits
   9797  1.1.6.2  bouyer 	mov.b		&0x1,Mod_Flag(%a6)
   9798  1.1.6.2  bouyer 
   9799  1.1.6.2  bouyer Mod_Rem:
   9800  1.1.6.2  bouyer #..Save sign of X and Y
   9801  1.1.6.2  bouyer 	movm.l		&0x3f00,-(%sp)		# save data registers
   9802  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d3
   9803  1.1.6.2  bouyer 	mov.w		%d3,SignY(%a6)
   9804  1.1.6.2  bouyer 	and.l		&0x00007FFF,%d3		# Y := |Y|
   9805  1.1.6.2  bouyer 
   9806  1.1.6.2  bouyer #
   9807  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),%d4
   9808  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),%d5		# (D3,D4,D5) is |Y|
   9809  1.1.6.2  bouyer 
   9810  1.1.6.2  bouyer 	tst.l		%d3
   9811  1.1.6.2  bouyer 	bne.b		Y_Normal
   9812  1.1.6.2  bouyer 
   9813  1.1.6.2  bouyer 	mov.l		&0x00003FFE,%d3		# $3FFD + 1
   9814  1.1.6.2  bouyer 	tst.l		%d4
   9815  1.1.6.2  bouyer 	bne.b		HiY_not0
   9816  1.1.6.2  bouyer 
   9817  1.1.6.2  bouyer HiY_0:
   9818  1.1.6.2  bouyer 	mov.l		%d5,%d4
   9819  1.1.6.2  bouyer 	clr.l		%d5
   9820  1.1.6.2  bouyer 	sub.l		&32,%d3
   9821  1.1.6.2  bouyer 	clr.l		%d6
   9822  1.1.6.2  bouyer 	bfffo		%d4{&0:&32},%d6
   9823  1.1.6.2  bouyer 	lsl.l		%d6,%d4
   9824  1.1.6.2  bouyer 	sub.l		%d6,%d3			# (D3,D4,D5) is normalized
   9825  1.1.6.2  bouyer #	                                        ...with bias $7FFD
   9826  1.1.6.2  bouyer 	bra.b		Chk_X
   9827  1.1.6.2  bouyer 
   9828  1.1.6.2  bouyer HiY_not0:
   9829  1.1.6.2  bouyer 	clr.l		%d6
   9830  1.1.6.2  bouyer 	bfffo		%d4{&0:&32},%d6
   9831  1.1.6.2  bouyer 	sub.l		%d6,%d3
   9832  1.1.6.2  bouyer 	lsl.l		%d6,%d4
   9833  1.1.6.2  bouyer 	mov.l		%d5,%d7			# a copy of D5
   9834  1.1.6.2  bouyer 	lsl.l		%d6,%d5
   9835  1.1.6.2  bouyer 	neg.l		%d6
   9836  1.1.6.2  bouyer 	add.l		&32,%d6
   9837  1.1.6.2  bouyer 	lsr.l		%d6,%d7
   9838  1.1.6.2  bouyer 	or.l		%d7,%d4			# (D3,D4,D5) normalized
   9839  1.1.6.2  bouyer #                                       ...with bias $7FFD
   9840  1.1.6.2  bouyer 	bra.b		Chk_X
   9841  1.1.6.2  bouyer 
   9842  1.1.6.2  bouyer Y_Normal:
   9843  1.1.6.2  bouyer 	add.l		&0x00003FFE,%d3		# (D3,D4,D5) normalized
   9844  1.1.6.2  bouyer #                                       ...with bias $7FFD
   9845  1.1.6.2  bouyer 
   9846  1.1.6.2  bouyer Chk_X:
   9847  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),%d0
   9848  1.1.6.2  bouyer 	mov.w		%d0,SignX(%a6)
   9849  1.1.6.2  bouyer 	mov.w		SignY(%a6),%d1
   9850  1.1.6.2  bouyer 	eor.l		%d0,%d1
   9851  1.1.6.2  bouyer 	and.l		&0x00008000,%d1
   9852  1.1.6.2  bouyer 	mov.w		%d1,SignQ(%a6)		# sign(Q) obtained
   9853  1.1.6.2  bouyer 	and.l		&0x00007FFF,%d0
   9854  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),%d1
   9855  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),%d2		# (D0,D1,D2) is |X|
   9856  1.1.6.2  bouyer 	tst.l		%d0
   9857  1.1.6.2  bouyer 	bne.b		X_Normal
   9858  1.1.6.2  bouyer 	mov.l		&0x00003FFE,%d0
   9859  1.1.6.2  bouyer 	tst.l		%d1
   9860  1.1.6.2  bouyer 	bne.b		HiX_not0
   9861  1.1.6.2  bouyer 
   9862  1.1.6.2  bouyer HiX_0:
   9863  1.1.6.2  bouyer 	mov.l		%d2,%d1
   9864  1.1.6.2  bouyer 	clr.l		%d2
   9865  1.1.6.2  bouyer 	sub.l		&32,%d0
   9866  1.1.6.2  bouyer 	clr.l		%d6
   9867  1.1.6.2  bouyer 	bfffo		%d1{&0:&32},%d6
   9868  1.1.6.2  bouyer 	lsl.l		%d6,%d1
   9869  1.1.6.2  bouyer 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
   9870  1.1.6.2  bouyer #                                       ...with bias $7FFD
   9871  1.1.6.2  bouyer 	bra.b		Init
   9872  1.1.6.2  bouyer 
   9873  1.1.6.2  bouyer HiX_not0:
   9874  1.1.6.2  bouyer 	clr.l		%d6
   9875  1.1.6.2  bouyer 	bfffo		%d1{&0:&32},%d6
   9876  1.1.6.2  bouyer 	sub.l		%d6,%d0
   9877  1.1.6.2  bouyer 	lsl.l		%d6,%d1
   9878  1.1.6.2  bouyer 	mov.l		%d2,%d7			# a copy of D2
   9879  1.1.6.2  bouyer 	lsl.l		%d6,%d2
   9880  1.1.6.2  bouyer 	neg.l		%d6
   9881  1.1.6.2  bouyer 	add.l		&32,%d6
   9882  1.1.6.2  bouyer 	lsr.l		%d6,%d7
   9883  1.1.6.2  bouyer 	or.l		%d7,%d1			# (D0,D1,D2) normalized
   9884  1.1.6.2  bouyer #                                       ...with bias $7FFD
   9885  1.1.6.2  bouyer 	bra.b		Init
   9886  1.1.6.2  bouyer 
   9887  1.1.6.2  bouyer X_Normal:
   9888  1.1.6.2  bouyer 	add.l		&0x00003FFE,%d0		# (D0,D1,D2) normalized
   9889  1.1.6.2  bouyer #                                       ...with bias $7FFD
   9890  1.1.6.2  bouyer 
   9891  1.1.6.2  bouyer Init:
   9892  1.1.6.2  bouyer #
   9893  1.1.6.2  bouyer 	mov.l		%d3,L_SCR1(%a6)		# save biased exp(Y)
   9894  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save biased exp(X)
   9895  1.1.6.2  bouyer 	sub.l		%d3,%d0			# L := expo(X)-expo(Y)
   9896  1.1.6.2  bouyer 
   9897  1.1.6.2  bouyer 	clr.l		%d6			# D6 := carry <- 0
   9898  1.1.6.2  bouyer 	clr.l		%d3			# D3 is Q
   9899  1.1.6.2  bouyer 	mov.l		&0,%a1			# A1 is k; j+k=L, Q=0
   9900  1.1.6.2  bouyer 
   9901  1.1.6.2  bouyer #..(Carry,D1,D2) is R
   9902  1.1.6.2  bouyer 	tst.l		%d0
   9903  1.1.6.2  bouyer 	bge.b		Mod_Loop_pre
   9904  1.1.6.2  bouyer 
   9905  1.1.6.2  bouyer #..expo(X) < expo(Y). Thus X = mod(X,Y)
   9906  1.1.6.2  bouyer #
   9907  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore d0
   9908  1.1.6.2  bouyer 	bra.w		Get_Mod
   9909  1.1.6.2  bouyer 
   9910  1.1.6.2  bouyer Mod_Loop_pre:
   9911  1.1.6.2  bouyer 	addq.l		&0x4,%sp		# erase exp(X)
   9912  1.1.6.2  bouyer #..At this point  R = 2^(-L)X; Q = 0; k = 0; and  k+j = L
   9913  1.1.6.2  bouyer Mod_Loop:
   9914  1.1.6.2  bouyer 	tst.l		%d6			# test carry bit
   9915  1.1.6.2  bouyer 	bgt.b		R_GT_Y
   9916  1.1.6.2  bouyer 
   9917  1.1.6.2  bouyer #..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
   9918  1.1.6.2  bouyer 	cmp.l		%d1,%d4			# compare hi(R) and hi(Y)
   9919  1.1.6.2  bouyer 	bne.b		R_NE_Y
   9920  1.1.6.2  bouyer 	cmp.l		%d2,%d5			# compare lo(R) and lo(Y)
   9921  1.1.6.2  bouyer 	bne.b		R_NE_Y
   9922  1.1.6.2  bouyer 
   9923  1.1.6.2  bouyer #..At this point, R = Y
   9924  1.1.6.2  bouyer 	bra.w		Rem_is_0
   9925  1.1.6.2  bouyer 
   9926  1.1.6.2  bouyer R_NE_Y:
   9927  1.1.6.2  bouyer #..use the borrow of the previous compare
   9928  1.1.6.2  bouyer 	bcs.b		R_LT_Y			# borrow is set iff R < Y
   9929  1.1.6.2  bouyer 
   9930  1.1.6.2  bouyer R_GT_Y:
   9931  1.1.6.2  bouyer #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
   9932  1.1.6.2  bouyer #..and Y < (D1,D2) < 2Y. Either way, perform R - Y
   9933  1.1.6.2  bouyer 	sub.l		%d5,%d2			# lo(R) - lo(Y)
   9934  1.1.6.2  bouyer 	subx.l		%d4,%d1			# hi(R) - hi(Y)
   9935  1.1.6.2  bouyer 	clr.l		%d6			# clear carry
   9936  1.1.6.2  bouyer 	addq.l		&1,%d3			# Q := Q + 1
   9937  1.1.6.2  bouyer 
   9938  1.1.6.2  bouyer R_LT_Y:
   9939  1.1.6.2  bouyer #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
   9940  1.1.6.2  bouyer 	tst.l		%d0			# see if j = 0.
   9941  1.1.6.2  bouyer 	beq.b		PostLoop
   9942  1.1.6.2  bouyer 
   9943  1.1.6.2  bouyer 	add.l		%d3,%d3			# Q := 2Q
   9944  1.1.6.2  bouyer 	add.l		%d2,%d2			# lo(R) = 2lo(R)
   9945  1.1.6.2  bouyer 	roxl.l		&1,%d1			# hi(R) = 2hi(R) + carry
   9946  1.1.6.2  bouyer 	scs		%d6			# set Carry if 2(R) overflows
   9947  1.1.6.2  bouyer 	addq.l		&1,%a1			# k := k+1
   9948  1.1.6.2  bouyer 	subq.l		&1,%d0			# j := j - 1
   9949  1.1.6.2  bouyer #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
   9950  1.1.6.2  bouyer 
   9951  1.1.6.2  bouyer 	bra.b		Mod_Loop
   9952  1.1.6.2  bouyer 
   9953  1.1.6.2  bouyer PostLoop:
   9954  1.1.6.2  bouyer #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
   9955  1.1.6.2  bouyer 
   9956  1.1.6.2  bouyer #..normalize R.
   9957  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d0		# new biased expo of R
   9958  1.1.6.2  bouyer 	tst.l		%d1
   9959  1.1.6.2  bouyer 	bne.b		HiR_not0
   9960  1.1.6.2  bouyer 
   9961  1.1.6.2  bouyer HiR_0:
   9962  1.1.6.2  bouyer 	mov.l		%d2,%d1
   9963  1.1.6.2  bouyer 	clr.l		%d2
   9964  1.1.6.2  bouyer 	sub.l		&32,%d0
   9965  1.1.6.2  bouyer 	clr.l		%d6
   9966  1.1.6.2  bouyer 	bfffo		%d1{&0:&32},%d6
   9967  1.1.6.2  bouyer 	lsl.l		%d6,%d1
   9968  1.1.6.2  bouyer 	sub.l		%d6,%d0			# (D0,D1,D2) is normalized
   9969  1.1.6.2  bouyer #                                       ...with bias $7FFD
   9970  1.1.6.2  bouyer 	bra.b		Get_Mod
   9971  1.1.6.2  bouyer 
   9972  1.1.6.2  bouyer HiR_not0:
   9973  1.1.6.2  bouyer 	clr.l		%d6
   9974  1.1.6.2  bouyer 	bfffo		%d1{&0:&32},%d6
   9975  1.1.6.2  bouyer 	bmi.b		Get_Mod			# already normalized
   9976  1.1.6.2  bouyer 	sub.l		%d6,%d0
   9977  1.1.6.2  bouyer 	lsl.l		%d6,%d1
   9978  1.1.6.2  bouyer 	mov.l		%d2,%d7			# a copy of D2
   9979  1.1.6.2  bouyer 	lsl.l		%d6,%d2
   9980  1.1.6.2  bouyer 	neg.l		%d6
   9981  1.1.6.2  bouyer 	add.l		&32,%d6
   9982  1.1.6.2  bouyer 	lsr.l		%d6,%d7
   9983  1.1.6.2  bouyer 	or.l		%d7,%d1			# (D0,D1,D2) normalized
   9984  1.1.6.2  bouyer 
   9985  1.1.6.2  bouyer #
   9986  1.1.6.2  bouyer Get_Mod:
   9987  1.1.6.2  bouyer 	cmp.l		%d0,&0x000041FE
   9988  1.1.6.2  bouyer 	bge.b		No_Scale
   9989  1.1.6.2  bouyer Do_Scale:
   9990  1.1.6.2  bouyer 	mov.w		%d0,R(%a6)
   9991  1.1.6.2  bouyer 	mov.l		%d1,R_Hi(%a6)
   9992  1.1.6.2  bouyer 	mov.l		%d2,R_Lo(%a6)
   9993  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d6
   9994  1.1.6.2  bouyer 	mov.w		%d6,Y(%a6)
   9995  1.1.6.2  bouyer 	mov.l		%d4,Y_Hi(%a6)
   9996  1.1.6.2  bouyer 	mov.l		%d5,Y_Lo(%a6)
   9997  1.1.6.2  bouyer 	fmov.x		R(%a6),%fp0		# no exception
   9998  1.1.6.2  bouyer 	mov.b		&1,Sc_Flag(%a6)
   9999  1.1.6.2  bouyer 	bra.b		ModOrRem
   10000  1.1.6.2  bouyer No_Scale:
   10001  1.1.6.2  bouyer 	mov.l		%d1,R_Hi(%a6)
   10002  1.1.6.2  bouyer 	mov.l		%d2,R_Lo(%a6)
   10003  1.1.6.2  bouyer 	sub.l		&0x3FFE,%d0
   10004  1.1.6.2  bouyer 	mov.w		%d0,R(%a6)
   10005  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d6
   10006  1.1.6.2  bouyer 	sub.l		&0x3FFE,%d6
   10007  1.1.6.2  bouyer 	mov.l		%d6,L_SCR1(%a6)
   10008  1.1.6.2  bouyer 	fmov.x		R(%a6),%fp0
   10009  1.1.6.2  bouyer 	mov.w		%d6,Y(%a6)
   10010  1.1.6.2  bouyer 	mov.l		%d4,Y_Hi(%a6)
   10011  1.1.6.2  bouyer 	mov.l		%d5,Y_Lo(%a6)
   10012  1.1.6.2  bouyer 	clr.b		Sc_Flag(%a6)
   10013  1.1.6.2  bouyer 
   10014  1.1.6.2  bouyer #
   10015  1.1.6.2  bouyer ModOrRem:
   10016  1.1.6.2  bouyer 	tst.b		Mod_Flag(%a6)
   10017  1.1.6.2  bouyer 	beq.b		Fix_Sign
   10018  1.1.6.2  bouyer 
   10019  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d6		# new biased expo(Y)
   10020  1.1.6.2  bouyer 	subq.l		&1,%d6			# biased expo(Y/2)
   10021  1.1.6.2  bouyer 	cmp.l		%d0,%d6
   10022  1.1.6.2  bouyer 	blt.b		Fix_Sign
   10023  1.1.6.2  bouyer 	bgt.b		Last_Sub
   10024  1.1.6.2  bouyer 
   10025  1.1.6.2  bouyer 	cmp.l		%d1,%d4
   10026  1.1.6.2  bouyer 	bne.b		Not_EQ
   10027  1.1.6.2  bouyer 	cmp.l		%d2,%d5
   10028  1.1.6.2  bouyer 	bne.b		Not_EQ
   10029  1.1.6.2  bouyer 	bra.w		Tie_Case
   10030  1.1.6.2  bouyer 
   10031  1.1.6.2  bouyer Not_EQ:
   10032  1.1.6.2  bouyer 	bcs.b		Fix_Sign
   10033  1.1.6.2  bouyer 
   10034  1.1.6.2  bouyer Last_Sub:
   10035  1.1.6.2  bouyer #
   10036  1.1.6.2  bouyer 	fsub.x		Y(%a6),%fp0		# no exceptions
   10037  1.1.6.2  bouyer 	addq.l		&1,%d3			# Q := Q + 1
   10038  1.1.6.2  bouyer 
   10039  1.1.6.2  bouyer #
   10040  1.1.6.2  bouyer Fix_Sign:
   10041  1.1.6.2  bouyer #..Get sign of X
   10042  1.1.6.2  bouyer 	mov.w		SignX(%a6),%d6
   10043  1.1.6.2  bouyer 	bge.b		Get_Q
   10044  1.1.6.2  bouyer 	fneg.x		%fp0
   10045  1.1.6.2  bouyer 
   10046  1.1.6.2  bouyer #..Get Q
   10047  1.1.6.2  bouyer #
   10048  1.1.6.2  bouyer Get_Q:
   10049  1.1.6.2  bouyer 	clr.l		%d6
   10050  1.1.6.2  bouyer 	mov.w		SignQ(%a6),%d6		# D6 is sign(Q)
   10051  1.1.6.2  bouyer 	mov.l		&8,%d7
   10052  1.1.6.2  bouyer 	lsr.l		%d7,%d6
   10053  1.1.6.2  bouyer 	and.l		&0x0000007F,%d3		# 7 bits of Q
   10054  1.1.6.2  bouyer 	or.l		%d6,%d3			# sign and bits of Q
   10055  1.1.6.2  bouyer #	swap		%d3
   10056  1.1.6.2  bouyer #	fmov.l		%fpsr,%d6
   10057  1.1.6.2  bouyer #	and.l		&0xFF00FFFF,%d6
   10058  1.1.6.2  bouyer #	or.l		%d3,%d6
   10059  1.1.6.2  bouyer #	fmov.l		%d6,%fpsr		# put Q in fpsr
   10060  1.1.6.2  bouyer 	mov.b		%d3,FPSR_QBYTE(%a6)	# put Q in fpsr
   10061  1.1.6.2  bouyer 
   10062  1.1.6.2  bouyer #
   10063  1.1.6.2  bouyer Restore:
   10064  1.1.6.2  bouyer 	movm.l		(%sp)+,&0xfc		#  {%d2-%d7}
   10065  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   10066  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   10067  1.1.6.2  bouyer 	tst.b		Sc_Flag(%a6)
   10068  1.1.6.2  bouyer 	beq.b		Finish
   10069  1.1.6.2  bouyer 	mov.b		&FMUL_OP,%d1		# last inst is MUL
   10070  1.1.6.2  bouyer 	fmul.x		Scale(%pc),%fp0		# may cause underflow
   10071  1.1.6.2  bouyer 	bra		t_catch2
   10072  1.1.6.2  bouyer # the '040 package did this apparently to see if the dst operand for the
   10073  1.1.6.2  bouyer # preceding fmul was a denorm. but, it better not have been since the
   10074  1.1.6.2  bouyer # algorithm just got done playing with fp0 and expected no exceptions
   10075  1.1.6.2  bouyer # as a result. trust me...
   10076  1.1.6.2  bouyer #	bra		t_avoid_unsupp		# check for denorm as a
   10077  1.1.6.2  bouyer #						;result of the scaling
   10078  1.1.6.2  bouyer 
   10079  1.1.6.2  bouyer Finish:
   10080  1.1.6.2  bouyer 	mov.b		&FMOV_OP,%d1		# last inst is MOVE
   10081  1.1.6.2  bouyer 	fmov.x		%fp0,%fp0		# capture exceptions & round
   10082  1.1.6.2  bouyer 	bra		t_catch2
   10083  1.1.6.2  bouyer 
   10084  1.1.6.2  bouyer Rem_is_0:
   10085  1.1.6.2  bouyer #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
   10086  1.1.6.2  bouyer 	addq.l		&1,%d3
   10087  1.1.6.2  bouyer 	cmp.l		%d0,&8			# D0 is j
   10088  1.1.6.2  bouyer 	bge.b		Q_Big
   10089  1.1.6.2  bouyer 
   10090  1.1.6.2  bouyer 	lsl.l		%d0,%d3
   10091  1.1.6.2  bouyer 	bra.b		Set_R_0
   10092  1.1.6.2  bouyer 
   10093  1.1.6.2  bouyer Q_Big:
   10094  1.1.6.2  bouyer 	clr.l		%d3
   10095  1.1.6.2  bouyer 
   10096  1.1.6.2  bouyer Set_R_0:
   10097  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0
   10098  1.1.6.2  bouyer 	clr.b		Sc_Flag(%a6)
   10099  1.1.6.2  bouyer 	bra.w		Fix_Sign
   10100  1.1.6.2  bouyer 
   10101  1.1.6.2  bouyer Tie_Case:
   10102  1.1.6.2  bouyer #..Check parity of Q
   10103  1.1.6.2  bouyer 	mov.l		%d3,%d6
   10104  1.1.6.2  bouyer 	and.l		&0x00000001,%d6
   10105  1.1.6.2  bouyer 	tst.l		%d6
   10106  1.1.6.2  bouyer 	beq.w		Fix_Sign		# Q is even
   10107  1.1.6.2  bouyer 
   10108  1.1.6.2  bouyer #..Q is odd, Q := Q + 1, signX := -signX
   10109  1.1.6.2  bouyer 	addq.l		&1,%d3
   10110  1.1.6.2  bouyer 	mov.w		SignX(%a6),%d6
   10111  1.1.6.2  bouyer 	eor.l		&0x00008000,%d6
   10112  1.1.6.2  bouyer 	mov.w		%d6,SignX(%a6)
   10113  1.1.6.2  bouyer 	bra.w		Fix_Sign
   10114  1.1.6.2  bouyer 
   10115  1.1.6.2  bouyer qnan:	long		0x7fff0000, 0xffffffff, 0xffffffff
   10116  1.1.6.2  bouyer 
   10117  1.1.6.2  bouyer #########################################################################
   10118  1.1.6.2  bouyer # XDEF ****************************************************************	#
   10119  1.1.6.2  bouyer #	t_dz(): Handle DZ exception during transcendental emulation.	#
   10120  1.1.6.2  bouyer #	        Sets N bit according to sign of source operand.		#
   10121  1.1.6.2  bouyer #	t_dz2(): Handle DZ exception during transcendental emulation.	#
   10122  1.1.6.2  bouyer #		 Sets N bit always.					#
   10123  1.1.6.2  bouyer #									#
   10124  1.1.6.2  bouyer # XREF ****************************************************************	#
   10125  1.1.6.2  bouyer #	None								#
   10126  1.1.6.2  bouyer #									#
   10127  1.1.6.2  bouyer # INPUT ***************************************************************	#
   10128  1.1.6.2  bouyer #	a0 = pointer to source operand					#
   10129  1.1.6.2  bouyer # 									#
   10130  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   10131  1.1.6.2  bouyer #	fp0 = default result						#
   10132  1.1.6.2  bouyer #									#
   10133  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   10134  1.1.6.2  bouyer #	- Store properly signed INF into fp0.				#
   10135  1.1.6.2  bouyer #	- Set FPSR exception status dz bit, ccode inf bit, and 		#
   10136  1.1.6.2  bouyer #	  accrued dz bit.						#
   10137  1.1.6.2  bouyer #									#
   10138  1.1.6.2  bouyer #########################################################################
   10139  1.1.6.2  bouyer 
   10140  1.1.6.2  bouyer 	global		t_dz
   10141  1.1.6.2  bouyer t_dz:
   10142  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0) 		# no; is src negative?
   10143  1.1.6.2  bouyer 	bmi.b		t_dz2			# yes
   10144  1.1.6.2  bouyer 
   10145  1.1.6.2  bouyer dz_pinf:
   10146  1.1.6.2  bouyer 	fmov.s		&0x7f800000,%fp0	# return +INF in fp0
   10147  1.1.6.2  bouyer 	ori.l		&dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
   10148  1.1.6.2  bouyer 	rts
   10149  1.1.6.2  bouyer 
   10150  1.1.6.2  bouyer 	global		t_dz2
   10151  1.1.6.2  bouyer t_dz2:
   10152  1.1.6.2  bouyer 	fmov.s		&0xff800000,%fp0	# return -INF in fp0
   10153  1.1.6.2  bouyer 	ori.l		&dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
   10154  1.1.6.2  bouyer 	rts
   10155  1.1.6.2  bouyer 
   10156  1.1.6.2  bouyer #################################################################
   10157  1.1.6.2  bouyer # OPERR exception:						#
   10158  1.1.6.2  bouyer #	- set FPSR exception status operr bit, condition code 	#
   10159  1.1.6.2  bouyer #	  nan bit; Store default NAN into fp0			#
   10160  1.1.6.2  bouyer #################################################################
   10161  1.1.6.2  bouyer 	global		t_operr
   10162  1.1.6.2  bouyer t_operr:
   10163  1.1.6.2  bouyer 	ori.l		&opnan_mask,USER_FPSR(%a6) # set NaN/OPERR/AIOP
   10164  1.1.6.2  bouyer 	fmovm.x		qnan(%pc),&0x80		# return default NAN in fp0
   10165  1.1.6.2  bouyer 	rts
   10166  1.1.6.2  bouyer 
   10167  1.1.6.2  bouyer #################################################################
   10168  1.1.6.2  bouyer # Extended DENORM:						#
   10169  1.1.6.2  bouyer # 	- For all functions that have a denormalized input and	#
   10170  1.1.6.2  bouyer #	  that f(x)=x, this is the entry point.			#
   10171  1.1.6.2  bouyer #	- we only return the EXOP here if either underflow or	#
   10172  1.1.6.2  bouyer #	  inexact is enabled.					#
   10173  1.1.6.2  bouyer #################################################################
   10174  1.1.6.2  bouyer 
   10175  1.1.6.2  bouyer # Entry point for scale w/ extended denorm. The function does
   10176  1.1.6.2  bouyer # NOT set INEX2/AUNFL/AINEX.
   10177  1.1.6.2  bouyer 	global		t_resdnrm
   10178  1.1.6.2  bouyer t_resdnrm:
   10179  1.1.6.2  bouyer 	ori.l		&unfl_mask,USER_FPSR(%a6) # set UNFL
   10180  1.1.6.2  bouyer 	bra.b		xdnrm_con
   10181  1.1.6.2  bouyer 
   10182  1.1.6.2  bouyer 	global		t_extdnrm
   10183  1.1.6.2  bouyer t_extdnrm:
   10184  1.1.6.2  bouyer 	ori.l		&unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
   10185  1.1.6.2  bouyer 
   10186  1.1.6.2  bouyer xdnrm_con:
   10187  1.1.6.2  bouyer 	mov.l		%a0,%a1			# make copy of src ptr
   10188  1.1.6.2  bouyer 	mov.l		%d0,%d1			# make copy of rnd prec,mode
   10189  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# extended precision?
   10190  1.1.6.2  bouyer 	bne.b		xdnrm_sd		# no
   10191  1.1.6.2  bouyer 
   10192  1.1.6.2  bouyer # result precision is extended.
   10193  1.1.6.2  bouyer 	tst.b		LOCAL_EX(%a0)		# is denorm negative?
   10194  1.1.6.2  bouyer 	bpl.b		xdnrm_exit		# no
   10195  1.1.6.2  bouyer 
   10196  1.1.6.2  bouyer 	bset		&neg_bit,FPSR_CC(%a6)	# yes; set 'N' ccode bit
   10197  1.1.6.2  bouyer 	bra.b		xdnrm_exit
   10198  1.1.6.2  bouyer 
   10199  1.1.6.2  bouyer # result precision is single or double
   10200  1.1.6.2  bouyer xdnrm_sd:
   10201  1.1.6.2  bouyer 	mov.l		%a1,-(%sp)
   10202  1.1.6.2  bouyer 	tst.b		LOCAL_EX(%a0)		# is denorm pos or neg?
   10203  1.1.6.2  bouyer 	smi.b		%d1			# set d0 accodingly
   10204  1.1.6.2  bouyer 	bsr.l		unf_sub
   10205  1.1.6.2  bouyer 	mov.l		(%sp)+,%a1
   10206  1.1.6.2  bouyer xdnrm_exit:
   10207  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10208  1.1.6.2  bouyer 
   10209  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0
   10210  1.1.6.2  bouyer 	andi.b		&0x0a,%d0		# is UNFL or INEX enabled?
   10211  1.1.6.2  bouyer 	bne.b		xdnrm_ena		# yes
   10212  1.1.6.2  bouyer 	rts
   10213  1.1.6.2  bouyer 
   10214  1.1.6.2  bouyer ################
   10215  1.1.6.2  bouyer # unfl enabled #
   10216  1.1.6.2  bouyer ################
   10217  1.1.6.2  bouyer # we have a DENORM that needs to be converted into an EXOP.
   10218  1.1.6.2  bouyer # so, normalize the mantissa, add 0x6000 to the new exponent,
   10219  1.1.6.2  bouyer # and return the result in fp1.
   10220  1.1.6.2  bouyer xdnrm_ena:
   10221  1.1.6.2  bouyer 	mov.w		LOCAL_EX(%a1),FP_SCR0_EX(%a6)
   10222  1.1.6.2  bouyer 	mov.l		LOCAL_HI(%a1),FP_SCR0_HI(%a6)
   10223  1.1.6.2  bouyer 	mov.l		LOCAL_LO(%a1),FP_SCR0_LO(%a6)
   10224  1.1.6.2  bouyer 
   10225  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   10226  1.1.6.2  bouyer 	bsr.l		norm			# normalize mantissa
   10227  1.1.6.2  bouyer 	addi.l		&0x6000,%d0		# add extra bias
   10228  1.1.6.2  bouyer 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# keep old sign
   10229  1.1.6.2  bouyer 	or.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   10230  1.1.6.2  bouyer 
   10231  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   10232  1.1.6.2  bouyer 	rts
   10233  1.1.6.2  bouyer 
   10234  1.1.6.2  bouyer #################################################################
   10235  1.1.6.2  bouyer # UNFL exception:						#
   10236  1.1.6.2  bouyer # 	- This routine is for cases where even an EXOP isn't	#
   10237  1.1.6.2  bouyer #  	  large enough to hold the range of this result.	#
   10238  1.1.6.2  bouyer #	  In such a case, the EXOP equals zero.			#
   10239  1.1.6.2  bouyer #  	- Return the default result to the proper precision 	#
   10240  1.1.6.2  bouyer #	  with the sign of this result being the same as that	#
   10241  1.1.6.2  bouyer #	  of the src operand.					#
   10242  1.1.6.2  bouyer # 	- t_unfl2() is provided to force the result sign to 	#
   10243  1.1.6.2  bouyer #	  positive which is the desired result for fetox().	#
   10244  1.1.6.2  bouyer #################################################################
   10245  1.1.6.2  bouyer 	global		t_unfl
   10246  1.1.6.2  bouyer t_unfl:
   10247  1.1.6.2  bouyer 	ori.l		&unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
   10248  1.1.6.2  bouyer 
   10249  1.1.6.2  bouyer 	tst.b		(%a0)			# is result pos or neg?
   10250  1.1.6.2  bouyer 	smi.b		%d1			# set d1 accordingly
   10251  1.1.6.2  bouyer 	bsr.l		unf_sub			# calc default unfl result
   10252  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10253  1.1.6.2  bouyer 
   10254  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp1	# return EXOP in fp1
   10255  1.1.6.2  bouyer 	rts
   10256  1.1.6.2  bouyer 
   10257  1.1.6.2  bouyer # t_unfl2 ALWAYS tells unf_sub to create a positive result
   10258  1.1.6.2  bouyer 	global		t_unfl2
   10259  1.1.6.2  bouyer t_unfl2:
   10260  1.1.6.2  bouyer 	ori.l		&unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
   10261  1.1.6.2  bouyer 
   10262  1.1.6.2  bouyer 	sf.b		%d1			# set d0 to represent positive
   10263  1.1.6.2  bouyer 	bsr.l		unf_sub			# calc default unfl result
   10264  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10265  1.1.6.2  bouyer 
   10266  1.1.6.2  bouyer 	fmov.s		&0x0000000,%fp1		# return EXOP in fp1
   10267  1.1.6.2  bouyer 	rts
   10268  1.1.6.2  bouyer 
   10269  1.1.6.2  bouyer #################################################################
   10270  1.1.6.2  bouyer # OVFL exception:						#
   10271  1.1.6.2  bouyer # 	- This routine is for cases where even an EXOP isn't	#
   10272  1.1.6.2  bouyer #  	  large enough to hold the range of this result.	#
   10273  1.1.6.2  bouyer # 	- Return the default result to the proper precision 	#
   10274  1.1.6.2  bouyer #	  with the sign of this result being the same as that 	#
   10275  1.1.6.2  bouyer #	  of the src operand.					#
   10276  1.1.6.2  bouyer # 	- t_ovfl2() is provided to force the result sign to 	#
   10277  1.1.6.2  bouyer #	  positive which is the desired result for fcosh().	#
   10278  1.1.6.2  bouyer # 	- t_ovfl_sc() is provided for scale() which only sets 	#
   10279  1.1.6.2  bouyer #	  the inexact bits if the number is inexact for the 	#
   10280  1.1.6.2  bouyer #	  precision indicated.					#
   10281  1.1.6.2  bouyer #################################################################
   10282  1.1.6.2  bouyer 
   10283  1.1.6.2  bouyer 	global		t_ovfl_sc
   10284  1.1.6.2  bouyer t_ovfl_sc:
   10285  1.1.6.2  bouyer 	ori.l		&ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
   10286  1.1.6.2  bouyer 
   10287  1.1.6.2  bouyer 	mov.b		%d0,%d1			# fetch rnd mode/prec
   10288  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# extract rnd prec
   10289  1.1.6.2  bouyer 	beq.b		ovfl_work		# prec is extended
   10290  1.1.6.2  bouyer 
   10291  1.1.6.2  bouyer 	tst.b		LOCAL_HI(%a0)		# is dst a DENORM?
   10292  1.1.6.2  bouyer 	bmi.b		ovfl_sc_norm		# no
   10293  1.1.6.2  bouyer 
   10294  1.1.6.2  bouyer # dst op is a DENORM. we have to normalize the mantissa to see if the
   10295  1.1.6.2  bouyer # result would be inexact for the given precision. make a copy of the
   10296  1.1.6.2  bouyer # dst so we don't screw up the version passed to us.
   10297  1.1.6.2  bouyer 	mov.w		LOCAL_EX(%a0),FP_SCR0_EX(%a6)
   10298  1.1.6.2  bouyer 	mov.l		LOCAL_HI(%a0),FP_SCR0_HI(%a6)
   10299  1.1.6.2  bouyer 	mov.l		LOCAL_LO(%a0),FP_SCR0_LO(%a6)
   10300  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass ptr to FP_SCR0
   10301  1.1.6.2  bouyer 	movm.l		&0xc080,-(%sp)		# save d0-d1/a0
   10302  1.1.6.2  bouyer 	bsr.l		norm			# normalize mantissa
   10303  1.1.6.2  bouyer 	movm.l		(%sp)+,&0x0103		# restore d0-d1/a0
   10304  1.1.6.2  bouyer 
   10305  1.1.6.2  bouyer ovfl_sc_norm:
   10306  1.1.6.2  bouyer 	cmpi.b		%d1,&0x40		# is prec dbl?
   10307  1.1.6.2  bouyer 	bne.b		ovfl_sc_dbl		# no; sgl
   10308  1.1.6.2  bouyer ovfl_sc_sgl:
   10309  1.1.6.2  bouyer 	tst.l		LOCAL_LO(%a0)		# is lo lw of sgl set?
   10310  1.1.6.2  bouyer 	bne.b		ovfl_sc_inx		# yes
   10311  1.1.6.2  bouyer 	tst.b		3+LOCAL_HI(%a0)		# is lo byte of hi lw set?
   10312  1.1.6.2  bouyer 	bne.b		ovfl_sc_inx		# yes
   10313  1.1.6.2  bouyer 	bra.b		ovfl_work		# don't set INEX2
   10314  1.1.6.2  bouyer ovfl_sc_dbl:
   10315  1.1.6.2  bouyer 	mov.l		LOCAL_LO(%a0),%d1	# are any of lo 11 bits of
   10316  1.1.6.2  bouyer 	andi.l		&0x7ff,%d1		# dbl mantissa set?
   10317  1.1.6.2  bouyer 	beq.b		ovfl_work		# no; don't set INEX2
   10318  1.1.6.2  bouyer ovfl_sc_inx:
   10319  1.1.6.2  bouyer 	ori.l		&inex2_mask,USER_FPSR(%a6) # set INEX2
   10320  1.1.6.2  bouyer 	bra.b		ovfl_work		# continue
   10321  1.1.6.2  bouyer 
   10322  1.1.6.2  bouyer 	global		t_ovfl
   10323  1.1.6.2  bouyer t_ovfl:
   10324  1.1.6.2  bouyer 	ori.l		&ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX
   10325  1.1.6.2  bouyer 
   10326  1.1.6.2  bouyer ovfl_work:
   10327  1.1.6.2  bouyer 	tst.b		LOCAL_EX(%a0)		# what is the sign?
   10328  1.1.6.2  bouyer 	smi.b		%d1			# set d1 accordingly
   10329  1.1.6.2  bouyer 	bsr.l		ovf_res			# calc default ovfl result
   10330  1.1.6.2  bouyer 	mov.b		%d0,FPSR_CC(%a6)	# insert new ccodes
   10331  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10332  1.1.6.2  bouyer 
   10333  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp1	# return EXOP in fp1
   10334  1.1.6.2  bouyer 	rts
   10335  1.1.6.2  bouyer 
   10336  1.1.6.2  bouyer # t_ovfl2 ALWAYS tells ovf_res to create a positive result
   10337  1.1.6.2  bouyer 	global		t_ovfl2
   10338  1.1.6.2  bouyer t_ovfl2:
   10339  1.1.6.2  bouyer 	ori.l		&ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX
   10340  1.1.6.2  bouyer 
   10341  1.1.6.2  bouyer 	sf.b		%d1			# clear sign flag for positive
   10342  1.1.6.2  bouyer 	bsr.l		ovf_res			# calc default ovfl result
   10343  1.1.6.2  bouyer 	mov.b		%d0,FPSR_CC(%a6)	# insert new ccodes
   10344  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   10345  1.1.6.2  bouyer 
   10346  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp1	# return EXOP in fp1
   10347  1.1.6.2  bouyer 	rts
   10348  1.1.6.2  bouyer 
   10349  1.1.6.2  bouyer #################################################################
   10350  1.1.6.2  bouyer # t_catch(): 							#
   10351  1.1.6.2  bouyer #	- the last operation of a transcendental emulation	#
   10352  1.1.6.2  bouyer # 	  routine may have caused an underflow or overflow. 	#
   10353  1.1.6.2  bouyer # 	  we find out if this occurred by doing an fsave and 	#
   10354  1.1.6.2  bouyer #	  checking the exception bit. if one did occur, then we	#
   10355  1.1.6.2  bouyer #	  jump to fgen_except() which creates the default	#
   10356  1.1.6.2  bouyer #	  result and EXOP for us.				#
   10357  1.1.6.2  bouyer #################################################################
   10358  1.1.6.2  bouyer 	global		t_catch
   10359  1.1.6.2  bouyer t_catch:
   10360  1.1.6.2  bouyer 
   10361  1.1.6.2  bouyer 	fsave		-(%sp)
   10362  1.1.6.2  bouyer 	tst.b		0x2(%sp)
   10363  1.1.6.2  bouyer 	bmi.b		catch
   10364  1.1.6.2  bouyer 	add.l		&0xc,%sp
   10365  1.1.6.2  bouyer 
   10366  1.1.6.2  bouyer #################################################################
   10367  1.1.6.2  bouyer # INEX2 exception:						#
   10368  1.1.6.2  bouyer #	- The inex2 and ainex bits are set.			#
   10369  1.1.6.2  bouyer #################################################################
   10370  1.1.6.2  bouyer 	global		t_inx2
   10371  1.1.6.2  bouyer t_inx2:
   10372  1.1.6.2  bouyer 	fblt.w		t_minx2
   10373  1.1.6.2  bouyer 	fbeq.w		inx2_zero
   10374  1.1.6.2  bouyer 
   10375  1.1.6.2  bouyer 	global		t_pinx2
   10376  1.1.6.2  bouyer t_pinx2:
   10377  1.1.6.2  bouyer 	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX
   10378  1.1.6.2  bouyer 	rts
   10379  1.1.6.2  bouyer 
   10380  1.1.6.2  bouyer 	global		t_minx2
   10381  1.1.6.2  bouyer t_minx2:
   10382  1.1.6.2  bouyer 	ori.l		&inx2a_mask+neg_mask,USER_FPSR(%a6) # set N/INEX2/AINEX
   10383  1.1.6.2  bouyer 	rts
   10384  1.1.6.2  bouyer 
   10385  1.1.6.2  bouyer inx2_zero:
   10386  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)
   10387  1.1.6.2  bouyer 	ori.w		&inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX
   10388  1.1.6.2  bouyer 	rts
   10389  1.1.6.2  bouyer 
   10390  1.1.6.2  bouyer # an underflow or overflow exception occurred.
   10391  1.1.6.2  bouyer # we must set INEX/AINEX since the fmul/fdiv/fmov emulation may not!
   10392  1.1.6.2  bouyer catch:
   10393  1.1.6.2  bouyer 	ori.w		&inx2a_mask,FPSR_EXCEPT(%a6)
   10394  1.1.6.2  bouyer catch2:
   10395  1.1.6.2  bouyer 	bsr.l		fgen_except
   10396  1.1.6.2  bouyer 	add.l		&0xc,%sp
   10397  1.1.6.2  bouyer 	rts
   10398  1.1.6.2  bouyer 
   10399  1.1.6.2  bouyer 	global		t_catch2
   10400  1.1.6.2  bouyer t_catch2:
   10401  1.1.6.2  bouyer 
   10402  1.1.6.2  bouyer 	fsave		-(%sp)
   10403  1.1.6.2  bouyer 
   10404  1.1.6.2  bouyer 	tst.b		0x2(%sp)
   10405  1.1.6.2  bouyer 	bmi.b		catch2
   10406  1.1.6.2  bouyer 	add.l		&0xc,%sp
   10407  1.1.6.2  bouyer 
   10408  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0
   10409  1.1.6.2  bouyer 	or.l		%d0,USER_FPSR(%a6)
   10410  1.1.6.2  bouyer 
   10411  1.1.6.2  bouyer 	rts
   10412  1.1.6.2  bouyer 
   10413  1.1.6.2  bouyer #########################################################################
   10414  1.1.6.2  bouyer 
   10415  1.1.6.2  bouyer #########################################################################
   10416  1.1.6.2  bouyer # unf_res(): underflow default result calculation for transcendentals	#
   10417  1.1.6.2  bouyer #									#
   10418  1.1.6.2  bouyer # INPUT:								#
   10419  1.1.6.2  bouyer # 	d0   : rnd mode,precision					#
   10420  1.1.6.2  bouyer # 	d1.b : sign bit of result ('11111111 = (-) ; '00000000 = (+))	#
   10421  1.1.6.2  bouyer # OUTPUT:								#
   10422  1.1.6.2  bouyer #	a0   : points to result (in instruction memory)			#
   10423  1.1.6.2  bouyer #########################################################################
   10424  1.1.6.2  bouyer unf_sub:
   10425  1.1.6.2  bouyer 	ori.l		&unfinx_mask,USER_FPSR(%a6)
   10426  1.1.6.2  bouyer 
   10427  1.1.6.2  bouyer 	andi.w		&0x10,%d1		# keep sign bit in 4th spot
   10428  1.1.6.2  bouyer 
   10429  1.1.6.2  bouyer 	lsr.b		&0x4,%d0		# shift rnd prec,mode to lo bits
   10430  1.1.6.2  bouyer 	andi.b		&0xf,%d0		# strip hi rnd mode bit
   10431  1.1.6.2  bouyer 	or.b		%d1,%d0			# concat {sgn,mode,prec}
   10432  1.1.6.2  bouyer 
   10433  1.1.6.2  bouyer 	mov.l		%d0,%d1			# make a copy
   10434  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# mult index 2 by 2
   10435  1.1.6.2  bouyer 
   10436  1.1.6.2  bouyer 	mov.b		(tbl_unf_cc.b,%pc,%d0.w*1),FPSR_CC(%a6) # insert ccode bits
   10437  1.1.6.2  bouyer 	lea		(tbl_unf_result.b,%pc,%d1.w*8),%a0 # grab result ptr
   10438  1.1.6.2  bouyer 	rts
   10439  1.1.6.2  bouyer 
   10440  1.1.6.2  bouyer tbl_unf_cc:
   10441  1.1.6.2  bouyer 	byte		0x4, 0x4, 0x4, 0x0
   10442  1.1.6.2  bouyer 	byte		0x4, 0x4, 0x4, 0x0
   10443  1.1.6.2  bouyer 	byte		0x4, 0x4, 0x4, 0x0
   10444  1.1.6.2  bouyer 	byte		0x0, 0x0, 0x0, 0x0
   10445  1.1.6.2  bouyer 	byte		0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
   10446  1.1.6.2  bouyer 	byte		0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
   10447  1.1.6.2  bouyer 	byte		0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
   10448  1.1.6.2  bouyer 
   10449  1.1.6.2  bouyer tbl_unf_result:
   10450  1.1.6.2  bouyer 	long		0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10451  1.1.6.2  bouyer 	long		0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10452  1.1.6.2  bouyer 	long		0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10453  1.1.6.2  bouyer 	long		0x00000000, 0x00000000, 0x00000001, 0x0 # MIN; ext
   10454  1.1.6.2  bouyer 
   10455  1.1.6.2  bouyer 	long		0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10456  1.1.6.2  bouyer 	long		0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10457  1.1.6.2  bouyer 	long		0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10458  1.1.6.2  bouyer 	long		0x3f810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl
   10459  1.1.6.2  bouyer 
   10460  1.1.6.2  bouyer 	long		0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10461  1.1.6.2  bouyer 	long		0x3c010000, 0x00000000, 0x00000000, 0x0 # ZER0;dbl
   10462  1.1.6.2  bouyer 	long		0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10463  1.1.6.2  bouyer 	long		0x3c010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl
   10464  1.1.6.2  bouyer 
   10465  1.1.6.2  bouyer 	long		0x0,0x0,0x0,0x0
   10466  1.1.6.2  bouyer 	long		0x0,0x0,0x0,0x0
   10467  1.1.6.2  bouyer 	long		0x0,0x0,0x0,0x0
   10468  1.1.6.2  bouyer 	long		0x0,0x0,0x0,0x0
   10469  1.1.6.2  bouyer 
   10470  1.1.6.2  bouyer 	long		0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10471  1.1.6.2  bouyer 	long		0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10472  1.1.6.2  bouyer 	long		0x80000000, 0x00000000, 0x00000001, 0x0 # MIN; ext
   10473  1.1.6.2  bouyer 	long		0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
   10474  1.1.6.2  bouyer 
   10475  1.1.6.2  bouyer 	long		0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10476  1.1.6.2  bouyer 	long		0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10477  1.1.6.2  bouyer 	long		0xbf810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl
   10478  1.1.6.2  bouyer 	long		0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
   10479  1.1.6.2  bouyer 
   10480  1.1.6.2  bouyer 	long		0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10481  1.1.6.2  bouyer 	long		0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10482  1.1.6.2  bouyer 	long		0xbc010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl
   10483  1.1.6.2  bouyer 	long		0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
   10484  1.1.6.2  bouyer 
   10485  1.1.6.2  bouyer ############################################################
   10486  1.1.6.2  bouyer 
   10487  1.1.6.2  bouyer #########################################################################
   10488  1.1.6.2  bouyer # src_zero(): Return signed zero according to sign of src operand.	#
   10489  1.1.6.2  bouyer #########################################################################
   10490  1.1.6.2  bouyer 	global		src_zero
   10491  1.1.6.2  bouyer src_zero:
   10492  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# get sign of src operand
   10493  1.1.6.2  bouyer 	bmi.b		ld_mzero		# if neg, load neg zero
   10494  1.1.6.2  bouyer 
   10495  1.1.6.2  bouyer #
   10496  1.1.6.2  bouyer # ld_pzero(): return a positive zero.
   10497  1.1.6.2  bouyer #
   10498  1.1.6.2  bouyer 	global		ld_pzero
   10499  1.1.6.2  bouyer ld_pzero:
   10500  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# load +0
   10501  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   10502  1.1.6.2  bouyer 	rts
   10503  1.1.6.2  bouyer 
   10504  1.1.6.2  bouyer # ld_mzero(): return a negative zero.
   10505  1.1.6.2  bouyer 	global		ld_mzero
   10506  1.1.6.2  bouyer ld_mzero:
   10507  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# load -0
   10508  1.1.6.2  bouyer 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
   10509  1.1.6.2  bouyer 	rts
   10510  1.1.6.2  bouyer 
   10511  1.1.6.2  bouyer #########################################################################
   10512  1.1.6.2  bouyer # dst_zero(): Return signed zero according to sign of dst operand.	#
   10513  1.1.6.2  bouyer #########################################################################
   10514  1.1.6.2  bouyer 	global		dst_zero
   10515  1.1.6.2  bouyer dst_zero:
   10516  1.1.6.2  bouyer 	tst.b		DST_EX(%a1) 		# get sign of dst operand
   10517  1.1.6.2  bouyer 	bmi.b		ld_mzero		# if neg, load neg zero
   10518  1.1.6.2  bouyer 	bra.b		ld_pzero		# load positive zero
   10519  1.1.6.2  bouyer 
   10520  1.1.6.2  bouyer #########################################################################
   10521  1.1.6.2  bouyer # src_inf(): Return signed inf according to sign of src operand.	#
   10522  1.1.6.2  bouyer #########################################################################
   10523  1.1.6.2  bouyer 	global		src_inf
   10524  1.1.6.2  bouyer src_inf:
   10525  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0) 		# get sign of src operand
   10526  1.1.6.2  bouyer 	bmi.b		ld_minf			# if negative branch
   10527  1.1.6.2  bouyer 
   10528  1.1.6.2  bouyer #
   10529  1.1.6.2  bouyer # ld_pinf(): return a positive infinity.
   10530  1.1.6.2  bouyer #
   10531  1.1.6.2  bouyer 	global		ld_pinf
   10532  1.1.6.2  bouyer ld_pinf:
   10533  1.1.6.2  bouyer 	fmov.s		&0x7f800000,%fp0	# load +INF
   10534  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'INF' ccode bit
   10535  1.1.6.2  bouyer 	rts
   10536  1.1.6.2  bouyer 
   10537  1.1.6.2  bouyer #
   10538  1.1.6.2  bouyer # ld_minf():return a negative infinity.
   10539  1.1.6.2  bouyer #
   10540  1.1.6.2  bouyer 	global		ld_minf
   10541  1.1.6.2  bouyer ld_minf:
   10542  1.1.6.2  bouyer 	fmov.s		&0xff800000,%fp0	# load -INF
   10543  1.1.6.2  bouyer 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
   10544  1.1.6.2  bouyer 	rts
   10545  1.1.6.2  bouyer 
   10546  1.1.6.2  bouyer #########################################################################
   10547  1.1.6.2  bouyer # dst_inf(): Return signed inf according to sign of dst operand.	#
   10548  1.1.6.2  bouyer #########################################################################
   10549  1.1.6.2  bouyer 	global		dst_inf
   10550  1.1.6.2  bouyer dst_inf:
   10551  1.1.6.2  bouyer 	tst.b		DST_EX(%a1) 		# get sign of dst operand
   10552  1.1.6.2  bouyer 	bmi.b		ld_minf			# if negative branch
   10553  1.1.6.2  bouyer 	bra.b		ld_pinf
   10554  1.1.6.2  bouyer 
   10555  1.1.6.2  bouyer 	global		szr_inf
   10556  1.1.6.2  bouyer #################################################################
   10557  1.1.6.2  bouyer # szr_inf(): Return +ZERO for a negative src operand or		#
   10558  1.1.6.2  bouyer #	            +INF for a positive src operand.		#
   10559  1.1.6.2  bouyer #	     Routine used for fetox, ftwotox, and ftentox.	#
   10560  1.1.6.2  bouyer #################################################################
   10561  1.1.6.2  bouyer szr_inf:
   10562  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# check sign of source
   10563  1.1.6.2  bouyer 	bmi.b		ld_pzero
   10564  1.1.6.2  bouyer 	bra.b		ld_pinf
   10565  1.1.6.2  bouyer 
   10566  1.1.6.2  bouyer #########################################################################
   10567  1.1.6.2  bouyer # sopr_inf(): Return +INF for a positive src operand or			#
   10568  1.1.6.2  bouyer #	      jump to operand error routine for a negative src operand.	#
   10569  1.1.6.2  bouyer #	      Routine used for flogn, flognp1, flog10, and flog2.	#
   10570  1.1.6.2  bouyer #########################################################################
   10571  1.1.6.2  bouyer 	global		sopr_inf
   10572  1.1.6.2  bouyer sopr_inf:
   10573  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# check sign of source
   10574  1.1.6.2  bouyer 	bmi.w		t_operr
   10575  1.1.6.2  bouyer 	bra.b		ld_pinf
   10576  1.1.6.2  bouyer 
   10577  1.1.6.2  bouyer #################################################################
   10578  1.1.6.2  bouyer # setoxm1i(): Return minus one for a negative src operand or	#
   10579  1.1.6.2  bouyer #	      positive infinity for a positive src operand.	#
   10580  1.1.6.2  bouyer #	      Routine used for fetoxm1.				#
   10581  1.1.6.2  bouyer #################################################################
   10582  1.1.6.2  bouyer 	global		setoxm1i
   10583  1.1.6.2  bouyer setoxm1i:
   10584  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# check sign of source
   10585  1.1.6.2  bouyer 	bmi.b		ld_mone
   10586  1.1.6.2  bouyer 	bra.b		ld_pinf
   10587  1.1.6.2  bouyer 
   10588  1.1.6.2  bouyer #########################################################################
   10589  1.1.6.2  bouyer # src_one(): Return signed one according to sign of src operand.	#
   10590  1.1.6.2  bouyer #########################################################################
   10591  1.1.6.2  bouyer 	global		src_one
   10592  1.1.6.2  bouyer src_one:
   10593  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0) 		# check sign of source
   10594  1.1.6.2  bouyer 	bmi.b		ld_mone
   10595  1.1.6.2  bouyer 
   10596  1.1.6.2  bouyer #
   10597  1.1.6.2  bouyer # ld_pone(): return positive one.
   10598  1.1.6.2  bouyer #
   10599  1.1.6.2  bouyer 	global		ld_pone
   10600  1.1.6.2  bouyer ld_pone:
   10601  1.1.6.2  bouyer 	fmov.s		&0x3f800000,%fp0	# load +1
   10602  1.1.6.2  bouyer 	clr.b		FPSR_CC(%a6)
   10603  1.1.6.2  bouyer 	rts
   10604  1.1.6.2  bouyer 
   10605  1.1.6.2  bouyer #
   10606  1.1.6.2  bouyer # ld_mone(): return negative one.
   10607  1.1.6.2  bouyer #
   10608  1.1.6.2  bouyer 	global		ld_mone
   10609  1.1.6.2  bouyer ld_mone:
   10610  1.1.6.2  bouyer 	fmov.s		&0xbf800000,%fp0	# load -1
   10611  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   10612  1.1.6.2  bouyer 	rts
   10613  1.1.6.2  bouyer 
   10614  1.1.6.2  bouyer ppiby2:	long		0x3fff0000, 0xc90fdaa2, 0x2168c235
   10615  1.1.6.2  bouyer mpiby2:	long		0xbfff0000, 0xc90fdaa2, 0x2168c235
   10616  1.1.6.2  bouyer 
   10617  1.1.6.2  bouyer #################################################################
   10618  1.1.6.2  bouyer # spi_2(): Return signed PI/2 according to sign of src operand.	#
   10619  1.1.6.2  bouyer #################################################################
   10620  1.1.6.2  bouyer 	global		spi_2
   10621  1.1.6.2  bouyer spi_2:
   10622  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0) 		# check sign of source
   10623  1.1.6.2  bouyer 	bmi.b		ld_mpi2
   10624  1.1.6.2  bouyer 
   10625  1.1.6.2  bouyer #
   10626  1.1.6.2  bouyer # ld_ppi2(): return positive PI/2.
   10627  1.1.6.2  bouyer #
   10628  1.1.6.2  bouyer 	global		ld_ppi2
   10629  1.1.6.2  bouyer ld_ppi2:
   10630  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   10631  1.1.6.2  bouyer 	fmov.x		ppiby2(%pc),%fp0	# load +pi/2
   10632  1.1.6.2  bouyer 	bra.w		t_pinx2			# set INEX2
   10633  1.1.6.2  bouyer 
   10634  1.1.6.2  bouyer #
   10635  1.1.6.2  bouyer # ld_mpi2(): return negative PI/2.
   10636  1.1.6.2  bouyer #
   10637  1.1.6.2  bouyer 	global		ld_mpi2
   10638  1.1.6.2  bouyer ld_mpi2:
   10639  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr
   10640  1.1.6.2  bouyer 	fmov.x		mpiby2(%pc),%fp0	# load -pi/2
   10641  1.1.6.2  bouyer 	bra.w		t_minx2			# set INEX2
   10642  1.1.6.2  bouyer 
   10643  1.1.6.2  bouyer ####################################################
   10644  1.1.6.2  bouyer # The following routines give support for fsincos. #
   10645  1.1.6.2  bouyer ####################################################
   10646  1.1.6.2  bouyer 
   10647  1.1.6.2  bouyer #
   10648  1.1.6.2  bouyer # ssincosz(): When the src operand is ZERO, store a one in the
   10649  1.1.6.2  bouyer # 	      cosine register and return a ZERO in fp0 w/ the same sign
   10650  1.1.6.2  bouyer #	      as the src operand.
   10651  1.1.6.2  bouyer #
   10652  1.1.6.2  bouyer 	global		ssincosz
   10653  1.1.6.2  bouyer ssincosz:
   10654  1.1.6.2  bouyer 	fmov.s		&0x3f800000,%fp1
   10655  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# test sign
   10656  1.1.6.2  bouyer 	bpl.b		sincoszp
   10657  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# return sin result in fp0
   10658  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)
   10659  1.1.6.2  bouyer 	bra.b		sto_cos			# store cosine result
   10660  1.1.6.2  bouyer sincoszp:
   10661  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# return sin result in fp0
   10662  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)
   10663  1.1.6.2  bouyer 	bra.b		sto_cos			# store cosine result
   10664  1.1.6.2  bouyer 
   10665  1.1.6.2  bouyer #
   10666  1.1.6.2  bouyer # ssincosi(): When the src operand is INF, store a QNAN in the cosine
   10667  1.1.6.2  bouyer #	      register and jump to the operand error routine for negative
   10668  1.1.6.2  bouyer #	      src operands.
   10669  1.1.6.2  bouyer #
   10670  1.1.6.2  bouyer 	global		ssincosi
   10671  1.1.6.2  bouyer ssincosi:
   10672  1.1.6.2  bouyer 	fmov.x		qnan(%pc),%fp1		# load NAN
   10673  1.1.6.2  bouyer 	bsr.l		sto_cos			# store cosine result
   10674  1.1.6.2  bouyer 	bra.w		t_operr
   10675  1.1.6.2  bouyer 
   10676  1.1.6.2  bouyer #
   10677  1.1.6.2  bouyer # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
   10678  1.1.6.2  bouyer # 		 register and branch to the src QNAN routine.
   10679  1.1.6.2  bouyer #
   10680  1.1.6.2  bouyer 	global		ssincosqnan
   10681  1.1.6.2  bouyer ssincosqnan:
   10682  1.1.6.2  bouyer 	fmov.x		LOCAL_EX(%a0),%fp1
   10683  1.1.6.2  bouyer 	bsr.l		sto_cos
   10684  1.1.6.2  bouyer 	bra.w		src_qnan
   10685  1.1.6.2  bouyer 
   10686  1.1.6.2  bouyer #
   10687  1.1.6.2  bouyer # ssincossnan(): When the src operand is an SNAN, store the SNAN w/ the SNAN bit set
   10688  1.1.6.2  bouyer #		 in the cosine register and branch to the src SNAN routine.
   10689  1.1.6.2  bouyer #
   10690  1.1.6.2  bouyer 	global		ssincossnan
   10691  1.1.6.2  bouyer ssincossnan:
   10692  1.1.6.2  bouyer 	fmov.x		LOCAL_EX(%a0),%fp1
   10693  1.1.6.2  bouyer 	bsr.l		sto_cos
   10694  1.1.6.2  bouyer 	bra.w		src_snan
   10695  1.1.6.2  bouyer 
   10696  1.1.6.2  bouyer ########################################################################
   10697  1.1.6.2  bouyer 
   10698  1.1.6.2  bouyer #########################################################################
   10699  1.1.6.2  bouyer # sto_cos(): store fp1 to the fpreg designated by the CMDREG dst field.	#
   10700  1.1.6.2  bouyer #	     fp1 holds the result of the cosine portion of ssincos().	#
   10701  1.1.6.2  bouyer #	     the value in fp1 will not take any exceptions when moved.	#
   10702  1.1.6.2  bouyer # INPUT:								#
   10703  1.1.6.2  bouyer #	fp1 : fp value to store						#
   10704  1.1.6.2  bouyer # MODIFIED:								#
   10705  1.1.6.2  bouyer #	d0								#
   10706  1.1.6.2  bouyer #########################################################################
   10707  1.1.6.2  bouyer 	global		sto_cos
   10708  1.1.6.2  bouyer sto_cos:
   10709  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d0
   10710  1.1.6.2  bouyer 	andi.w		&0x7,%d0
   10711  1.1.6.2  bouyer 	mov.w		(tbl_sto_cos.b,%pc,%d0.w*2),%d0
   10712  1.1.6.2  bouyer 	jmp		(tbl_sto_cos.b,%pc,%d0.w*1)
   10713  1.1.6.2  bouyer 
   10714  1.1.6.2  bouyer tbl_sto_cos:
   10715  1.1.6.2  bouyer 	short		sto_cos_0 - tbl_sto_cos
   10716  1.1.6.2  bouyer 	short		sto_cos_1 - tbl_sto_cos
   10717  1.1.6.2  bouyer 	short		sto_cos_2 - tbl_sto_cos
   10718  1.1.6.2  bouyer 	short		sto_cos_3 - tbl_sto_cos
   10719  1.1.6.2  bouyer 	short		sto_cos_4 - tbl_sto_cos
   10720  1.1.6.2  bouyer 	short		sto_cos_5 - tbl_sto_cos
   10721  1.1.6.2  bouyer 	short		sto_cos_6 - tbl_sto_cos
   10722  1.1.6.2  bouyer 	short		sto_cos_7 - tbl_sto_cos
   10723  1.1.6.2  bouyer 
   10724  1.1.6.2  bouyer sto_cos_0:
   10725  1.1.6.2  bouyer 	fmovm.x		&0x40,EXC_FP0(%a6)
   10726  1.1.6.2  bouyer 	rts
   10727  1.1.6.2  bouyer sto_cos_1:
   10728  1.1.6.2  bouyer 	fmovm.x		&0x40,EXC_FP1(%a6)
   10729  1.1.6.2  bouyer 	rts
   10730  1.1.6.2  bouyer sto_cos_2:
   10731  1.1.6.2  bouyer 	fmov.x 		%fp1,%fp2
   10732  1.1.6.2  bouyer 	rts
   10733  1.1.6.2  bouyer sto_cos_3:
   10734  1.1.6.2  bouyer 	fmov.x		%fp1,%fp3
   10735  1.1.6.2  bouyer 	rts
   10736  1.1.6.2  bouyer sto_cos_4:
   10737  1.1.6.2  bouyer 	fmov.x		%fp1,%fp4
   10738  1.1.6.2  bouyer 	rts
   10739  1.1.6.2  bouyer sto_cos_5:
   10740  1.1.6.2  bouyer 	fmov.x		%fp1,%fp5
   10741  1.1.6.2  bouyer 	rts
   10742  1.1.6.2  bouyer sto_cos_6:
   10743  1.1.6.2  bouyer 	fmov.x		%fp1,%fp6
   10744  1.1.6.2  bouyer 	rts
   10745  1.1.6.2  bouyer sto_cos_7:
   10746  1.1.6.2  bouyer 	fmov.x		%fp1,%fp7
   10747  1.1.6.2  bouyer 	rts
   10748  1.1.6.2  bouyer 
   10749  1.1.6.2  bouyer ##################################################################
   10750  1.1.6.2  bouyer 	global		smod_sdnrm
   10751  1.1.6.2  bouyer 	global		smod_snorm
   10752  1.1.6.2  bouyer smod_sdnrm:
   10753  1.1.6.2  bouyer smod_snorm:
   10754  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10755  1.1.6.2  bouyer 	beq.l		smod
   10756  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10757  1.1.6.2  bouyer 	beq.w		smod_zro
   10758  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10759  1.1.6.2  bouyer 	beq.l		t_operr
   10760  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10761  1.1.6.2  bouyer 	beq.l		smod
   10762  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN
   10763  1.1.6.2  bouyer 	beq.l		dst_snan
   10764  1.1.6.2  bouyer 	bra.l		dst_qnan
   10765  1.1.6.2  bouyer 
   10766  1.1.6.2  bouyer 	global		smod_szero
   10767  1.1.6.2  bouyer smod_szero:
   10768  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10769  1.1.6.2  bouyer 	beq.l		t_operr
   10770  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10771  1.1.6.2  bouyer 	beq.l		t_operr
   10772  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10773  1.1.6.2  bouyer 	beq.l		t_operr
   10774  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10775  1.1.6.2  bouyer 	beq.l		t_operr
   10776  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10777  1.1.6.2  bouyer 	beq.l		dst_qnan
   10778  1.1.6.2  bouyer 	bra.l		dst_snan
   10779  1.1.6.2  bouyer 
   10780  1.1.6.2  bouyer 	global		smod_sinf
   10781  1.1.6.2  bouyer smod_sinf:
   10782  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10783  1.1.6.2  bouyer 	beq.l		smod_fpn
   10784  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10785  1.1.6.2  bouyer 	beq.l		smod_zro
   10786  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10787  1.1.6.2  bouyer 	beq.l		t_operr
   10788  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10789  1.1.6.2  bouyer 	beq.l		smod_fpn
   10790  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10791  1.1.6.2  bouyer 	beq.l		dst_qnan
   10792  1.1.6.2  bouyer 	bra.l		dst_snan
   10793  1.1.6.2  bouyer 
   10794  1.1.6.2  bouyer smod_zro:
   10795  1.1.6.2  bouyer srem_zro:
   10796  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d1		# get src sign
   10797  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d0		# get dst sign
   10798  1.1.6.2  bouyer 	eor.b		%d0,%d1			# get qbyte sign
   10799  1.1.6.2  bouyer 	andi.b		&0x80,%d1
   10800  1.1.6.2  bouyer 	mov.b		%d1,FPSR_QBYTE(%a6)
   10801  1.1.6.2  bouyer 	tst.b		%d0
   10802  1.1.6.2  bouyer 	bpl.w		ld_pzero
   10803  1.1.6.2  bouyer 	bra.w		ld_mzero
   10804  1.1.6.2  bouyer 
   10805  1.1.6.2  bouyer smod_fpn:
   10806  1.1.6.2  bouyer srem_fpn:
   10807  1.1.6.2  bouyer 	clr.b		FPSR_QBYTE(%a6)
   10808  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   10809  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d1		# get src sign
   10810  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d0		# get dst sign
   10811  1.1.6.2  bouyer 	eor.b		%d0,%d1			# get qbyte sign
   10812  1.1.6.2  bouyer 	andi.b		&0x80,%d1
   10813  1.1.6.2  bouyer 	mov.b		%d1,FPSR_QBYTE(%a6)
   10814  1.1.6.2  bouyer 	cmpi.b		DTAG(%a6),&DENORM
   10815  1.1.6.2  bouyer 	bne.b		smod_nrm
   10816  1.1.6.2  bouyer 	lea		DST(%a1),%a0
   10817  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   10818  1.1.6.2  bouyer 	bra		t_resdnrm
   10819  1.1.6.2  bouyer smod_nrm:
   10820  1.1.6.2  bouyer 	fmov.l		(%sp)+,%fpcr
   10821  1.1.6.2  bouyer 	fmov.x		DST(%a1),%fp0
   10822  1.1.6.2  bouyer 	tst.b		DST_EX(%a1)
   10823  1.1.6.2  bouyer 	bmi.b		smod_nrm_neg
   10824  1.1.6.2  bouyer 	rts
   10825  1.1.6.2  bouyer 
   10826  1.1.6.2  bouyer smod_nrm_neg:
   10827  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode
   10828  1.1.6.2  bouyer 	rts
   10829  1.1.6.2  bouyer 
   10830  1.1.6.2  bouyer #########################################################################
   10831  1.1.6.2  bouyer 	global		srem_snorm
   10832  1.1.6.2  bouyer 	global		srem_sdnrm
   10833  1.1.6.2  bouyer srem_sdnrm:
   10834  1.1.6.2  bouyer srem_snorm:
   10835  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10836  1.1.6.2  bouyer 	beq.l		srem
   10837  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10838  1.1.6.2  bouyer 	beq.w		srem_zro
   10839  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10840  1.1.6.2  bouyer 	beq.l		t_operr
   10841  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10842  1.1.6.2  bouyer 	beq.l		srem
   10843  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10844  1.1.6.2  bouyer 	beq.l		dst_qnan
   10845  1.1.6.2  bouyer 	bra.l		dst_snan
   10846  1.1.6.2  bouyer 
   10847  1.1.6.2  bouyer 	global		srem_szero
   10848  1.1.6.2  bouyer srem_szero:
   10849  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10850  1.1.6.2  bouyer 	beq.l		t_operr
   10851  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10852  1.1.6.2  bouyer 	beq.l		t_operr
   10853  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10854  1.1.6.2  bouyer 	beq.l		t_operr
   10855  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10856  1.1.6.2  bouyer 	beq.l		t_operr
   10857  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10858  1.1.6.2  bouyer 	beq.l		dst_qnan
   10859  1.1.6.2  bouyer 	bra.l		dst_snan
   10860  1.1.6.2  bouyer 
   10861  1.1.6.2  bouyer 	global		srem_sinf
   10862  1.1.6.2  bouyer srem_sinf:
   10863  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10864  1.1.6.2  bouyer 	beq.w		srem_fpn
   10865  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10866  1.1.6.2  bouyer 	beq.w		srem_zro
   10867  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10868  1.1.6.2  bouyer 	beq.l		t_operr
   10869  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10870  1.1.6.2  bouyer 	beq.l		srem_fpn
   10871  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10872  1.1.6.2  bouyer 	beq.l		dst_qnan
   10873  1.1.6.2  bouyer 	bra.l		dst_snan
   10874  1.1.6.2  bouyer 
   10875  1.1.6.2  bouyer #########################################################################
   10876  1.1.6.2  bouyer 	global		sscale_snorm
   10877  1.1.6.2  bouyer 	global		sscale_sdnrm
   10878  1.1.6.2  bouyer sscale_snorm:
   10879  1.1.6.2  bouyer sscale_sdnrm:
   10880  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10881  1.1.6.2  bouyer 	beq.l		sscale
   10882  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10883  1.1.6.2  bouyer 	beq.l		dst_zero
   10884  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10885  1.1.6.2  bouyer 	beq.l		dst_inf
   10886  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10887  1.1.6.2  bouyer 	beq.l		sscale
   10888  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10889  1.1.6.2  bouyer 	beq.l		dst_qnan
   10890  1.1.6.2  bouyer 	bra.l		dst_snan
   10891  1.1.6.2  bouyer 
   10892  1.1.6.2  bouyer 	global		sscale_szero
   10893  1.1.6.2  bouyer sscale_szero:
   10894  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10895  1.1.6.2  bouyer 	beq.l		sscale
   10896  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   10897  1.1.6.2  bouyer 	beq.l		dst_zero
   10898  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   10899  1.1.6.2  bouyer 	beq.l		dst_inf
   10900  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   10901  1.1.6.2  bouyer 	beq.l		sscale
   10902  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10903  1.1.6.2  bouyer 	beq.l		dst_qnan
   10904  1.1.6.2  bouyer 	bra.l		dst_snan
   10905  1.1.6.2  bouyer 
   10906  1.1.6.2  bouyer 	global		sscale_sinf
   10907  1.1.6.2  bouyer sscale_sinf:
   10908  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10909  1.1.6.2  bouyer 	beq.l		t_operr
   10910  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10911  1.1.6.2  bouyer 	beq.l		dst_qnan
   10912  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN
   10913  1.1.6.2  bouyer 	beq.l		dst_snan
   10914  1.1.6.2  bouyer 	bra.l		t_operr
   10915  1.1.6.2  bouyer 
   10916  1.1.6.2  bouyer ########################################################################
   10917  1.1.6.2  bouyer 
   10918  1.1.6.2  bouyer #
   10919  1.1.6.2  bouyer # sop_sqnan(): The src op for frem/fmod/fscale was a QNAN.
   10920  1.1.6.2  bouyer #
   10921  1.1.6.2  bouyer 	global		sop_sqnan
   10922  1.1.6.2  bouyer sop_sqnan:
   10923  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10924  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10925  1.1.6.2  bouyer 	beq.b		dst_qnan
   10926  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN
   10927  1.1.6.2  bouyer 	beq.b		dst_snan
   10928  1.1.6.2  bouyer 	bra.b		src_qnan
   10929  1.1.6.2  bouyer 
   10930  1.1.6.2  bouyer #
   10931  1.1.6.2  bouyer # sop_ssnan(): The src op for frem/fmod/fscale was an SNAN.
   10932  1.1.6.2  bouyer #
   10933  1.1.6.2  bouyer 	global		sop_ssnan
   10934  1.1.6.2  bouyer sop_ssnan:
   10935  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   10936  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   10937  1.1.6.2  bouyer 	beq.b		dst_qnan_src_snan
   10938  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN
   10939  1.1.6.2  bouyer 	beq.b		dst_snan
   10940  1.1.6.2  bouyer 	bra.b		src_snan
   10941  1.1.6.2  bouyer 
   10942  1.1.6.2  bouyer dst_qnan_src_snan:
   10943  1.1.6.2  bouyer 	ori.l		&snaniop_mask,USER_FPSR(%a6) # set NAN/SNAN/AIOP
   10944  1.1.6.2  bouyer 	bra.b		dst_qnan
   10945  1.1.6.2  bouyer 
   10946  1.1.6.2  bouyer #
   10947  1.1.6.2  bouyer # dst_qnan(): Return the dst SNAN w/ the SNAN bit set.
   10948  1.1.6.2  bouyer #
   10949  1.1.6.2  bouyer 	global		dst_snan
   10950  1.1.6.2  bouyer dst_snan:
   10951  1.1.6.2  bouyer 	fmov.x		DST(%a1),%fp0		# the fmove sets the SNAN bit
   10952  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# catch resulting status
   10953  1.1.6.2  bouyer 	or.l		%d0,USER_FPSR(%a6)	# store status
   10954  1.1.6.2  bouyer 	rts
   10955  1.1.6.2  bouyer 
   10956  1.1.6.2  bouyer #
   10957  1.1.6.2  bouyer # dst_qnan(): Return the dst QNAN.
   10958  1.1.6.2  bouyer #
   10959  1.1.6.2  bouyer 	global		dst_qnan
   10960  1.1.6.2  bouyer dst_qnan:
   10961  1.1.6.2  bouyer 	fmov.x		DST(%a1),%fp0		# return the non-signalling nan
   10962  1.1.6.2  bouyer 	tst.b		DST_EX(%a1)		# set ccodes according to QNAN sign
   10963  1.1.6.2  bouyer 	bmi.b		dst_qnan_m
   10964  1.1.6.2  bouyer dst_qnan_p:
   10965  1.1.6.2  bouyer 	mov.b		&nan_bmask,FPSR_CC(%a6)
   10966  1.1.6.2  bouyer 	rts
   10967  1.1.6.2  bouyer dst_qnan_m:
   10968  1.1.6.2  bouyer 	mov.b		&neg_bmask+nan_bmask,FPSR_CC(%a6)
   10969  1.1.6.2  bouyer 	rts
   10970  1.1.6.2  bouyer 
   10971  1.1.6.2  bouyer #
   10972  1.1.6.2  bouyer # src_snan(): Return the src SNAN w/ the SNAN bit set.
   10973  1.1.6.2  bouyer #
   10974  1.1.6.2  bouyer 	global		src_snan
   10975  1.1.6.2  bouyer src_snan:
   10976  1.1.6.2  bouyer 	fmov.x		SRC(%a0),%fp0		# the fmove sets the SNAN bit
   10977  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# catch resulting status
   10978  1.1.6.2  bouyer 	or.l		%d0,USER_FPSR(%a6)	# store status
   10979  1.1.6.2  bouyer 	rts
   10980  1.1.6.2  bouyer 
   10981  1.1.6.2  bouyer #
   10982  1.1.6.2  bouyer # src_qnan(): Return the src QNAN.
   10983  1.1.6.2  bouyer #
   10984  1.1.6.2  bouyer 	global		src_qnan
   10985  1.1.6.2  bouyer src_qnan:
   10986  1.1.6.2  bouyer 	fmov.x		SRC(%a0),%fp0		# return the non-signalling nan
   10987  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# set ccodes according to QNAN sign
   10988  1.1.6.2  bouyer 	bmi.b		dst_qnan_m
   10989  1.1.6.2  bouyer src_qnan_p:
   10990  1.1.6.2  bouyer 	mov.b		&nan_bmask,FPSR_CC(%a6)
   10991  1.1.6.2  bouyer 	rts
   10992  1.1.6.2  bouyer src_qnan_m:
   10993  1.1.6.2  bouyer 	mov.b		&neg_bmask+nan_bmask,FPSR_CC(%a6)
   10994  1.1.6.2  bouyer 	rts
   10995  1.1.6.2  bouyer 
   10996  1.1.6.2  bouyer #
   10997  1.1.6.2  bouyer # fkern2.s:
   10998  1.1.6.2  bouyer #	These entry points are used by the exception handler
   10999  1.1.6.2  bouyer # routines where an instruction is selected by an index into
   11000  1.1.6.2  bouyer # a large jump table corresponding to a given instruction which
   11001  1.1.6.2  bouyer # has been decoded. Flow continues here where we now decode
   11002  1.1.6.2  bouyer # further accoding to the source operand type.
   11003  1.1.6.2  bouyer #
   11004  1.1.6.2  bouyer 
   11005  1.1.6.2  bouyer 	global		fsinh
   11006  1.1.6.2  bouyer fsinh:
   11007  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11008  1.1.6.2  bouyer 	beq.l		ssinh
   11009  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11010  1.1.6.2  bouyer 	beq.l		src_zero
   11011  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11012  1.1.6.2  bouyer 	beq.l		src_inf
   11013  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11014  1.1.6.2  bouyer 	beq.l		ssinhd
   11015  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11016  1.1.6.2  bouyer 	beq.l		src_qnan
   11017  1.1.6.2  bouyer 	bra.l		src_snan
   11018  1.1.6.2  bouyer 
   11019  1.1.6.2  bouyer 	global		flognp1
   11020  1.1.6.2  bouyer flognp1:
   11021  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11022  1.1.6.2  bouyer 	beq.l		slognp1
   11023  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11024  1.1.6.2  bouyer 	beq.l		src_zero
   11025  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11026  1.1.6.2  bouyer 	beq.l		sopr_inf
   11027  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11028  1.1.6.2  bouyer 	beq.l		slognp1d
   11029  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11030  1.1.6.2  bouyer 	beq.l		src_qnan
   11031  1.1.6.2  bouyer 	bra.l		src_snan
   11032  1.1.6.2  bouyer 
   11033  1.1.6.2  bouyer 	global		fetoxm1
   11034  1.1.6.2  bouyer fetoxm1:
   11035  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11036  1.1.6.2  bouyer 	beq.l		setoxm1
   11037  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11038  1.1.6.2  bouyer 	beq.l		src_zero
   11039  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11040  1.1.6.2  bouyer 	beq.l		setoxm1i
   11041  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11042  1.1.6.2  bouyer 	beq.l		setoxm1d
   11043  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11044  1.1.6.2  bouyer 	beq.l		src_qnan
   11045  1.1.6.2  bouyer 	bra.l		src_snan
   11046  1.1.6.2  bouyer 
   11047  1.1.6.2  bouyer 	global		ftanh
   11048  1.1.6.2  bouyer ftanh:
   11049  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11050  1.1.6.2  bouyer 	beq.l		stanh
   11051  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11052  1.1.6.2  bouyer 	beq.l		src_zero
   11053  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11054  1.1.6.2  bouyer 	beq.l		src_one
   11055  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11056  1.1.6.2  bouyer 	beq.l		stanhd
   11057  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11058  1.1.6.2  bouyer 	beq.l		src_qnan
   11059  1.1.6.2  bouyer 	bra.l		src_snan
   11060  1.1.6.2  bouyer 
   11061  1.1.6.2  bouyer 	global		fatan
   11062  1.1.6.2  bouyer fatan:
   11063  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11064  1.1.6.2  bouyer 	beq.l		satan
   11065  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11066  1.1.6.2  bouyer 	beq.l		src_zero
   11067  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11068  1.1.6.2  bouyer 	beq.l		spi_2
   11069  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11070  1.1.6.2  bouyer 	beq.l		satand
   11071  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11072  1.1.6.2  bouyer 	beq.l		src_qnan
   11073  1.1.6.2  bouyer 	bra.l		src_snan
   11074  1.1.6.2  bouyer 
   11075  1.1.6.2  bouyer 	global		fasin
   11076  1.1.6.2  bouyer fasin:
   11077  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11078  1.1.6.2  bouyer 	beq.l		sasin
   11079  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11080  1.1.6.2  bouyer 	beq.l		src_zero
   11081  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11082  1.1.6.2  bouyer 	beq.l		t_operr
   11083  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11084  1.1.6.2  bouyer 	beq.l		sasind
   11085  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11086  1.1.6.2  bouyer 	beq.l		src_qnan
   11087  1.1.6.2  bouyer 	bra.l		src_snan
   11088  1.1.6.2  bouyer 
   11089  1.1.6.2  bouyer 	global		fatanh
   11090  1.1.6.2  bouyer fatanh:
   11091  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11092  1.1.6.2  bouyer 	beq.l		satanh
   11093  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11094  1.1.6.2  bouyer 	beq.l		src_zero
   11095  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11096  1.1.6.2  bouyer 	beq.l		t_operr
   11097  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11098  1.1.6.2  bouyer 	beq.l		satanhd
   11099  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11100  1.1.6.2  bouyer 	beq.l		src_qnan
   11101  1.1.6.2  bouyer 	bra.l		src_snan
   11102  1.1.6.2  bouyer 
   11103  1.1.6.2  bouyer 	global		fsine
   11104  1.1.6.2  bouyer fsine:
   11105  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11106  1.1.6.2  bouyer 	beq.l		ssin
   11107  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11108  1.1.6.2  bouyer 	beq.l		src_zero
   11109  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11110  1.1.6.2  bouyer 	beq.l		t_operr
   11111  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11112  1.1.6.2  bouyer 	beq.l		ssind
   11113  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11114  1.1.6.2  bouyer 	beq.l		src_qnan
   11115  1.1.6.2  bouyer 	bra.l		src_snan
   11116  1.1.6.2  bouyer 
   11117  1.1.6.2  bouyer 	global		ftan
   11118  1.1.6.2  bouyer ftan:
   11119  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11120  1.1.6.2  bouyer 	beq.l		stan
   11121  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11122  1.1.6.2  bouyer 	beq.l		src_zero
   11123  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11124  1.1.6.2  bouyer 	beq.l		t_operr
   11125  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11126  1.1.6.2  bouyer 	beq.l		stand
   11127  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11128  1.1.6.2  bouyer 	beq.l		src_qnan
   11129  1.1.6.2  bouyer 	bra.l		src_snan
   11130  1.1.6.2  bouyer 
   11131  1.1.6.2  bouyer 	global		fetox
   11132  1.1.6.2  bouyer fetox:
   11133  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11134  1.1.6.2  bouyer 	beq.l		setox
   11135  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11136  1.1.6.2  bouyer 	beq.l		ld_pone
   11137  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11138  1.1.6.2  bouyer 	beq.l		szr_inf
   11139  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11140  1.1.6.2  bouyer 	beq.l		setoxd
   11141  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11142  1.1.6.2  bouyer 	beq.l		src_qnan
   11143  1.1.6.2  bouyer 	bra.l		src_snan
   11144  1.1.6.2  bouyer 
   11145  1.1.6.2  bouyer 	global		ftwotox
   11146  1.1.6.2  bouyer ftwotox:
   11147  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11148  1.1.6.2  bouyer 	beq.l		stwotox
   11149  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11150  1.1.6.2  bouyer 	beq.l		ld_pone
   11151  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11152  1.1.6.2  bouyer 	beq.l		szr_inf
   11153  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11154  1.1.6.2  bouyer 	beq.l		stwotoxd
   11155  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11156  1.1.6.2  bouyer 	beq.l		src_qnan
   11157  1.1.6.2  bouyer 	bra.l		src_snan
   11158  1.1.6.2  bouyer 
   11159  1.1.6.2  bouyer 	global		ftentox
   11160  1.1.6.2  bouyer ftentox:
   11161  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11162  1.1.6.2  bouyer 	beq.l		stentox
   11163  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11164  1.1.6.2  bouyer 	beq.l		ld_pone
   11165  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11166  1.1.6.2  bouyer 	beq.l		szr_inf
   11167  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11168  1.1.6.2  bouyer 	beq.l		stentoxd
   11169  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11170  1.1.6.2  bouyer 	beq.l		src_qnan
   11171  1.1.6.2  bouyer 	bra.l		src_snan
   11172  1.1.6.2  bouyer 
   11173  1.1.6.2  bouyer 	global		flogn
   11174  1.1.6.2  bouyer flogn:
   11175  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11176  1.1.6.2  bouyer 	beq.l		slogn
   11177  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11178  1.1.6.2  bouyer 	beq.l		t_dz2
   11179  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11180  1.1.6.2  bouyer 	beq.l		sopr_inf
   11181  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11182  1.1.6.2  bouyer 	beq.l		slognd
   11183  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11184  1.1.6.2  bouyer 	beq.l		src_qnan
   11185  1.1.6.2  bouyer 	bra.l		src_snan
   11186  1.1.6.2  bouyer 
   11187  1.1.6.2  bouyer 	global		flog10
   11188  1.1.6.2  bouyer flog10:
   11189  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11190  1.1.6.2  bouyer 	beq.l		slog10
   11191  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11192  1.1.6.2  bouyer 	beq.l		t_dz2
   11193  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11194  1.1.6.2  bouyer 	beq.l		sopr_inf
   11195  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11196  1.1.6.2  bouyer 	beq.l		slog10d
   11197  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11198  1.1.6.2  bouyer 	beq.l		src_qnan
   11199  1.1.6.2  bouyer 	bra.l		src_snan
   11200  1.1.6.2  bouyer 
   11201  1.1.6.2  bouyer 	global		flog2
   11202  1.1.6.2  bouyer flog2:
   11203  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11204  1.1.6.2  bouyer 	beq.l		slog2
   11205  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11206  1.1.6.2  bouyer 	beq.l		t_dz2
   11207  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11208  1.1.6.2  bouyer 	beq.l		sopr_inf
   11209  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11210  1.1.6.2  bouyer 	beq.l		slog2d
   11211  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11212  1.1.6.2  bouyer 	beq.l		src_qnan
   11213  1.1.6.2  bouyer 	bra.l		src_snan
   11214  1.1.6.2  bouyer 
   11215  1.1.6.2  bouyer 	global		fcosh
   11216  1.1.6.2  bouyer fcosh:
   11217  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11218  1.1.6.2  bouyer 	beq.l		scosh
   11219  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11220  1.1.6.2  bouyer 	beq.l		ld_pone
   11221  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11222  1.1.6.2  bouyer 	beq.l		ld_pinf
   11223  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11224  1.1.6.2  bouyer 	beq.l		scoshd
   11225  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11226  1.1.6.2  bouyer 	beq.l		src_qnan
   11227  1.1.6.2  bouyer 	bra.l		src_snan
   11228  1.1.6.2  bouyer 
   11229  1.1.6.2  bouyer 	global		facos
   11230  1.1.6.2  bouyer facos:
   11231  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11232  1.1.6.2  bouyer 	beq.l		sacos
   11233  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11234  1.1.6.2  bouyer 	beq.l		ld_ppi2
   11235  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11236  1.1.6.2  bouyer 	beq.l		t_operr
   11237  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11238  1.1.6.2  bouyer 	beq.l		sacosd
   11239  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11240  1.1.6.2  bouyer 	beq.l		src_qnan
   11241  1.1.6.2  bouyer 	bra.l		src_snan
   11242  1.1.6.2  bouyer 
   11243  1.1.6.2  bouyer 	global		fcos
   11244  1.1.6.2  bouyer fcos:
   11245  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11246  1.1.6.2  bouyer 	beq.l		scos
   11247  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11248  1.1.6.2  bouyer 	beq.l		ld_pone
   11249  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11250  1.1.6.2  bouyer 	beq.l		t_operr
   11251  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11252  1.1.6.2  bouyer 	beq.l		scosd
   11253  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11254  1.1.6.2  bouyer 	beq.l		src_qnan
   11255  1.1.6.2  bouyer 	bra.l		src_snan
   11256  1.1.6.2  bouyer 
   11257  1.1.6.2  bouyer 	global		fgetexp
   11258  1.1.6.2  bouyer fgetexp:
   11259  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11260  1.1.6.2  bouyer 	beq.l		sgetexp
   11261  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11262  1.1.6.2  bouyer 	beq.l		src_zero
   11263  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11264  1.1.6.2  bouyer 	beq.l		t_operr
   11265  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11266  1.1.6.2  bouyer 	beq.l		sgetexpd
   11267  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11268  1.1.6.2  bouyer 	beq.l		src_qnan
   11269  1.1.6.2  bouyer 	bra.l		src_snan
   11270  1.1.6.2  bouyer 
   11271  1.1.6.2  bouyer 	global		fgetman
   11272  1.1.6.2  bouyer fgetman:
   11273  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11274  1.1.6.2  bouyer 	beq.l		sgetman
   11275  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11276  1.1.6.2  bouyer 	beq.l		src_zero
   11277  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11278  1.1.6.2  bouyer 	beq.l		t_operr
   11279  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11280  1.1.6.2  bouyer 	beq.l		sgetmand
   11281  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11282  1.1.6.2  bouyer 	beq.l		src_qnan
   11283  1.1.6.2  bouyer 	bra.l		src_snan
   11284  1.1.6.2  bouyer 
   11285  1.1.6.2  bouyer 	global		fsincos
   11286  1.1.6.2  bouyer fsincos:
   11287  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11288  1.1.6.2  bouyer 	beq.l		ssincos
   11289  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11290  1.1.6.2  bouyer 	beq.l		ssincosz
   11291  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11292  1.1.6.2  bouyer 	beq.l		ssincosi
   11293  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11294  1.1.6.2  bouyer 	beq.l		ssincosd
   11295  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11296  1.1.6.2  bouyer 	beq.l		ssincosqnan
   11297  1.1.6.2  bouyer 	bra.l		ssincossnan
   11298  1.1.6.2  bouyer 
   11299  1.1.6.2  bouyer 	global		fmod
   11300  1.1.6.2  bouyer fmod:
   11301  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11302  1.1.6.2  bouyer 	beq.l		smod_snorm
   11303  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11304  1.1.6.2  bouyer 	beq.l		smod_szero
   11305  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11306  1.1.6.2  bouyer 	beq.l		smod_sinf
   11307  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11308  1.1.6.2  bouyer 	beq.l		smod_sdnrm
   11309  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11310  1.1.6.2  bouyer 	beq.l		sop_sqnan
   11311  1.1.6.2  bouyer 	bra.l		sop_ssnan
   11312  1.1.6.2  bouyer 
   11313  1.1.6.2  bouyer 	global		frem
   11314  1.1.6.2  bouyer frem:
   11315  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11316  1.1.6.2  bouyer 	beq.l		srem_snorm
   11317  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11318  1.1.6.2  bouyer 	beq.l		srem_szero
   11319  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11320  1.1.6.2  bouyer 	beq.l		srem_sinf
   11321  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11322  1.1.6.2  bouyer 	beq.l		srem_sdnrm
   11323  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11324  1.1.6.2  bouyer 	beq.l		sop_sqnan
   11325  1.1.6.2  bouyer 	bra.l		sop_ssnan
   11326  1.1.6.2  bouyer 
   11327  1.1.6.2  bouyer 	global		fscale
   11328  1.1.6.2  bouyer fscale:
   11329  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   11330  1.1.6.2  bouyer 	beq.l		sscale_snorm
   11331  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO
   11332  1.1.6.2  bouyer 	beq.l		sscale_szero
   11333  1.1.6.2  bouyer 	cmpi.b		%d1,&INF
   11334  1.1.6.2  bouyer 	beq.l		sscale_sinf
   11335  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM
   11336  1.1.6.2  bouyer 	beq.l		sscale_sdnrm
   11337  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN
   11338  1.1.6.2  bouyer 	beq.l		sop_sqnan
   11339  1.1.6.2  bouyer 	bra.l		sop_ssnan
   11340  1.1.6.2  bouyer 
   11341  1.1.6.2  bouyer #########################################################################
   11342  1.1.6.2  bouyer # XDEF ****************************************************************	#
   11343  1.1.6.2  bouyer # 	fgen_except(): catch an exception during transcendental 	#
   11344  1.1.6.2  bouyer #		       emulation					#
   11345  1.1.6.2  bouyer #									#
   11346  1.1.6.2  bouyer # XREF ****************************************************************	#
   11347  1.1.6.2  bouyer #	fmul() - emulate a multiply instruction				#
   11348  1.1.6.2  bouyer #	fadd() - emulate an add instruction				#
   11349  1.1.6.2  bouyer #	fin() - emulate an fmove instruction				#
   11350  1.1.6.2  bouyer #									#
   11351  1.1.6.2  bouyer # INPUT ***************************************************************	#
   11352  1.1.6.2  bouyer #	fp0 = destination operand					#
   11353  1.1.6.2  bouyer #	d0  = type of instruction that took exception			#
   11354  1.1.6.2  bouyer #	fsave frame = source operand					#
   11355  1.1.6.2  bouyer # 									#
   11356  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   11357  1.1.6.2  bouyer #	fp0 = result							#
   11358  1.1.6.2  bouyer #	fp1 = EXOP							#
   11359  1.1.6.2  bouyer #									#
   11360  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   11361  1.1.6.2  bouyer # 	An exception occurred on the last instruction of the 		#
   11362  1.1.6.2  bouyer # transcendental emulation. hopefully, this won't be happening much 	#
   11363  1.1.6.2  bouyer # because it will be VERY slow.						#
   11364  1.1.6.2  bouyer # 	The only exceptions capable of passing through here are		#
   11365  1.1.6.2  bouyer # Overflow, Underflow, and Unsupported Data Type.			#
   11366  1.1.6.2  bouyer #									#
   11367  1.1.6.2  bouyer #########################################################################
   11368  1.1.6.2  bouyer 
   11369  1.1.6.2  bouyer 	global		fgen_except
   11370  1.1.6.2  bouyer fgen_except:
   11371  1.1.6.2  bouyer 	cmpi.b		0x3(%sp),&0x7		# is exception UNSUPP?
   11372  1.1.6.2  bouyer 	beq.b		fge_unsupp		# yes
   11373  1.1.6.2  bouyer 
   11374  1.1.6.2  bouyer 	mov.b		&NORM,STAG(%a6)
   11375  1.1.6.2  bouyer 
   11376  1.1.6.2  bouyer fge_cont:
   11377  1.1.6.2  bouyer 	mov.b		&NORM,DTAG(%a6)
   11378  1.1.6.2  bouyer 
   11379  1.1.6.2  bouyer # ok, I have a problem with putting the dst op at FP_DST. the emulation
   11380  1.1.6.2  bouyer # routines aren't supposed to alter the operands but we've just squashed
   11381  1.1.6.2  bouyer # FP_DST here...
   11382  1.1.6.2  bouyer 
   11383  1.1.6.2  bouyer # 8/17/93 - this turns out to be more of a "cleanliness" standpoint
   11384  1.1.6.2  bouyer # then a potential bug. to begin with, only the dyadic functions
   11385  1.1.6.2  bouyer # frem,fmod, and fscale would get the dst trashed here. But, for
   11386  1.1.6.2  bouyer # the 060SP, the FP_DST is never used again anyways.
   11387  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_DST(%a6)	# dst op is in fp0
   11388  1.1.6.2  bouyer 
   11389  1.1.6.2  bouyer 	lea		0x4(%sp),%a0		# pass: ptr to src op
   11390  1.1.6.2  bouyer 	lea		FP_DST(%a6),%a1		# pass: ptr to dst op
   11391  1.1.6.2  bouyer 
   11392  1.1.6.2  bouyer 	cmpi.b		%d1,&FMOV_OP
   11393  1.1.6.2  bouyer 	beq.b		fge_fin			# it was an "fmov"
   11394  1.1.6.2  bouyer 	cmpi.b		%d1,&FADD_OP
   11395  1.1.6.2  bouyer 	beq.b		fge_fadd		# it was an "fadd"
   11396  1.1.6.2  bouyer fge_fmul:
   11397  1.1.6.2  bouyer 	bsr.l		fmul
   11398  1.1.6.2  bouyer 	rts
   11399  1.1.6.2  bouyer fge_fadd:
   11400  1.1.6.2  bouyer 	bsr.l		fadd
   11401  1.1.6.2  bouyer 	rts
   11402  1.1.6.2  bouyer fge_fin:
   11403  1.1.6.2  bouyer 	bsr.l		fin
   11404  1.1.6.2  bouyer 	rts
   11405  1.1.6.2  bouyer 
   11406  1.1.6.2  bouyer fge_unsupp:
   11407  1.1.6.2  bouyer 	mov.b		&DENORM,STAG(%a6)
   11408  1.1.6.2  bouyer 	bra.b		fge_cont
   11409  1.1.6.2  bouyer 
   11410  1.1.6.2  bouyer #
   11411  1.1.6.2  bouyer # This table holds the offsets of the emulation routines for each individual
   11412  1.1.6.2  bouyer # math operation relative to the address of this table. Included are
   11413  1.1.6.2  bouyer # routines like fadd/fmul/fabs as well as the transcendentals.
   11414  1.1.6.2  bouyer # The location within the table is determined by the extension bits of the
   11415  1.1.6.2  bouyer # operation longword.
   11416  1.1.6.2  bouyer #
   11417  1.1.6.2  bouyer 
   11418  1.1.6.2  bouyer 	swbeg		&109
   11419  1.1.6.2  bouyer tbl_unsupp:
   11420  1.1.6.2  bouyer 	long		fin	 	- tbl_unsupp	# 00: fmove
   11421  1.1.6.2  bouyer 	long		fint	 	- tbl_unsupp	# 01: fint
   11422  1.1.6.2  bouyer 	long		fsinh	 	- tbl_unsupp	# 02: fsinh
   11423  1.1.6.2  bouyer 	long		fintrz	 	- tbl_unsupp	# 03: fintrz
   11424  1.1.6.2  bouyer 	long		fsqrt	 	- tbl_unsupp	# 04: fsqrt
   11425  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11426  1.1.6.2  bouyer 	long		flognp1		- tbl_unsupp	# 06: flognp1
   11427  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11428  1.1.6.2  bouyer 	long		fetoxm1		- tbl_unsupp	# 08: fetoxm1
   11429  1.1.6.2  bouyer 	long		ftanh		- tbl_unsupp	# 09: ftanh
   11430  1.1.6.2  bouyer 	long		fatan		- tbl_unsupp	# 0a: fatan
   11431  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11432  1.1.6.2  bouyer 	long		fasin		- tbl_unsupp	# 0c: fasin
   11433  1.1.6.2  bouyer 	long		fatanh		- tbl_unsupp	# 0d: fatanh
   11434  1.1.6.2  bouyer 	long		fsine		- tbl_unsupp	# 0e: fsin
   11435  1.1.6.2  bouyer 	long		ftan		- tbl_unsupp	# 0f: ftan
   11436  1.1.6.2  bouyer 	long		fetox		- tbl_unsupp	# 10: fetox
   11437  1.1.6.2  bouyer 	long		ftwotox		- tbl_unsupp	# 11: ftwotox
   11438  1.1.6.2  bouyer 	long		ftentox		- tbl_unsupp	# 12: ftentox
   11439  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11440  1.1.6.2  bouyer 	long		flogn		- tbl_unsupp	# 14: flogn
   11441  1.1.6.2  bouyer 	long		flog10		- tbl_unsupp	# 15: flog10
   11442  1.1.6.2  bouyer 	long		flog2		- tbl_unsupp	# 16: flog2
   11443  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11444  1.1.6.2  bouyer 	long		fabs		- tbl_unsupp 	# 18: fabs
   11445  1.1.6.2  bouyer 	long		fcosh		- tbl_unsupp	# 19: fcosh
   11446  1.1.6.2  bouyer 	long		fneg		- tbl_unsupp 	# 1a: fneg
   11447  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11448  1.1.6.2  bouyer 	long		facos		- tbl_unsupp	# 1c: facos
   11449  1.1.6.2  bouyer 	long		fcos		- tbl_unsupp	# 1d: fcos
   11450  1.1.6.2  bouyer 	long		fgetexp		- tbl_unsupp	# 1e: fgetexp
   11451  1.1.6.2  bouyer 	long		fgetman		- tbl_unsupp	# 1f: fgetman
   11452  1.1.6.2  bouyer 	long		fdiv		- tbl_unsupp 	# 20: fdiv
   11453  1.1.6.2  bouyer 	long		fmod		- tbl_unsupp	# 21: fmod
   11454  1.1.6.2  bouyer 	long		fadd		- tbl_unsupp 	# 22: fadd
   11455  1.1.6.2  bouyer 	long		fmul		- tbl_unsupp 	# 23: fmul
   11456  1.1.6.2  bouyer 	long		fsgldiv		- tbl_unsupp 	# 24: fsgldiv
   11457  1.1.6.2  bouyer 	long		frem		- tbl_unsupp	# 25: frem
   11458  1.1.6.2  bouyer 	long		fscale		- tbl_unsupp	# 26: fscale
   11459  1.1.6.2  bouyer 	long		fsglmul		- tbl_unsupp 	# 27: fsglmul
   11460  1.1.6.2  bouyer 	long		fsub		- tbl_unsupp 	# 28: fsub
   11461  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11462  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11463  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11464  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11465  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11466  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11467  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11468  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 30: fsincos
   11469  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 31: fsincos
   11470  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 32: fsincos
   11471  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 33: fsincos
   11472  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 34: fsincos
   11473  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 35: fsincos
   11474  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 36: fsincos
   11475  1.1.6.2  bouyer 	long		fsincos		- tbl_unsupp	# 37: fsincos
   11476  1.1.6.2  bouyer 	long		fcmp		- tbl_unsupp 	# 38: fcmp
   11477  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11478  1.1.6.2  bouyer 	long		ftst		- tbl_unsupp 	# 3a: ftst
   11479  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11480  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11481  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11482  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11483  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11484  1.1.6.2  bouyer 	long		fsin		- tbl_unsupp 	# 40: fsmove
   11485  1.1.6.2  bouyer 	long		fssqrt		- tbl_unsupp 	# 41: fssqrt
   11486  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11487  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11488  1.1.6.2  bouyer 	long		fdin		- tbl_unsupp	# 44: fdmove
   11489  1.1.6.2  bouyer 	long		fdsqrt		- tbl_unsupp 	# 45: fdsqrt
   11490  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11491  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11492  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11493  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11494  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11495  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11496  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11497  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11498  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11499  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11500  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11501  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11502  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11503  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11504  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11505  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11506  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11507  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11508  1.1.6.2  bouyer 	long		fsabs		- tbl_unsupp 	# 58: fsabs
   11509  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11510  1.1.6.2  bouyer 	long		fsneg		- tbl_unsupp 	# 5a: fsneg
   11511  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11512  1.1.6.2  bouyer 	long		fdabs		- tbl_unsupp	# 5c: fdabs
   11513  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11514  1.1.6.2  bouyer 	long		fdneg		- tbl_unsupp 	# 5e: fdneg
   11515  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11516  1.1.6.2  bouyer 	long		fsdiv		- tbl_unsupp	# 60: fsdiv
   11517  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11518  1.1.6.2  bouyer 	long		fsadd		- tbl_unsupp	# 62: fsadd
   11519  1.1.6.2  bouyer 	long		fsmul		- tbl_unsupp	# 63: fsmul
   11520  1.1.6.2  bouyer 	long		fddiv		- tbl_unsupp 	# 64: fddiv
   11521  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11522  1.1.6.2  bouyer 	long		fdadd		- tbl_unsupp	# 66: fdadd
   11523  1.1.6.2  bouyer 	long		fdmul		- tbl_unsupp 	# 67: fdmul
   11524  1.1.6.2  bouyer 	long		fssub		- tbl_unsupp	# 68: fssub
   11525  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11526  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11527  1.1.6.2  bouyer 	long		tbl_unsupp	- tbl_unsupp
   11528  1.1.6.2  bouyer 	long		fdsub		- tbl_unsupp 	# 6c: fdsub
   11529  1.1.6.2  bouyer 
   11530  1.1.6.2  bouyer #########################################################################
   11531  1.1.6.2  bouyer # XDEF ****************************************************************	#
   11532  1.1.6.2  bouyer # 	fmul(): emulates the fmul instruction				#
   11533  1.1.6.2  bouyer #	fsmul(): emulates the fsmul instruction				#
   11534  1.1.6.2  bouyer #	fdmul(): emulates the fdmul instruction				#
   11535  1.1.6.2  bouyer #									#
   11536  1.1.6.2  bouyer # XREF ****************************************************************	#
   11537  1.1.6.2  bouyer #	scale_to_zero_src() - scale src exponent to zero		#
   11538  1.1.6.2  bouyer #	scale_to_zero_dst() - scale dst exponent to zero		#
   11539  1.1.6.2  bouyer #	unf_res() - return default underflow result			#
   11540  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   11541  1.1.6.2  bouyer # 	res_qnan() - return QNAN result					#
   11542  1.1.6.2  bouyer # 	res_snan() - return SNAN result					#
   11543  1.1.6.2  bouyer #									#
   11544  1.1.6.2  bouyer # INPUT ***************************************************************	#
   11545  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   11546  1.1.6.2  bouyer #	a1 = pointer to extended precision destination operand		#
   11547  1.1.6.2  bouyer #	d0  rnd prec,mode						#
   11548  1.1.6.2  bouyer #									#
   11549  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   11550  1.1.6.2  bouyer #	fp0 = result							#
   11551  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   11552  1.1.6.2  bouyer #									#
   11553  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   11554  1.1.6.2  bouyer #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   11555  1.1.6.2  bouyer # norms/denorms into ext/sgl/dbl precision.				#
   11556  1.1.6.2  bouyer #	For norms/denorms, scale the exponents such that a multiply	#
   11557  1.1.6.2  bouyer # instruction won't cause an exception. Use the regular fmul to		#
   11558  1.1.6.2  bouyer # compute a result. Check if the regular operands would have taken	#
   11559  1.1.6.2  bouyer # an exception. If so, return the default overflow/underflow result	#
   11560  1.1.6.2  bouyer # and return the EXOP if exceptions are enabled. Else, scale the 	#
   11561  1.1.6.2  bouyer # result operand to the proper exponent.				#
   11562  1.1.6.2  bouyer #									#
   11563  1.1.6.2  bouyer #########################################################################
   11564  1.1.6.2  bouyer 
   11565  1.1.6.2  bouyer 	align 		0x10
   11566  1.1.6.2  bouyer tbl_fmul_ovfl:
   11567  1.1.6.2  bouyer 	long		0x3fff - 0x7ffe		# ext_max
   11568  1.1.6.2  bouyer 	long		0x3fff - 0x407e		# sgl_max
   11569  1.1.6.2  bouyer 	long		0x3fff - 0x43fe		# dbl_max
   11570  1.1.6.2  bouyer tbl_fmul_unfl:
   11571  1.1.6.2  bouyer 	long		0x3fff + 0x0001		# ext_unfl
   11572  1.1.6.2  bouyer 	long		0x3fff - 0x3f80		# sgl_unfl
   11573  1.1.6.2  bouyer 	long		0x3fff - 0x3c00		# dbl_unfl
   11574  1.1.6.2  bouyer 
   11575  1.1.6.2  bouyer 	global		fsmul
   11576  1.1.6.2  bouyer fsmul:
   11577  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   11578  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   11579  1.1.6.2  bouyer 	bra.b		fmul
   11580  1.1.6.2  bouyer 
   11581  1.1.6.2  bouyer 	global		fdmul
   11582  1.1.6.2  bouyer fdmul:
   11583  1.1.6.2  bouyer 	andi.b		&0x30,%d0
   11584  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   11585  1.1.6.2  bouyer 
   11586  1.1.6.2  bouyer 	global		fmul
   11587  1.1.6.2  bouyer fmul:
   11588  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   11589  1.1.6.2  bouyer 
   11590  1.1.6.2  bouyer 	clr.w		%d1
   11591  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   11592  1.1.6.2  bouyer 	lsl.b		&0x3,%d1
   11593  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1		# combine src tags
   11594  1.1.6.2  bouyer 	bne.w		fmul_not_norm		# optimize on non-norm input
   11595  1.1.6.2  bouyer 
   11596  1.1.6.2  bouyer fmul_norm:
   11597  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   11598  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   11599  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   11600  1.1.6.2  bouyer 
   11601  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   11602  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   11603  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   11604  1.1.6.2  bouyer 
   11605  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# scale src exponent
   11606  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save scale factor 1
   11607  1.1.6.2  bouyer 
   11608  1.1.6.2  bouyer 	bsr.l		scale_to_zero_dst	# scale dst exponent
   11609  1.1.6.2  bouyer 
   11610  1.1.6.2  bouyer 	add.l		%d0,(%sp)		# SCALE_FACTOR = scale1 + scale2
   11611  1.1.6.2  bouyer 
   11612  1.1.6.2  bouyer 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision
   11613  1.1.6.2  bouyer 	lsr.b		&0x6,%d1		# shift to lo bits
   11614  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# load S.F.
   11615  1.1.6.2  bouyer 	cmp.l		%d0,(tbl_fmul_ovfl.w,%pc,%d1.w*4) # would result ovfl?
   11616  1.1.6.2  bouyer 	beq.w		fmul_may_ovfl		# result may rnd to overflow
   11617  1.1.6.2  bouyer 	blt.w		fmul_ovfl		# result will overflow
   11618  1.1.6.2  bouyer 
   11619  1.1.6.2  bouyer 	cmp.l		%d0,(tbl_fmul_unfl.w,%pc,%d1.w*4) # would result unfl?
   11620  1.1.6.2  bouyer 	beq.w		fmul_may_unfl		# result may rnd to no unfl
   11621  1.1.6.2  bouyer 	bgt.w		fmul_unfl		# result will underflow
   11622  1.1.6.2  bouyer 
   11623  1.1.6.2  bouyer #
   11624  1.1.6.2  bouyer # NORMAL:
   11625  1.1.6.2  bouyer # - the result of the multiply operation will neither overflow nor underflow.
   11626  1.1.6.2  bouyer # - do the multiply to the proper precision and rounding mode.
   11627  1.1.6.2  bouyer # - scale the result exponent using the scale factor. if both operands were
   11628  1.1.6.2  bouyer # normalized then we really don't need to go through this scaling. but for now,
   11629  1.1.6.2  bouyer # this will do.
   11630  1.1.6.2  bouyer #
   11631  1.1.6.2  bouyer fmul_normal:
   11632  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11633  1.1.6.2  bouyer 
   11634  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11635  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   11636  1.1.6.2  bouyer 
   11637  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11638  1.1.6.2  bouyer 
   11639  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   11640  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11641  1.1.6.2  bouyer 
   11642  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11643  1.1.6.2  bouyer 
   11644  1.1.6.2  bouyer fmul_normal_exit:
   11645  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   11646  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   11647  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   11648  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   11649  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   11650  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   11651  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   11652  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   11653  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   11654  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   11655  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   11656  1.1.6.2  bouyer 	rts
   11657  1.1.6.2  bouyer 
   11658  1.1.6.2  bouyer #
   11659  1.1.6.2  bouyer # OVERFLOW:
   11660  1.1.6.2  bouyer # - the result of the multiply operation is an overflow.
   11661  1.1.6.2  bouyer # - do the multiply to the proper precision and rounding mode in order to
   11662  1.1.6.2  bouyer # set the inexact bits.
   11663  1.1.6.2  bouyer # - calculate the default result and return it in fp0.
   11664  1.1.6.2  bouyer # - if overflow or inexact is enabled, we need a multiply result rounded to
   11665  1.1.6.2  bouyer # extended precision. if the original operation was extended, then we have this
   11666  1.1.6.2  bouyer # result. if the original operation was single or double, we have to do another
   11667  1.1.6.2  bouyer # multiply using extended precision and the correct rounding mode. the result
   11668  1.1.6.2  bouyer # of this operation then has its exponent scaled by -0x6000 to create the
   11669  1.1.6.2  bouyer # exceptional operand.
   11670  1.1.6.2  bouyer #
   11671  1.1.6.2  bouyer fmul_ovfl:
   11672  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11673  1.1.6.2  bouyer 
   11674  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11675  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   11676  1.1.6.2  bouyer 
   11677  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11678  1.1.6.2  bouyer 
   11679  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   11680  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11681  1.1.6.2  bouyer 
   11682  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11683  1.1.6.2  bouyer 
   11684  1.1.6.2  bouyer # save setting this until now because this is where fmul_may_ovfl may jump in
   11685  1.1.6.2  bouyer fmul_ovfl_tst:
   11686  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   11687  1.1.6.2  bouyer 
   11688  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   11689  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   11690  1.1.6.2  bouyer 	bne.b		fmul_ovfl_ena		# yes
   11691  1.1.6.2  bouyer 
   11692  1.1.6.2  bouyer # calculate the default result
   11693  1.1.6.2  bouyer fmul_ovfl_dis:
   11694  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   11695  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   11696  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass rnd prec,mode
   11697  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   11698  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   11699  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   11700  1.1.6.2  bouyer 	rts
   11701  1.1.6.2  bouyer 
   11702  1.1.6.2  bouyer #
   11703  1.1.6.2  bouyer # OVFL is enabled; Create EXOP:
   11704  1.1.6.2  bouyer # - if precision is extended, then we have the EXOP. simply bias the exponent
   11705  1.1.6.2  bouyer # with an extra -0x6000. if the precision is single or double, we need to
   11706  1.1.6.2  bouyer # calculate a result rounded to extended precision.
   11707  1.1.6.2  bouyer #
   11708  1.1.6.2  bouyer fmul_ovfl_ena:
   11709  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   11710  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# test the rnd prec
   11711  1.1.6.2  bouyer 	bne.b		fmul_ovfl_ena_sd	# it's sgl or dbl
   11712  1.1.6.2  bouyer 
   11713  1.1.6.2  bouyer fmul_ovfl_ena_cont:
   11714  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   11715  1.1.6.2  bouyer 
   11716  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   11717  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   11718  1.1.6.2  bouyer 	mov.w		%d1,%d2			# make a copy
   11719  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   11720  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   11721  1.1.6.2  bouyer 	subi.l		&0x6000,%d1		# subtract bias
   11722  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1		# clear sign bit
   11723  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   11724  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   11725  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   11726  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   11727  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   11728  1.1.6.2  bouyer 	bra.b		fmul_ovfl_dis
   11729  1.1.6.2  bouyer 
   11730  1.1.6.2  bouyer fmul_ovfl_ena_sd:
   11731  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11732  1.1.6.2  bouyer 
   11733  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   11734  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# keep rnd mode only
   11735  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   11736  1.1.6.2  bouyer 
   11737  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11738  1.1.6.2  bouyer 
   11739  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11740  1.1.6.2  bouyer 	bra.b		fmul_ovfl_ena_cont
   11741  1.1.6.2  bouyer 
   11742  1.1.6.2  bouyer #
   11743  1.1.6.2  bouyer # may OVERFLOW:
   11744  1.1.6.2  bouyer # - the result of the multiply operation MAY overflow.
   11745  1.1.6.2  bouyer # - do the multiply to the proper precision and rounding mode in order to
   11746  1.1.6.2  bouyer # set the inexact bits.
   11747  1.1.6.2  bouyer # - calculate the default result and return it in fp0.
   11748  1.1.6.2  bouyer #
   11749  1.1.6.2  bouyer fmul_may_ovfl:
   11750  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   11751  1.1.6.2  bouyer 
   11752  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11753  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   11754  1.1.6.2  bouyer 
   11755  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11756  1.1.6.2  bouyer 
   11757  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   11758  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11759  1.1.6.2  bouyer 
   11760  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11761  1.1.6.2  bouyer 
   11762  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   11763  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   11764  1.1.6.2  bouyer 	fbge.w		fmul_ovfl_tst		# yes; overflow has occurred
   11765  1.1.6.2  bouyer 
   11766  1.1.6.2  bouyer # no, it didn't overflow; we have correct result
   11767  1.1.6.2  bouyer 	bra.w		fmul_normal_exit
   11768  1.1.6.2  bouyer 
   11769  1.1.6.2  bouyer #
   11770  1.1.6.2  bouyer # UNDERFLOW:
   11771  1.1.6.2  bouyer # - the result of the multiply operation is an underflow.
   11772  1.1.6.2  bouyer # - do the multiply to the proper precision and rounding mode in order to
   11773  1.1.6.2  bouyer # set the inexact bits.
   11774  1.1.6.2  bouyer # - calculate the default result and return it in fp0.
   11775  1.1.6.2  bouyer # - if overflow or inexact is enabled, we need a multiply result rounded to
   11776  1.1.6.2  bouyer # extended precision. if the original operation was extended, then we have this
   11777  1.1.6.2  bouyer # result. if the original operation was single or double, we have to do another
   11778  1.1.6.2  bouyer # multiply using extended precision and the correct rounding mode. the result
   11779  1.1.6.2  bouyer # of this operation then has its exponent scaled by -0x6000 to create the
   11780  1.1.6.2  bouyer # exceptional operand.
   11781  1.1.6.2  bouyer #
   11782  1.1.6.2  bouyer fmul_unfl:
   11783  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   11784  1.1.6.2  bouyer 
   11785  1.1.6.2  bouyer # for fun, let's use only extended precision, round to zero. then, let
   11786  1.1.6.2  bouyer # the unf_res() routine figure out all the rest.
   11787  1.1.6.2  bouyer # will we get the correct answer.
   11788  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11789  1.1.6.2  bouyer 
   11790  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   11791  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   11792  1.1.6.2  bouyer 
   11793  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11794  1.1.6.2  bouyer 
   11795  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   11796  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11797  1.1.6.2  bouyer 
   11798  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11799  1.1.6.2  bouyer 
   11800  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   11801  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   11802  1.1.6.2  bouyer 	bne.b		fmul_unfl_ena		# yes
   11803  1.1.6.2  bouyer 
   11804  1.1.6.2  bouyer fmul_unfl_dis:
   11805  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   11806  1.1.6.2  bouyer 
   11807  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   11808  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   11809  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   11810  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# unf_res2 may have set 'Z'
   11811  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   11812  1.1.6.2  bouyer 	rts
   11813  1.1.6.2  bouyer 
   11814  1.1.6.2  bouyer #
   11815  1.1.6.2  bouyer # UNFL is enabled.
   11816  1.1.6.2  bouyer #
   11817  1.1.6.2  bouyer fmul_unfl_ena:
   11818  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   11819  1.1.6.2  bouyer 
   11820  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   11821  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# is precision extended?
   11822  1.1.6.2  bouyer 	bne.b		fmul_unfl_ena_sd	# no, sgl or dbl
   11823  1.1.6.2  bouyer 
   11824  1.1.6.2  bouyer # if the rnd mode is anything but RZ, then we have to re-do the above
   11825  1.1.6.2  bouyer # multiplication becuase we used RZ for all.
   11826  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11827  1.1.6.2  bouyer 
   11828  1.1.6.2  bouyer fmul_unfl_ena_cont:
   11829  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   11830  1.1.6.2  bouyer 
   11831  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp1	# execute multiply
   11832  1.1.6.2  bouyer 
   11833  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11834  1.1.6.2  bouyer 
   11835  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   11836  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   11837  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   11838  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   11839  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   11840  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   11841  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   11842  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add bias
   11843  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   11844  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   11845  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   11846  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   11847  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   11848  1.1.6.2  bouyer 	bra.w		fmul_unfl_dis
   11849  1.1.6.2  bouyer 
   11850  1.1.6.2  bouyer fmul_unfl_ena_sd:
   11851  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   11852  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# use only rnd mode
   11853  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   11854  1.1.6.2  bouyer 
   11855  1.1.6.2  bouyer 	bra.b		fmul_unfl_ena_cont
   11856  1.1.6.2  bouyer 
   11857  1.1.6.2  bouyer # MAY UNDERFLOW:
   11858  1.1.6.2  bouyer # -use the correct rounding mode and precision. this code favors operations
   11859  1.1.6.2  bouyer # that do not underflow.
   11860  1.1.6.2  bouyer fmul_may_unfl:
   11861  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   11862  1.1.6.2  bouyer 
   11863  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   11864  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   11865  1.1.6.2  bouyer 
   11866  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
   11867  1.1.6.2  bouyer 
   11868  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   11869  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11870  1.1.6.2  bouyer 
   11871  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   11872  1.1.6.2  bouyer 
   11873  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   11874  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| > 2.b?
   11875  1.1.6.2  bouyer 	fbgt.w		fmul_normal_exit	# no; no underflow occurred
   11876  1.1.6.2  bouyer 	fblt.w		fmul_unfl		# yes; underflow occurred
   11877  1.1.6.2  bouyer 
   11878  1.1.6.2  bouyer #
   11879  1.1.6.2  bouyer # we still don't know if underflow occurred. result is ~ equal to 2. but,
   11880  1.1.6.2  bouyer # we don't know if the result was an underflow that rounded up to a 2 or
   11881  1.1.6.2  bouyer # a normalized number that rounded down to a 2. so, redo the entire operation
   11882  1.1.6.2  bouyer # using RZ as the rounding mode to see what the pre-rounded result is.
   11883  1.1.6.2  bouyer # this case should be relatively rare.
   11884  1.1.6.2  bouyer #
   11885  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst operand
   11886  1.1.6.2  bouyer 
   11887  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   11888  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# keep rnd prec
   11889  1.1.6.2  bouyer 	ori.b		&rz_mode*0x10,%d1	# insert RZ
   11890  1.1.6.2  bouyer 
   11891  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   11892  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   11893  1.1.6.2  bouyer 
   11894  1.1.6.2  bouyer 	fmul.x		FP_SCR0(%a6),%fp1	# execute multiply
   11895  1.1.6.2  bouyer 
   11896  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   11897  1.1.6.2  bouyer 	fabs.x		%fp1			# make absolute value
   11898  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| < 2.b?
   11899  1.1.6.2  bouyer 	fbge.w		fmul_normal_exit	# no; no underflow occurred
   11900  1.1.6.2  bouyer 	bra.w		fmul_unfl		# yes, underflow occurred
   11901  1.1.6.2  bouyer 
   11902  1.1.6.2  bouyer ################################################################################
   11903  1.1.6.2  bouyer 
   11904  1.1.6.2  bouyer #
   11905  1.1.6.2  bouyer # Multiply: inputs are not both normalized; what are they?
   11906  1.1.6.2  bouyer #
   11907  1.1.6.2  bouyer fmul_not_norm:
   11908  1.1.6.2  bouyer 	mov.w		(tbl_fmul_op.b,%pc,%d1.w*2),%d1
   11909  1.1.6.2  bouyer 	jmp		(tbl_fmul_op.b,%pc,%d1.w)
   11910  1.1.6.2  bouyer 
   11911  1.1.6.2  bouyer 	swbeg		&48
   11912  1.1.6.2  bouyer tbl_fmul_op:
   11913  1.1.6.2  bouyer 	short		fmul_norm	- tbl_fmul_op # NORM x NORM
   11914  1.1.6.2  bouyer 	short		fmul_zero	- tbl_fmul_op # NORM x ZERO
   11915  1.1.6.2  bouyer 	short		fmul_inf_src	- tbl_fmul_op # NORM x INF
   11916  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # NORM x QNAN
   11917  1.1.6.2  bouyer 	short		fmul_norm	- tbl_fmul_op # NORM x DENORM
   11918  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # NORM x SNAN
   11919  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11920  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11921  1.1.6.2  bouyer 
   11922  1.1.6.2  bouyer 	short		fmul_zero	- tbl_fmul_op # ZERO x NORM
   11923  1.1.6.2  bouyer 	short		fmul_zero	- tbl_fmul_op # ZERO x ZERO
   11924  1.1.6.2  bouyer 	short		fmul_res_operr	- tbl_fmul_op # ZERO x INF
   11925  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # ZERO x QNAN
   11926  1.1.6.2  bouyer 	short		fmul_zero	- tbl_fmul_op # ZERO x DENORM
   11927  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # ZERO x SNAN
   11928  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11929  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11930  1.1.6.2  bouyer 
   11931  1.1.6.2  bouyer 	short		fmul_inf_dst	- tbl_fmul_op # INF x NORM
   11932  1.1.6.2  bouyer 	short		fmul_res_operr	- tbl_fmul_op # INF x ZERO
   11933  1.1.6.2  bouyer 	short		fmul_inf_dst	- tbl_fmul_op # INF x INF
   11934  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # INF x QNAN
   11935  1.1.6.2  bouyer 	short		fmul_inf_dst	- tbl_fmul_op # INF x DENORM
   11936  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # INF x SNAN
   11937  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11938  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11939  1.1.6.2  bouyer 
   11940  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x NORM
   11941  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x ZERO
   11942  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x INF
   11943  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x QNAN
   11944  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x DENORM
   11945  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # QNAN x SNAN
   11946  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11947  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11948  1.1.6.2  bouyer 
   11949  1.1.6.2  bouyer 	short		fmul_norm	- tbl_fmul_op # NORM x NORM
   11950  1.1.6.2  bouyer 	short		fmul_zero	- tbl_fmul_op # NORM x ZERO
   11951  1.1.6.2  bouyer 	short		fmul_inf_src	- tbl_fmul_op # NORM x INF
   11952  1.1.6.2  bouyer 	short		fmul_res_qnan	- tbl_fmul_op # NORM x QNAN
   11953  1.1.6.2  bouyer 	short		fmul_norm	- tbl_fmul_op # NORM x DENORM
   11954  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # NORM x SNAN
   11955  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11956  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11957  1.1.6.2  bouyer 
   11958  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # SNAN x NORM
   11959  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # SNAN x ZERO
   11960  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # SNAN x INF
   11961  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # SNAN x QNAN
   11962  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # SNAN x DENORM
   11963  1.1.6.2  bouyer 	short		fmul_res_snan	- tbl_fmul_op # SNAN x SNAN
   11964  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11965  1.1.6.2  bouyer 	short		tbl_fmul_op	- tbl_fmul_op #
   11966  1.1.6.2  bouyer 
   11967  1.1.6.2  bouyer fmul_res_operr:
   11968  1.1.6.2  bouyer 	bra.l		res_operr
   11969  1.1.6.2  bouyer fmul_res_snan:
   11970  1.1.6.2  bouyer 	bra.l		res_snan
   11971  1.1.6.2  bouyer fmul_res_qnan:
   11972  1.1.6.2  bouyer 	bra.l		res_qnan
   11973  1.1.6.2  bouyer 
   11974  1.1.6.2  bouyer #
   11975  1.1.6.2  bouyer # Multiply: (Zero x Zero) || (Zero x norm) || (Zero x denorm)
   11976  1.1.6.2  bouyer #
   11977  1.1.6.2  bouyer 	global		fmul_zero		# global for fsglmul
   11978  1.1.6.2  bouyer fmul_zero:
   11979  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   11980  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   11981  1.1.6.2  bouyer 	eor.b		%d0,%d1
   11982  1.1.6.2  bouyer 	bpl.b		fmul_zero_p		# result ZERO is pos.
   11983  1.1.6.2  bouyer fmul_zero_n:
   11984  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# load -ZERO
   11985  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/N
   11986  1.1.6.2  bouyer 	rts
   11987  1.1.6.2  bouyer fmul_zero_p:
   11988  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# load +ZERO
   11989  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   11990  1.1.6.2  bouyer 	rts
   11991  1.1.6.2  bouyer 
   11992  1.1.6.2  bouyer #
   11993  1.1.6.2  bouyer # Multiply: (inf x inf) || (inf x norm) || (inf x denorm)
   11994  1.1.6.2  bouyer #
   11995  1.1.6.2  bouyer # Note: The j-bit for an infinity is a don't-care. However, to be
   11996  1.1.6.2  bouyer # strictly compatible w/ the 68881/882, we make sure to return an
   11997  1.1.6.2  bouyer # INF w/ the j-bit set if the input INF j-bit was set. Destination
   11998  1.1.6.2  bouyer # INFs take priority.
   11999  1.1.6.2  bouyer #
   12000  1.1.6.2  bouyer 	global		fmul_inf_dst		# global for fsglmul
   12001  1.1.6.2  bouyer fmul_inf_dst:
   12002  1.1.6.2  bouyer 	fmovm.x		DST(%a1),&0x80		# return INF result in fp0
   12003  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   12004  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   12005  1.1.6.2  bouyer 	eor.b		%d0,%d1
   12006  1.1.6.2  bouyer 	bpl.b		fmul_inf_dst_p		# result INF is pos.
   12007  1.1.6.2  bouyer fmul_inf_dst_n:
   12008  1.1.6.2  bouyer 	fabs.x		%fp0			# clear result sign
   12009  1.1.6.2  bouyer 	fneg.x		%fp0			# set result sign
   12010  1.1.6.2  bouyer 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
   12011  1.1.6.2  bouyer 	rts
   12012  1.1.6.2  bouyer fmul_inf_dst_p:
   12013  1.1.6.2  bouyer 	fabs.x		%fp0			# clear result sign
   12014  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
   12015  1.1.6.2  bouyer 	rts
   12016  1.1.6.2  bouyer 
   12017  1.1.6.2  bouyer 	global		fmul_inf_src		# global for fsglmul
   12018  1.1.6.2  bouyer fmul_inf_src:
   12019  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return INF result in fp0
   12020  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   12021  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   12022  1.1.6.2  bouyer 	eor.b		%d0,%d1
   12023  1.1.6.2  bouyer 	bpl.b		fmul_inf_dst_p		# result INF is pos.
   12024  1.1.6.2  bouyer 	bra.b		fmul_inf_dst_n
   12025  1.1.6.2  bouyer 
   12026  1.1.6.2  bouyer #########################################################################
   12027  1.1.6.2  bouyer # XDEF ****************************************************************	#
   12028  1.1.6.2  bouyer #	fin(): emulates the fmove instruction				#
   12029  1.1.6.2  bouyer #	fsin(): emulates the fsmove instruction				#
   12030  1.1.6.2  bouyer #	fdin(): emulates the fdmove instruction				#
   12031  1.1.6.2  bouyer #									#
   12032  1.1.6.2  bouyer # XREF ****************************************************************	#
   12033  1.1.6.2  bouyer #	norm() - normalize mantissa for EXOP on denorm			#
   12034  1.1.6.2  bouyer #	scale_to_zero_src() - scale src exponent to zero		#
   12035  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   12036  1.1.6.2  bouyer # 	unf_res() - return default underflow result			#
   12037  1.1.6.2  bouyer #	res_qnan_1op() - return QNAN result				#
   12038  1.1.6.2  bouyer #	res_snan_1op() - return SNAN result				#
   12039  1.1.6.2  bouyer #									#
   12040  1.1.6.2  bouyer # INPUT ***************************************************************	#
   12041  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   12042  1.1.6.2  bouyer #	d0 = round prec/mode						#
   12043  1.1.6.2  bouyer # 									#
   12044  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   12045  1.1.6.2  bouyer #	fp0 = result							#
   12046  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   12047  1.1.6.2  bouyer #									#
   12048  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   12049  1.1.6.2  bouyer # 	Handle NANs, infinities, and zeroes as special cases. Divide	#
   12050  1.1.6.2  bouyer # norms into extended, single, and double precision.			#
   12051  1.1.6.2  bouyer # 	Norms can be emulated w/ a regular fmove instruction. For	#
   12052  1.1.6.2  bouyer # sgl/dbl, must scale exponent and perform an "fmove". Check to see	#
   12053  1.1.6.2  bouyer # if the result would have overflowed/underflowed. If so, use unf_res()	#
   12054  1.1.6.2  bouyer # or ovf_res() to return the default result. Also return EXOP if	#
   12055  1.1.6.2  bouyer # exception is enabled. If no exception, return the default result.	#
   12056  1.1.6.2  bouyer #	Unnorms don't pass through here.				#
   12057  1.1.6.2  bouyer #									#
   12058  1.1.6.2  bouyer #########################################################################
   12059  1.1.6.2  bouyer 
   12060  1.1.6.2  bouyer 	global		fsin
   12061  1.1.6.2  bouyer fsin:
   12062  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   12063  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   12064  1.1.6.2  bouyer 	bra.b		fin
   12065  1.1.6.2  bouyer 
   12066  1.1.6.2  bouyer 	global		fdin
   12067  1.1.6.2  bouyer fdin:
   12068  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   12069  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
   12070  1.1.6.2  bouyer 
   12071  1.1.6.2  bouyer 	global		fin
   12072  1.1.6.2  bouyer fin:
   12073  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   12074  1.1.6.2  bouyer 
   12075  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1		# fetch src optype tag
   12076  1.1.6.2  bouyer 	bne.w		fin_not_norm		# optimize on non-norm input
   12077  1.1.6.2  bouyer 
   12078  1.1.6.2  bouyer #
   12079  1.1.6.2  bouyer # FP MOVE IN: NORMs and DENORMs ONLY!
   12080  1.1.6.2  bouyer #
   12081  1.1.6.2  bouyer fin_norm:
   12082  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   12083  1.1.6.2  bouyer 	bne.w		fin_not_ext		# no, so go handle dbl or sgl
   12084  1.1.6.2  bouyer 
   12085  1.1.6.2  bouyer #
   12086  1.1.6.2  bouyer # precision selected is extended. so...we cannot get an underflow
   12087  1.1.6.2  bouyer # or overflow because of rounding to the correct precision. so...
   12088  1.1.6.2  bouyer # skip the scaling and unscaling...
   12089  1.1.6.2  bouyer #
   12090  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is the operand negative?
   12091  1.1.6.2  bouyer 	bpl.b		fin_norm_done		# no
   12092  1.1.6.2  bouyer 	bset		&neg_bit,FPSR_CC(%a6)	# yes, so set 'N' ccode bit
   12093  1.1.6.2  bouyer fin_norm_done:
   12094  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   12095  1.1.6.2  bouyer 	rts
   12096  1.1.6.2  bouyer 
   12097  1.1.6.2  bouyer #
   12098  1.1.6.2  bouyer # for an extended precision DENORM, the UNFL exception bit is set
   12099  1.1.6.2  bouyer # the accrued bit is NOT set in this instance(no inexactness!)
   12100  1.1.6.2  bouyer #
   12101  1.1.6.2  bouyer fin_denorm:
   12102  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   12103  1.1.6.2  bouyer 	bne.w		fin_not_ext		# no, so go handle dbl or sgl
   12104  1.1.6.2  bouyer 
   12105  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12106  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is the operand negative?
   12107  1.1.6.2  bouyer 	bpl.b		fin_denorm_done		# no
   12108  1.1.6.2  bouyer 	bset		&neg_bit,FPSR_CC(%a6)	# yes, so set 'N' ccode bit
   12109  1.1.6.2  bouyer fin_denorm_done:
   12110  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   12111  1.1.6.2  bouyer 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
   12112  1.1.6.2  bouyer 	bne.b		fin_denorm_unfl_ena	# yes
   12113  1.1.6.2  bouyer 	rts
   12114  1.1.6.2  bouyer 
   12115  1.1.6.2  bouyer #
   12116  1.1.6.2  bouyer # the input is an extended DENORM and underflow is enabled in the FPCR.
   12117  1.1.6.2  bouyer # normalize the mantissa and add the bias of 0x6000 to the resulting negative
   12118  1.1.6.2  bouyer # exponent and insert back into the operand.
   12119  1.1.6.2  bouyer #
   12120  1.1.6.2  bouyer fin_denorm_unfl_ena:
   12121  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12122  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12123  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12124  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   12125  1.1.6.2  bouyer 	bsr.l		norm			# normalize result
   12126  1.1.6.2  bouyer 	neg.w		%d0			# new exponent = -(shft val)
   12127  1.1.6.2  bouyer 	addi.w		&0x6000,%d0		# add new bias to exponent
   12128  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
   12129  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep old sign
   12130  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# clear sign position
   12131  1.1.6.2  bouyer 	or.w		%d1,%d0			# concat new exo,old sign
   12132  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   12133  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12134  1.1.6.2  bouyer 	rts
   12135  1.1.6.2  bouyer 
   12136  1.1.6.2  bouyer #
   12137  1.1.6.2  bouyer # operand is to be rounded to single or double precision
   12138  1.1.6.2  bouyer #
   12139  1.1.6.2  bouyer fin_not_ext:
   12140  1.1.6.2  bouyer 	cmpi.b		%d0,&s_mode*0x10 	# separate sgl/dbl prec
   12141  1.1.6.2  bouyer 	bne.b		fin_dbl
   12142  1.1.6.2  bouyer 
   12143  1.1.6.2  bouyer #
   12144  1.1.6.2  bouyer # operand is to be rounded to single precision
   12145  1.1.6.2  bouyer #
   12146  1.1.6.2  bouyer fin_sgl:
   12147  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12148  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12149  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12150  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# calculate scale factor
   12151  1.1.6.2  bouyer 
   12152  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
   12153  1.1.6.2  bouyer 	bge.w		fin_sd_unfl		# yes; go handle underflow
   12154  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
   12155  1.1.6.2  bouyer 	beq.w		fin_sd_may_ovfl		# maybe; go check
   12156  1.1.6.2  bouyer 	blt.w		fin_sd_ovfl		# yes; go handle overflow
   12157  1.1.6.2  bouyer 
   12158  1.1.6.2  bouyer #
   12159  1.1.6.2  bouyer # operand will NOT overflow or underflow when moved into the fp reg file
   12160  1.1.6.2  bouyer #
   12161  1.1.6.2  bouyer fin_sd_normal:
   12162  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12163  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12164  1.1.6.2  bouyer 
   12165  1.1.6.2  bouyer 	fmov.x		FP_SCR0(%a6),%fp0	# perform move
   12166  1.1.6.2  bouyer 
   12167  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   12168  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12169  1.1.6.2  bouyer 
   12170  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12171  1.1.6.2  bouyer 
   12172  1.1.6.2  bouyer fin_sd_normal_exit:
   12173  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   12174  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   12175  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   12176  1.1.6.2  bouyer 	mov.w		%d1,%d2			# make a copy
   12177  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   12178  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   12179  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   12180  1.1.6.2  bouyer 	or.w		%d1,%d2			# concat old sign,new exponent
   12181  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   12182  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   12183  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12184  1.1.6.2  bouyer 	rts
   12185  1.1.6.2  bouyer 
   12186  1.1.6.2  bouyer #
   12187  1.1.6.2  bouyer # operand is to be rounded to double precision
   12188  1.1.6.2  bouyer #
   12189  1.1.6.2  bouyer fin_dbl:
   12190  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12191  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12192  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12193  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# calculate scale factor
   12194  1.1.6.2  bouyer 
   12195  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
   12196  1.1.6.2  bouyer 	bge.w		fin_sd_unfl		# yes; go handle underflow
   12197  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
   12198  1.1.6.2  bouyer 	beq.w		fin_sd_may_ovfl		# maybe; go check
   12199  1.1.6.2  bouyer 	blt.w		fin_sd_ovfl		# yes; go handle overflow
   12200  1.1.6.2  bouyer 	bra.w		fin_sd_normal		# no; ho handle normalized op
   12201  1.1.6.2  bouyer 
   12202  1.1.6.2  bouyer #
   12203  1.1.6.2  bouyer # operand WILL underflow when moved in to the fp register file
   12204  1.1.6.2  bouyer #
   12205  1.1.6.2  bouyer fin_sd_unfl:
   12206  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12207  1.1.6.2  bouyer 
   12208  1.1.6.2  bouyer 	tst.b		FP_SCR0_EX(%a6)		# is operand negative?
   12209  1.1.6.2  bouyer 	bpl.b		fin_sd_unfl_tst
   12210  1.1.6.2  bouyer 	bset		&neg_bit,FPSR_CC(%a6)	# set 'N' ccode bit
   12211  1.1.6.2  bouyer 
   12212  1.1.6.2  bouyer # if underflow or inexact is enabled, then go calculate the EXOP first.
   12213  1.1.6.2  bouyer fin_sd_unfl_tst:
   12214  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   12215  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   12216  1.1.6.2  bouyer 	bne.b		fin_sd_unfl_ena		# yes
   12217  1.1.6.2  bouyer 
   12218  1.1.6.2  bouyer fin_sd_unfl_dis:
   12219  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   12220  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   12221  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   12222  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# unf_res may have set 'Z'
   12223  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   12224  1.1.6.2  bouyer 	rts
   12225  1.1.6.2  bouyer 
   12226  1.1.6.2  bouyer #
   12227  1.1.6.2  bouyer # operand will underflow AND underflow or inexact is enabled.
   12228  1.1.6.2  bouyer # therefore, we must return the result rounded to extended precision.
   12229  1.1.6.2  bouyer #
   12230  1.1.6.2  bouyer fin_sd_unfl_ena:
   12231  1.1.6.2  bouyer 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   12232  1.1.6.2  bouyer 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   12233  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   12234  1.1.6.2  bouyer 
   12235  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   12236  1.1.6.2  bouyer 	mov.w		%d1,%d2			# make a copy
   12237  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   12238  1.1.6.2  bouyer 	sub.l		%d0,%d1			# subtract scale factor
   12239  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# extract old sign
   12240  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add new bias
   12241  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   12242  1.1.6.2  bouyer 	or.w		%d1,%d2			# concat old sign,new exp
   12243  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR1_EX(%a6)	# insert new exponent
   12244  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   12245  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   12246  1.1.6.2  bouyer 	bra.b		fin_sd_unfl_dis
   12247  1.1.6.2  bouyer 
   12248  1.1.6.2  bouyer #
   12249  1.1.6.2  bouyer # operand WILL overflow.
   12250  1.1.6.2  bouyer #
   12251  1.1.6.2  bouyer fin_sd_ovfl:
   12252  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12253  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12254  1.1.6.2  bouyer 
   12255  1.1.6.2  bouyer 	fmov.x		FP_SCR0(%a6),%fp0	# perform move
   12256  1.1.6.2  bouyer 
   12257  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12258  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   12259  1.1.6.2  bouyer 
   12260  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12261  1.1.6.2  bouyer 
   12262  1.1.6.2  bouyer fin_sd_ovfl_tst:
   12263  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   12264  1.1.6.2  bouyer 
   12265  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   12266  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   12267  1.1.6.2  bouyer 	bne.b		fin_sd_ovfl_ena		# yes
   12268  1.1.6.2  bouyer 
   12269  1.1.6.2  bouyer #
   12270  1.1.6.2  bouyer # OVFL is not enabled; therefore, we must create the default result by
   12271  1.1.6.2  bouyer # calling ovf_res().
   12272  1.1.6.2  bouyer #
   12273  1.1.6.2  bouyer fin_sd_ovfl_dis:
   12274  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   12275  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   12276  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   12277  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   12278  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   12279  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   12280  1.1.6.2  bouyer 	rts
   12281  1.1.6.2  bouyer 
   12282  1.1.6.2  bouyer #
   12283  1.1.6.2  bouyer # OVFL is enabled.
   12284  1.1.6.2  bouyer # the INEX2 bit has already been updated by the round to the correct precision.
   12285  1.1.6.2  bouyer # now, round to extended(and don't alter the FPSR).
   12286  1.1.6.2  bouyer #
   12287  1.1.6.2  bouyer fin_sd_ovfl_ena:
   12288  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   12289  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   12290  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   12291  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   12292  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   12293  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   12294  1.1.6.2  bouyer 	sub.l		&0x6000,%d1		# subtract bias
   12295  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   12296  1.1.6.2  bouyer 	or.w		%d2,%d1
   12297  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   12298  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   12299  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12300  1.1.6.2  bouyer 	bra.b		fin_sd_ovfl_dis
   12301  1.1.6.2  bouyer 
   12302  1.1.6.2  bouyer #
   12303  1.1.6.2  bouyer # the move in MAY overflow. so...
   12304  1.1.6.2  bouyer #
   12305  1.1.6.2  bouyer fin_sd_may_ovfl:
   12306  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12307  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12308  1.1.6.2  bouyer 
   12309  1.1.6.2  bouyer 	fmov.x		FP_SCR0(%a6),%fp0	# perform the move
   12310  1.1.6.2  bouyer 
   12311  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   12312  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12313  1.1.6.2  bouyer 
   12314  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12315  1.1.6.2  bouyer 
   12316  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   12317  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   12318  1.1.6.2  bouyer 	fbge.w		fin_sd_ovfl_tst		# yes; overflow has occurred
   12319  1.1.6.2  bouyer 
   12320  1.1.6.2  bouyer # no, it didn't overflow; we have correct result
   12321  1.1.6.2  bouyer 	bra.w		fin_sd_normal_exit
   12322  1.1.6.2  bouyer 
   12323  1.1.6.2  bouyer ##########################################################################
   12324  1.1.6.2  bouyer 
   12325  1.1.6.2  bouyer #
   12326  1.1.6.2  bouyer # operand is not a NORM: check its optype and branch accordingly
   12327  1.1.6.2  bouyer #
   12328  1.1.6.2  bouyer fin_not_norm:
   12329  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM		# weed out DENORM
   12330  1.1.6.2  bouyer 	beq.w		fin_denorm
   12331  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN		# weed out SNANs
   12332  1.1.6.2  bouyer 	beq.l		res_snan_1op
   12333  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN		# weed out QNANs
   12334  1.1.6.2  bouyer 	beq.l		res_qnan_1op
   12335  1.1.6.2  bouyer 
   12336  1.1.6.2  bouyer #
   12337  1.1.6.2  bouyer # do the fmove in; at this point, only possible ops are ZERO and INF.
   12338  1.1.6.2  bouyer # use fmov to determine ccodes.
   12339  1.1.6.2  bouyer # prec:mode should be zero at this point but it won't affect answer anyways.
   12340  1.1.6.2  bouyer #
   12341  1.1.6.2  bouyer 	fmov.x		SRC(%a0),%fp0		# do fmove in
   12342  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# no exceptions possible
   12343  1.1.6.2  bouyer 	rol.l		&0x8,%d0		# put ccodes in lo byte
   12344  1.1.6.2  bouyer 	mov.b		%d0,FPSR_CC(%a6)	# insert correct ccodes
   12345  1.1.6.2  bouyer 	rts
   12346  1.1.6.2  bouyer 
   12347  1.1.6.2  bouyer #########################################################################
   12348  1.1.6.2  bouyer # XDEF ****************************************************************	#
   12349  1.1.6.2  bouyer # 	fdiv(): emulates the fdiv instruction				#
   12350  1.1.6.2  bouyer #	fsdiv(): emulates the fsdiv instruction				#
   12351  1.1.6.2  bouyer #	fddiv(): emulates the fddiv instruction				#
   12352  1.1.6.2  bouyer #									#
   12353  1.1.6.2  bouyer # XREF ****************************************************************	#
   12354  1.1.6.2  bouyer #	scale_to_zero_src() - scale src exponent to zero		#
   12355  1.1.6.2  bouyer #	scale_to_zero_dst() - scale dst exponent to zero		#
   12356  1.1.6.2  bouyer #	unf_res() - return default underflow result			#
   12357  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   12358  1.1.6.2  bouyer # 	res_qnan() - return QNAN result					#
   12359  1.1.6.2  bouyer # 	res_snan() - return SNAN result					#
   12360  1.1.6.2  bouyer #									#
   12361  1.1.6.2  bouyer # INPUT ***************************************************************	#
   12362  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   12363  1.1.6.2  bouyer #	a1 = pointer to extended precision destination operand		#
   12364  1.1.6.2  bouyer #	d0  rnd prec,mode						#
   12365  1.1.6.2  bouyer #									#
   12366  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   12367  1.1.6.2  bouyer #	fp0 = result							#
   12368  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   12369  1.1.6.2  bouyer #									#
   12370  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   12371  1.1.6.2  bouyer #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   12372  1.1.6.2  bouyer # norms/denorms into ext/sgl/dbl precision.				#
   12373  1.1.6.2  bouyer #	For norms/denorms, scale the exponents such that a divide	#
   12374  1.1.6.2  bouyer # instruction won't cause an exception. Use the regular fdiv to		#
   12375  1.1.6.2  bouyer # compute a result. Check if the regular operands would have taken	#
   12376  1.1.6.2  bouyer # an exception. If so, return the default overflow/underflow result	#
   12377  1.1.6.2  bouyer # and return the EXOP if exceptions are enabled. Else, scale the 	#
   12378  1.1.6.2  bouyer # result operand to the proper exponent.				#
   12379  1.1.6.2  bouyer #									#
   12380  1.1.6.2  bouyer #########################################################################
   12381  1.1.6.2  bouyer 
   12382  1.1.6.2  bouyer 	align		0x10
   12383  1.1.6.2  bouyer tbl_fdiv_unfl:
   12384  1.1.6.2  bouyer 	long		0x3fff - 0x0000		# ext_unfl
   12385  1.1.6.2  bouyer 	long		0x3fff - 0x3f81		# sgl_unfl
   12386  1.1.6.2  bouyer 	long		0x3fff - 0x3c01		# dbl_unfl
   12387  1.1.6.2  bouyer 
   12388  1.1.6.2  bouyer tbl_fdiv_ovfl:
   12389  1.1.6.2  bouyer 	long		0x3fff - 0x7ffe		# ext overflow exponent
   12390  1.1.6.2  bouyer 	long		0x3fff - 0x407e		# sgl overflow exponent
   12391  1.1.6.2  bouyer 	long		0x3fff - 0x43fe		# dbl overflow exponent
   12392  1.1.6.2  bouyer 
   12393  1.1.6.2  bouyer 	global		fsdiv
   12394  1.1.6.2  bouyer fsdiv:
   12395  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   12396  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   12397  1.1.6.2  bouyer 	bra.b		fdiv
   12398  1.1.6.2  bouyer 
   12399  1.1.6.2  bouyer 	global		fddiv
   12400  1.1.6.2  bouyer fddiv:
   12401  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   12402  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   12403  1.1.6.2  bouyer 
   12404  1.1.6.2  bouyer 	global		fdiv
   12405  1.1.6.2  bouyer fdiv:
   12406  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   12407  1.1.6.2  bouyer 
   12408  1.1.6.2  bouyer 	clr.w		%d1
   12409  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   12410  1.1.6.2  bouyer 	lsl.b		&0x3,%d1
   12411  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1		# combine src tags
   12412  1.1.6.2  bouyer 
   12413  1.1.6.2  bouyer 	bne.w		fdiv_not_norm		# optimize on non-norm input
   12414  1.1.6.2  bouyer 
   12415  1.1.6.2  bouyer #
   12416  1.1.6.2  bouyer # DIVIDE: NORMs and DENORMs ONLY!
   12417  1.1.6.2  bouyer #
   12418  1.1.6.2  bouyer fdiv_norm:
   12419  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   12420  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   12421  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   12422  1.1.6.2  bouyer 
   12423  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12424  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12425  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12426  1.1.6.2  bouyer 
   12427  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# scale src exponent
   12428  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save scale factor 1
   12429  1.1.6.2  bouyer 
   12430  1.1.6.2  bouyer 	bsr.l		scale_to_zero_dst	# scale dst exponent
   12431  1.1.6.2  bouyer 
   12432  1.1.6.2  bouyer 	neg.l		(%sp)			# SCALE FACTOR = scale1 - scale2
   12433  1.1.6.2  bouyer 	add.l		%d0,(%sp)
   12434  1.1.6.2  bouyer 
   12435  1.1.6.2  bouyer 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision
   12436  1.1.6.2  bouyer 	lsr.b		&0x6,%d1		# shift to lo bits
   12437  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# load S.F.
   12438  1.1.6.2  bouyer 	cmp.l		%d0,(tbl_fdiv_ovfl.b,%pc,%d1.w*4) # will result overflow?
   12439  1.1.6.2  bouyer 	ble.w		fdiv_may_ovfl		# result will overflow
   12440  1.1.6.2  bouyer 
   12441  1.1.6.2  bouyer 	cmp.l		%d0,(tbl_fdiv_unfl.w,%pc,%d1.w*4) # will result underflow?
   12442  1.1.6.2  bouyer 	beq.w		fdiv_may_unfl		# maybe
   12443  1.1.6.2  bouyer 	bgt.w		fdiv_unfl		# yes; go handle underflow
   12444  1.1.6.2  bouyer 
   12445  1.1.6.2  bouyer fdiv_normal:
   12446  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12447  1.1.6.2  bouyer 
   12448  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# save FPCR
   12449  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12450  1.1.6.2  bouyer 
   12451  1.1.6.2  bouyer 	fdiv.x		FP_SCR0(%a6),%fp0	# perform divide
   12452  1.1.6.2  bouyer 
   12453  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   12454  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12455  1.1.6.2  bouyer 
   12456  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12457  1.1.6.2  bouyer 
   12458  1.1.6.2  bouyer fdiv_normal_exit:
   12459  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store result on stack
   12460  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# store d2
   12461  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   12462  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   12463  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   12464  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   12465  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   12466  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   12467  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   12468  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   12469  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12470  1.1.6.2  bouyer 	rts
   12471  1.1.6.2  bouyer 
   12472  1.1.6.2  bouyer tbl_fdiv_ovfl2:
   12473  1.1.6.2  bouyer 	long		0x7fff
   12474  1.1.6.2  bouyer 	long		0x407f
   12475  1.1.6.2  bouyer 	long		0x43ff
   12476  1.1.6.2  bouyer 
   12477  1.1.6.2  bouyer fdiv_no_ovfl:
   12478  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore scale factor
   12479  1.1.6.2  bouyer 	bra.b		fdiv_normal_exit
   12480  1.1.6.2  bouyer 
   12481  1.1.6.2  bouyer fdiv_may_ovfl:
   12482  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save scale factor
   12483  1.1.6.2  bouyer 
   12484  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12485  1.1.6.2  bouyer 
   12486  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12487  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# set FPSR
   12488  1.1.6.2  bouyer 
   12489  1.1.6.2  bouyer 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12490  1.1.6.2  bouyer 
   12491  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0
   12492  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr
   12493  1.1.6.2  bouyer 
   12494  1.1.6.2  bouyer 	or.l		%d0,USER_FPSR(%a6)	# save INEX,N
   12495  1.1.6.2  bouyer 
   12496  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save result to stack
   12497  1.1.6.2  bouyer 	mov.w		(%sp),%d0		# fetch new exponent
   12498  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear result from stack
   12499  1.1.6.2  bouyer 	andi.l		&0x7fff,%d0		# strip sign
   12500  1.1.6.2  bouyer 	sub.l		(%sp),%d0		# add scale factor
   12501  1.1.6.2  bouyer 	cmp.l		%d0,(tbl_fdiv_ovfl2.b,%pc,%d1.w*4)
   12502  1.1.6.2  bouyer 	blt.b		fdiv_no_ovfl
   12503  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   12504  1.1.6.2  bouyer 
   12505  1.1.6.2  bouyer fdiv_ovfl_tst:
   12506  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   12507  1.1.6.2  bouyer 
   12508  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   12509  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   12510  1.1.6.2  bouyer 	bne.b		fdiv_ovfl_ena		# yes
   12511  1.1.6.2  bouyer 
   12512  1.1.6.2  bouyer fdiv_ovfl_dis:
   12513  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6) 	# is result negative?
   12514  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   12515  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   12516  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   12517  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF if applicable
   12518  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   12519  1.1.6.2  bouyer 	rts
   12520  1.1.6.2  bouyer 
   12521  1.1.6.2  bouyer fdiv_ovfl_ena:
   12522  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   12523  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# is precision extended?
   12524  1.1.6.2  bouyer 	bne.b		fdiv_ovfl_ena_sd	# no, do sgl or dbl
   12525  1.1.6.2  bouyer 
   12526  1.1.6.2  bouyer fdiv_ovfl_ena_cont:
   12527  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   12528  1.1.6.2  bouyer 
   12529  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   12530  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   12531  1.1.6.2  bouyer 	mov.w		%d1,%d2			# make a copy
   12532  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   12533  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   12534  1.1.6.2  bouyer 	subi.l		&0x6000,%d1		# subtract bias
   12535  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1		# clear sign bit
   12536  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   12537  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   12538  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   12539  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   12540  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12541  1.1.6.2  bouyer 	bra.b		fdiv_ovfl_dis
   12542  1.1.6.2  bouyer 
   12543  1.1.6.2  bouyer fdiv_ovfl_ena_sd:
   12544  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
   12545  1.1.6.2  bouyer 
   12546  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   12547  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# keep rnd mode
   12548  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   12549  1.1.6.2  bouyer 
   12550  1.1.6.2  bouyer 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12551  1.1.6.2  bouyer 
   12552  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12553  1.1.6.2  bouyer 	bra.b		fdiv_ovfl_ena_cont
   12554  1.1.6.2  bouyer 
   12555  1.1.6.2  bouyer fdiv_unfl:
   12556  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12557  1.1.6.2  bouyer 
   12558  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12559  1.1.6.2  bouyer 
   12560  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   12561  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12562  1.1.6.2  bouyer 
   12563  1.1.6.2  bouyer 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12564  1.1.6.2  bouyer 
   12565  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   12566  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12567  1.1.6.2  bouyer 
   12568  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12569  1.1.6.2  bouyer 
   12570  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   12571  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   12572  1.1.6.2  bouyer 	bne.b		fdiv_unfl_ena		# yes
   12573  1.1.6.2  bouyer 
   12574  1.1.6.2  bouyer fdiv_unfl_dis:
   12575  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   12576  1.1.6.2  bouyer 
   12577  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   12578  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   12579  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   12580  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# 'Z' may have been set
   12581  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   12582  1.1.6.2  bouyer 	rts
   12583  1.1.6.2  bouyer 
   12584  1.1.6.2  bouyer #
   12585  1.1.6.2  bouyer # UNFL is enabled.
   12586  1.1.6.2  bouyer #
   12587  1.1.6.2  bouyer fdiv_unfl_ena:
   12588  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   12589  1.1.6.2  bouyer 
   12590  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   12591  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# is precision extended?
   12592  1.1.6.2  bouyer 	bne.b		fdiv_unfl_ena_sd	# no, sgl or dbl
   12593  1.1.6.2  bouyer 
   12594  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12595  1.1.6.2  bouyer 
   12596  1.1.6.2  bouyer fdiv_unfl_ena_cont:
   12597  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12598  1.1.6.2  bouyer 
   12599  1.1.6.2  bouyer 	fdiv.x		FP_SCR0(%a6),%fp1	# execute divide
   12600  1.1.6.2  bouyer 
   12601  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12602  1.1.6.2  bouyer 
   12603  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   12604  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   12605  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   12606  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   12607  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   12608  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   12609  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factoer
   12610  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add bias
   12611  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   12612  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   12613  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exp
   12614  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   12615  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12616  1.1.6.2  bouyer 	bra.w		fdiv_unfl_dis
   12617  1.1.6.2  bouyer 
   12618  1.1.6.2  bouyer fdiv_unfl_ena_sd:
   12619  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   12620  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# use only rnd mode
   12621  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   12622  1.1.6.2  bouyer 
   12623  1.1.6.2  bouyer 	bra.b		fdiv_unfl_ena_cont
   12624  1.1.6.2  bouyer 
   12625  1.1.6.2  bouyer #
   12626  1.1.6.2  bouyer # the divide operation MAY underflow:
   12627  1.1.6.2  bouyer #
   12628  1.1.6.2  bouyer fdiv_may_unfl:
   12629  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   12630  1.1.6.2  bouyer 
   12631  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12632  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12633  1.1.6.2  bouyer 
   12634  1.1.6.2  bouyer 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
   12635  1.1.6.2  bouyer 
   12636  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   12637  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12638  1.1.6.2  bouyer 
   12639  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12640  1.1.6.2  bouyer 
   12641  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   12642  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x1		# is |result| > 1.b?
   12643  1.1.6.2  bouyer 	fbgt.w		fdiv_normal_exit	# no; no underflow occurred
   12644  1.1.6.2  bouyer 	fblt.w		fdiv_unfl		# yes; underflow occurred
   12645  1.1.6.2  bouyer 
   12646  1.1.6.2  bouyer #
   12647  1.1.6.2  bouyer # we still don't know if underflow occurred. result is ~ equal to 1. but,
   12648  1.1.6.2  bouyer # we don't know if the result was an underflow that rounded up to a 1
   12649  1.1.6.2  bouyer # or a normalized number that rounded down to a 1. so, redo the entire
   12650  1.1.6.2  bouyer # operation using RZ as the rounding mode to see what the pre-rounded
   12651  1.1.6.2  bouyer # result is. this case should be relatively rare.
   12652  1.1.6.2  bouyer #
   12653  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   12654  1.1.6.2  bouyer 
   12655  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   12656  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# keep rnd prec
   12657  1.1.6.2  bouyer 	ori.b		&rz_mode*0x10,%d1	# insert RZ
   12658  1.1.6.2  bouyer 
   12659  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   12660  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12661  1.1.6.2  bouyer 
   12662  1.1.6.2  bouyer 	fdiv.x		FP_SCR0(%a6),%fp1	# execute divide
   12663  1.1.6.2  bouyer 
   12664  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12665  1.1.6.2  bouyer 	fabs.x		%fp1			# make absolute value
   12666  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x1		# is |result| < 1.b?
   12667  1.1.6.2  bouyer 	fbge.w		fdiv_normal_exit	# no; no underflow occurred
   12668  1.1.6.2  bouyer 	bra.w		fdiv_unfl		# yes; underflow occurred
   12669  1.1.6.2  bouyer 
   12670  1.1.6.2  bouyer ############################################################################
   12671  1.1.6.2  bouyer 
   12672  1.1.6.2  bouyer #
   12673  1.1.6.2  bouyer # Divide: inputs are not both normalized; what are they?
   12674  1.1.6.2  bouyer #
   12675  1.1.6.2  bouyer fdiv_not_norm:
   12676  1.1.6.2  bouyer 	mov.w		(tbl_fdiv_op.b,%pc,%d1.w*2),%d1
   12677  1.1.6.2  bouyer 	jmp		(tbl_fdiv_op.b,%pc,%d1.w*1)
   12678  1.1.6.2  bouyer 
   12679  1.1.6.2  bouyer 	swbeg		&48
   12680  1.1.6.2  bouyer tbl_fdiv_op:
   12681  1.1.6.2  bouyer 	short		fdiv_norm	- tbl_fdiv_op # NORM / NORM
   12682  1.1.6.2  bouyer 	short		fdiv_inf_load	- tbl_fdiv_op # NORM / ZERO
   12683  1.1.6.2  bouyer 	short		fdiv_zero_load	- tbl_fdiv_op # NORM / INF
   12684  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # NORM / QNAN
   12685  1.1.6.2  bouyer 	short		fdiv_norm	- tbl_fdiv_op # NORM / DENORM
   12686  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # NORM / SNAN
   12687  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12688  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12689  1.1.6.2  bouyer 
   12690  1.1.6.2  bouyer 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / NORM
   12691  1.1.6.2  bouyer 	short		fdiv_res_operr	- tbl_fdiv_op # ZERO / ZERO
   12692  1.1.6.2  bouyer 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / INF
   12693  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # ZERO / QNAN
   12694  1.1.6.2  bouyer 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / DENORM
   12695  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # ZERO / SNAN
   12696  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12697  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12698  1.1.6.2  bouyer 
   12699  1.1.6.2  bouyer 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / NORM
   12700  1.1.6.2  bouyer 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / ZERO
   12701  1.1.6.2  bouyer 	short		fdiv_res_operr	- tbl_fdiv_op # INF / INF
   12702  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # INF / QNAN
   12703  1.1.6.2  bouyer 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / DENORM
   12704  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # INF / SNAN
   12705  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12706  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12707  1.1.6.2  bouyer 
   12708  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / NORM
   12709  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / ZERO
   12710  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / INF
   12711  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / QNAN
   12712  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / DENORM
   12713  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # QNAN / SNAN
   12714  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12715  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12716  1.1.6.2  bouyer 
   12717  1.1.6.2  bouyer 	short		fdiv_norm	- tbl_fdiv_op # DENORM / NORM
   12718  1.1.6.2  bouyer 	short		fdiv_inf_load	- tbl_fdiv_op # DENORM / ZERO
   12719  1.1.6.2  bouyer 	short		fdiv_zero_load	- tbl_fdiv_op # DENORM / INF
   12720  1.1.6.2  bouyer 	short		fdiv_res_qnan	- tbl_fdiv_op # DENORM / QNAN
   12721  1.1.6.2  bouyer 	short		fdiv_norm	- tbl_fdiv_op # DENORM / DENORM
   12722  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # DENORM / SNAN
   12723  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12724  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12725  1.1.6.2  bouyer 
   12726  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / NORM
   12727  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / ZERO
   12728  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / INF
   12729  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / QNAN
   12730  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / DENORM
   12731  1.1.6.2  bouyer 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / SNAN
   12732  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12733  1.1.6.2  bouyer 	short		tbl_fdiv_op	- tbl_fdiv_op #
   12734  1.1.6.2  bouyer 
   12735  1.1.6.2  bouyer fdiv_res_qnan:
   12736  1.1.6.2  bouyer 	bra.l		res_qnan
   12737  1.1.6.2  bouyer fdiv_res_snan:
   12738  1.1.6.2  bouyer 	bra.l		res_snan
   12739  1.1.6.2  bouyer fdiv_res_operr:
   12740  1.1.6.2  bouyer 	bra.l		res_operr
   12741  1.1.6.2  bouyer 
   12742  1.1.6.2  bouyer 	global		fdiv_zero_load		# global for fsgldiv
   12743  1.1.6.2  bouyer fdiv_zero_load:
   12744  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# result sign is exclusive
   12745  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1		# or of input signs.
   12746  1.1.6.2  bouyer 	eor.b		%d0,%d1
   12747  1.1.6.2  bouyer 	bpl.b		fdiv_zero_load_p	# result is positive
   12748  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# load a -ZERO
   12749  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set Z/N
   12750  1.1.6.2  bouyer 	rts
   12751  1.1.6.2  bouyer fdiv_zero_load_p:
   12752  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# load a +ZERO
   12753  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   12754  1.1.6.2  bouyer 	rts
   12755  1.1.6.2  bouyer 
   12756  1.1.6.2  bouyer #
   12757  1.1.6.2  bouyer # The destination was In Range and the source was a ZERO. The result,
   12758  1.1.6.2  bouyer # therefore, is an INF w/ the proper sign.
   12759  1.1.6.2  bouyer # So, determine the sign and return a new INF (w/ the j-bit cleared).
   12760  1.1.6.2  bouyer #
   12761  1.1.6.2  bouyer 	global		fdiv_inf_load		# global for fsgldiv
   12762  1.1.6.2  bouyer fdiv_inf_load:
   12763  1.1.6.2  bouyer 	ori.w		&dz_mask+adz_mask,2+USER_FPSR(%a6) # no; set DZ/ADZ
   12764  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# load both signs
   12765  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   12766  1.1.6.2  bouyer 	eor.b		%d0,%d1
   12767  1.1.6.2  bouyer 	bpl.b		fdiv_inf_load_p		# result is positive
   12768  1.1.6.2  bouyer 	fmov.s		&0xff800000,%fp0	# make result -INF
   12769  1.1.6.2  bouyer 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
   12770  1.1.6.2  bouyer 	rts
   12771  1.1.6.2  bouyer fdiv_inf_load_p:
   12772  1.1.6.2  bouyer 	fmov.s		&0x7f800000,%fp0	# make result +INF
   12773  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
   12774  1.1.6.2  bouyer 	rts
   12775  1.1.6.2  bouyer 
   12776  1.1.6.2  bouyer #
   12777  1.1.6.2  bouyer # The destination was an INF w/ an In Range or ZERO source, the result is
   12778  1.1.6.2  bouyer # an INF w/ the proper sign.
   12779  1.1.6.2  bouyer # The 68881/882 returns the destination INF w/ the new sign(if the j-bit of the
   12780  1.1.6.2  bouyer # dst INF is set, then then j-bit of the result INF is also set).
   12781  1.1.6.2  bouyer #
   12782  1.1.6.2  bouyer 	global		fdiv_inf_dst		# global for fsgldiv
   12783  1.1.6.2  bouyer fdiv_inf_dst:
   12784  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d0		# load both signs
   12785  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d1
   12786  1.1.6.2  bouyer 	eor.b		%d0,%d1
   12787  1.1.6.2  bouyer 	bpl.b		fdiv_inf_dst_p		# result is positive
   12788  1.1.6.2  bouyer 
   12789  1.1.6.2  bouyer 	fmovm.x		DST(%a1),&0x80		# return result in fp0
   12790  1.1.6.2  bouyer 	fabs.x		%fp0			# clear sign bit
   12791  1.1.6.2  bouyer 	fneg.x		%fp0			# set sign bit
   12792  1.1.6.2  bouyer 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/NEG
   12793  1.1.6.2  bouyer 	rts
   12794  1.1.6.2  bouyer 
   12795  1.1.6.2  bouyer fdiv_inf_dst_p:
   12796  1.1.6.2  bouyer 	fmovm.x		DST(%a1),&0x80		# return result in fp0
   12797  1.1.6.2  bouyer 	fabs.x		%fp0			# return positive INF
   12798  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6) # set INF
   12799  1.1.6.2  bouyer 	rts
   12800  1.1.6.2  bouyer 
   12801  1.1.6.2  bouyer #########################################################################
   12802  1.1.6.2  bouyer # XDEF ****************************************************************	#
   12803  1.1.6.2  bouyer #	fneg(): emulates the fneg instruction				#
   12804  1.1.6.2  bouyer #	fsneg(): emulates the fsneg instruction				#
   12805  1.1.6.2  bouyer #	fdneg(): emulates the fdneg instruction				#
   12806  1.1.6.2  bouyer #									#
   12807  1.1.6.2  bouyer # XREF ****************************************************************	#
   12808  1.1.6.2  bouyer # 	norm() - normalize a denorm to provide EXOP			#
   12809  1.1.6.2  bouyer #	scale_to_zero_src() - scale sgl/dbl source exponent		#
   12810  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   12811  1.1.6.2  bouyer #	unf_res() - return default underflow result			#
   12812  1.1.6.2  bouyer # 	res_qnan_1op() - return QNAN result				#
   12813  1.1.6.2  bouyer #	res_snan_1op() - return SNAN result				#
   12814  1.1.6.2  bouyer #									#
   12815  1.1.6.2  bouyer # INPUT ***************************************************************	#
   12816  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   12817  1.1.6.2  bouyer #	d0 = rnd prec,mode						#
   12818  1.1.6.2  bouyer #									#
   12819  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   12820  1.1.6.2  bouyer #	fp0 = result							#
   12821  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   12822  1.1.6.2  bouyer #									#
   12823  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   12824  1.1.6.2  bouyer #	Handle NANs, zeroes, and infinities as special cases. Separate	#
   12825  1.1.6.2  bouyer # norms/denorms into ext/sgl/dbl precisions. Extended precision can be	#
   12826  1.1.6.2  bouyer # emulated by simply setting sign bit. Sgl/dbl operands must be scaled	#
   12827  1.1.6.2  bouyer # and an actual fneg performed to see if overflow/underflow would have	#
   12828  1.1.6.2  bouyer # occurred. If so, return default underflow/overflow result. Else,	#
   12829  1.1.6.2  bouyer # scale the result exponent and return result. FPSR gets set based on	#
   12830  1.1.6.2  bouyer # the result value.							#
   12831  1.1.6.2  bouyer #									#
   12832  1.1.6.2  bouyer #########################################################################
   12833  1.1.6.2  bouyer 
   12834  1.1.6.2  bouyer 	global		fsneg
   12835  1.1.6.2  bouyer fsneg:
   12836  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   12837  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   12838  1.1.6.2  bouyer 	bra.b		fneg
   12839  1.1.6.2  bouyer 
   12840  1.1.6.2  bouyer 	global		fdneg
   12841  1.1.6.2  bouyer fdneg:
   12842  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   12843  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   12844  1.1.6.2  bouyer 
   12845  1.1.6.2  bouyer 	global		fneg
   12846  1.1.6.2  bouyer fneg:
   12847  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   12848  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   12849  1.1.6.2  bouyer 	bne.w		fneg_not_norm		# optimize on non-norm input
   12850  1.1.6.2  bouyer 
   12851  1.1.6.2  bouyer #
   12852  1.1.6.2  bouyer # NEGATE SIGN : norms and denorms ONLY!
   12853  1.1.6.2  bouyer #
   12854  1.1.6.2  bouyer fneg_norm:
   12855  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   12856  1.1.6.2  bouyer 	bne.w		fneg_not_ext		# no; go handle sgl or dbl
   12857  1.1.6.2  bouyer 
   12858  1.1.6.2  bouyer #
   12859  1.1.6.2  bouyer # precision selected is extended. so...we can not get an underflow
   12860  1.1.6.2  bouyer # or overflow because of rounding to the correct precision. so...
   12861  1.1.6.2  bouyer # skip the scaling and unscaling...
   12862  1.1.6.2  bouyer #
   12863  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12864  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12865  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0
   12866  1.1.6.2  bouyer 	eori.w		&0x8000,%d0		# negate sign
   12867  1.1.6.2  bouyer 	bpl.b		fneg_norm_load		# sign is positive
   12868  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   12869  1.1.6.2  bouyer fneg_norm_load:
   12870  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)
   12871  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12872  1.1.6.2  bouyer 	rts
   12873  1.1.6.2  bouyer 
   12874  1.1.6.2  bouyer #
   12875  1.1.6.2  bouyer # for an extended precision DENORM, the UNFL exception bit is set
   12876  1.1.6.2  bouyer # the accrued bit is NOT set in this instance(no inexactness!)
   12877  1.1.6.2  bouyer #
   12878  1.1.6.2  bouyer fneg_denorm:
   12879  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   12880  1.1.6.2  bouyer 	bne.b		fneg_not_ext		# no; go handle sgl or dbl
   12881  1.1.6.2  bouyer 
   12882  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12883  1.1.6.2  bouyer 
   12884  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12885  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12886  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0
   12887  1.1.6.2  bouyer 	eori.w		&0x8000,%d0		# negate sign
   12888  1.1.6.2  bouyer 	bpl.b		fneg_denorm_done	# no
   12889  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# yes, set 'N' ccode bit
   12890  1.1.6.2  bouyer fneg_denorm_done:
   12891  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)
   12892  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   12893  1.1.6.2  bouyer 
   12894  1.1.6.2  bouyer 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
   12895  1.1.6.2  bouyer 	bne.b		fneg_ext_unfl_ena	# yes
   12896  1.1.6.2  bouyer 	rts
   12897  1.1.6.2  bouyer 
   12898  1.1.6.2  bouyer #
   12899  1.1.6.2  bouyer # the input is an extended DENORM and underflow is enabled in the FPCR.
   12900  1.1.6.2  bouyer # normalize the mantissa and add the bias of 0x6000 to the resulting negative
   12901  1.1.6.2  bouyer # exponent and insert back into the operand.
   12902  1.1.6.2  bouyer #
   12903  1.1.6.2  bouyer fneg_ext_unfl_ena:
   12904  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   12905  1.1.6.2  bouyer 	bsr.l		norm			# normalize result
   12906  1.1.6.2  bouyer 	neg.w		%d0			# new exponent = -(shft val)
   12907  1.1.6.2  bouyer 	addi.w		&0x6000,%d0		# add new bias to exponent
   12908  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
   12909  1.1.6.2  bouyer 	andi.w		&0x8000,%d1	 	# keep old sign
   12910  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# clear sign position
   12911  1.1.6.2  bouyer 	or.w		%d1,%d0			# concat old sign, new exponent
   12912  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   12913  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   12914  1.1.6.2  bouyer 	rts
   12915  1.1.6.2  bouyer 
   12916  1.1.6.2  bouyer #
   12917  1.1.6.2  bouyer # operand is either single or double
   12918  1.1.6.2  bouyer #
   12919  1.1.6.2  bouyer fneg_not_ext:
   12920  1.1.6.2  bouyer 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
   12921  1.1.6.2  bouyer 	bne.b		fneg_dbl
   12922  1.1.6.2  bouyer 
   12923  1.1.6.2  bouyer #
   12924  1.1.6.2  bouyer # operand is to be rounded to single precision
   12925  1.1.6.2  bouyer #
   12926  1.1.6.2  bouyer fneg_sgl:
   12927  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12928  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12929  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12930  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# calculate scale factor
   12931  1.1.6.2  bouyer 
   12932  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
   12933  1.1.6.2  bouyer 	bge.w		fneg_sd_unfl		# yes; go handle underflow
   12934  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
   12935  1.1.6.2  bouyer 	beq.w		fneg_sd_may_ovfl	# maybe; go check
   12936  1.1.6.2  bouyer 	blt.w		fneg_sd_ovfl		# yes; go handle overflow
   12937  1.1.6.2  bouyer 
   12938  1.1.6.2  bouyer #
   12939  1.1.6.2  bouyer # operand will NOT overflow or underflow when moved in to the fp reg file
   12940  1.1.6.2  bouyer #
   12941  1.1.6.2  bouyer fneg_sd_normal:
   12942  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   12943  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   12944  1.1.6.2  bouyer 
   12945  1.1.6.2  bouyer 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
   12946  1.1.6.2  bouyer 
   12947  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   12948  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   12949  1.1.6.2  bouyer 
   12950  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   12951  1.1.6.2  bouyer 
   12952  1.1.6.2  bouyer fneg_sd_normal_exit:
   12953  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   12954  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   12955  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
   12956  1.1.6.2  bouyer 	mov.w		%d1,%d2			# make a copy
   12957  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   12958  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   12959  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   12960  1.1.6.2  bouyer 	or.w		%d1,%d2			# concat old sign,new exp
   12961  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   12962  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   12963  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   12964  1.1.6.2  bouyer 	rts
   12965  1.1.6.2  bouyer 
   12966  1.1.6.2  bouyer #
   12967  1.1.6.2  bouyer # operand is to be rounded to double precision
   12968  1.1.6.2  bouyer #
   12969  1.1.6.2  bouyer fneg_dbl:
   12970  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   12971  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   12972  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   12973  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# calculate scale factor
   12974  1.1.6.2  bouyer 
   12975  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
   12976  1.1.6.2  bouyer 	bge.b		fneg_sd_unfl		# yes; go handle underflow
   12977  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
   12978  1.1.6.2  bouyer 	beq.w		fneg_sd_may_ovfl	# maybe; go check
   12979  1.1.6.2  bouyer 	blt.w		fneg_sd_ovfl		# yes; go handle overflow
   12980  1.1.6.2  bouyer 	bra.w		fneg_sd_normal		# no; ho handle normalized op
   12981  1.1.6.2  bouyer 
   12982  1.1.6.2  bouyer #
   12983  1.1.6.2  bouyer # operand WILL underflow when moved in to the fp register file
   12984  1.1.6.2  bouyer #
   12985  1.1.6.2  bouyer fneg_sd_unfl:
   12986  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   12987  1.1.6.2  bouyer 
   12988  1.1.6.2  bouyer 	eori.b		&0x80,FP_SCR0_EX(%a6)	# negate sign
   12989  1.1.6.2  bouyer 	bpl.b		fneg_sd_unfl_tst
   12990  1.1.6.2  bouyer 	bset		&neg_bit,FPSR_CC(%a6)	# set 'N' ccode bit
   12991  1.1.6.2  bouyer 
   12992  1.1.6.2  bouyer # if underflow or inexact is enabled, go calculate EXOP first.
   12993  1.1.6.2  bouyer fneg_sd_unfl_tst:
   12994  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   12995  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   12996  1.1.6.2  bouyer 	bne.b		fneg_sd_unfl_ena	# yes
   12997  1.1.6.2  bouyer 
   12998  1.1.6.2  bouyer fneg_sd_unfl_dis:
   12999  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   13000  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   13001  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   13002  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# unf_res may have set 'Z'
   13003  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   13004  1.1.6.2  bouyer 	rts
   13005  1.1.6.2  bouyer 
   13006  1.1.6.2  bouyer #
   13007  1.1.6.2  bouyer # operand will underflow AND underflow is enabled.
   13008  1.1.6.2  bouyer # therefore, we must return the result rounded to extended precision.
   13009  1.1.6.2  bouyer #
   13010  1.1.6.2  bouyer fneg_sd_unfl_ena:
   13011  1.1.6.2  bouyer 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   13012  1.1.6.2  bouyer 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   13013  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   13014  1.1.6.2  bouyer 
   13015  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   13016  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   13017  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   13018  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   13019  1.1.6.2  bouyer 	sub.l		%d0,%d1			# subtract scale factor
   13020  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add new bias
   13021  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   13022  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat new sign,new exp
   13023  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
   13024  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   13025  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   13026  1.1.6.2  bouyer 	bra.b		fneg_sd_unfl_dis
   13027  1.1.6.2  bouyer 
   13028  1.1.6.2  bouyer #
   13029  1.1.6.2  bouyer # operand WILL overflow.
   13030  1.1.6.2  bouyer #
   13031  1.1.6.2  bouyer fneg_sd_ovfl:
   13032  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   13033  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13034  1.1.6.2  bouyer 
   13035  1.1.6.2  bouyer 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
   13036  1.1.6.2  bouyer 
   13037  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   13038  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   13039  1.1.6.2  bouyer 
   13040  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13041  1.1.6.2  bouyer 
   13042  1.1.6.2  bouyer fneg_sd_ovfl_tst:
   13043  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   13044  1.1.6.2  bouyer 
   13045  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   13046  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   13047  1.1.6.2  bouyer 	bne.b		fneg_sd_ovfl_ena	# yes
   13048  1.1.6.2  bouyer 
   13049  1.1.6.2  bouyer #
   13050  1.1.6.2  bouyer # OVFL is not enabled; therefore, we must create the default result by
   13051  1.1.6.2  bouyer # calling ovf_res().
   13052  1.1.6.2  bouyer #
   13053  1.1.6.2  bouyer fneg_sd_ovfl_dis:
   13054  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   13055  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   13056  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   13057  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   13058  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   13059  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   13060  1.1.6.2  bouyer 	rts
   13061  1.1.6.2  bouyer 
   13062  1.1.6.2  bouyer #
   13063  1.1.6.2  bouyer # OVFL is enabled.
   13064  1.1.6.2  bouyer # the INEX2 bit has already been updated by the round to the correct precision.
   13065  1.1.6.2  bouyer # now, round to extended(and don't alter the FPSR).
   13066  1.1.6.2  bouyer #
   13067  1.1.6.2  bouyer fneg_sd_ovfl_ena:
   13068  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   13069  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   13070  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   13071  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   13072  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   13073  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   13074  1.1.6.2  bouyer 	subi.l		&0x6000,%d1		# subtract bias
   13075  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   13076  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sign,exp
   13077  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   13078  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   13079  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   13080  1.1.6.2  bouyer 	bra.b		fneg_sd_ovfl_dis
   13081  1.1.6.2  bouyer 
   13082  1.1.6.2  bouyer #
   13083  1.1.6.2  bouyer # the move in MAY underflow. so...
   13084  1.1.6.2  bouyer #
   13085  1.1.6.2  bouyer fneg_sd_may_ovfl:
   13086  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   13087  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13088  1.1.6.2  bouyer 
   13089  1.1.6.2  bouyer 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
   13090  1.1.6.2  bouyer 
   13091  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   13092  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   13093  1.1.6.2  bouyer 
   13094  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13095  1.1.6.2  bouyer 
   13096  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   13097  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   13098  1.1.6.2  bouyer 	fbge.w		fneg_sd_ovfl_tst	# yes; overflow has occurred
   13099  1.1.6.2  bouyer 
   13100  1.1.6.2  bouyer # no, it didn't overflow; we have correct result
   13101  1.1.6.2  bouyer 	bra.w		fneg_sd_normal_exit
   13102  1.1.6.2  bouyer 
   13103  1.1.6.2  bouyer ##########################################################################
   13104  1.1.6.2  bouyer 
   13105  1.1.6.2  bouyer #
   13106  1.1.6.2  bouyer # input is not normalized; what is it?
   13107  1.1.6.2  bouyer #
   13108  1.1.6.2  bouyer fneg_not_norm:
   13109  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13110  1.1.6.2  bouyer 	beq.w		fneg_denorm
   13111  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13112  1.1.6.2  bouyer 	beq.l		res_snan_1op
   13113  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN		# weed out QNAN
   13114  1.1.6.2  bouyer 	beq.l		res_qnan_1op
   13115  1.1.6.2  bouyer 
   13116  1.1.6.2  bouyer #
   13117  1.1.6.2  bouyer # do the fneg; at this point, only possible ops are ZERO and INF.
   13118  1.1.6.2  bouyer # use fneg to determine ccodes.
   13119  1.1.6.2  bouyer # prec:mode should be zero at this point but it won't affect answer anyways.
   13120  1.1.6.2  bouyer #
   13121  1.1.6.2  bouyer 	fneg.x		SRC_EX(%a0),%fp0	# do fneg
   13122  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0
   13123  1.1.6.2  bouyer 	rol.l		&0x8,%d0		# put ccodes in lo byte
   13124  1.1.6.2  bouyer 	mov.b		%d0,FPSR_CC(%a6)	# insert correct ccodes
   13125  1.1.6.2  bouyer 	rts
   13126  1.1.6.2  bouyer 
   13127  1.1.6.2  bouyer #########################################################################
   13128  1.1.6.2  bouyer # XDEF ****************************************************************	#
   13129  1.1.6.2  bouyer # 	ftst(): emulates the ftest instruction				#
   13130  1.1.6.2  bouyer #									#
   13131  1.1.6.2  bouyer # XREF ****************************************************************	#
   13132  1.1.6.2  bouyer # 	res{s,q}nan_1op() - set NAN result for monadic instruction	#
   13133  1.1.6.2  bouyer #									#
   13134  1.1.6.2  bouyer # INPUT ***************************************************************	#
   13135  1.1.6.2  bouyer # 	a0 = pointer to extended precision source operand		#
   13136  1.1.6.2  bouyer #									#
   13137  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   13138  1.1.6.2  bouyer #	none								#
   13139  1.1.6.2  bouyer #									#
   13140  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   13141  1.1.6.2  bouyer # 	Check the source operand tag (STAG) and set the FPCR according	#
   13142  1.1.6.2  bouyer # to the operand type and sign.						#
   13143  1.1.6.2  bouyer #									#
   13144  1.1.6.2  bouyer #########################################################################
   13145  1.1.6.2  bouyer 
   13146  1.1.6.2  bouyer 	global		ftst
   13147  1.1.6.2  bouyer ftst:
   13148  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   13149  1.1.6.2  bouyer 	bne.b		ftst_not_norm		# optimize on non-norm input
   13150  1.1.6.2  bouyer 
   13151  1.1.6.2  bouyer #
   13152  1.1.6.2  bouyer # Norm:
   13153  1.1.6.2  bouyer #
   13154  1.1.6.2  bouyer ftst_norm:
   13155  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   13156  1.1.6.2  bouyer 	bmi.b		ftst_norm_m		# yes
   13157  1.1.6.2  bouyer 	rts
   13158  1.1.6.2  bouyer ftst_norm_m:
   13159  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   13160  1.1.6.2  bouyer 	rts
   13161  1.1.6.2  bouyer 
   13162  1.1.6.2  bouyer #
   13163  1.1.6.2  bouyer # input is not normalized; what is it?
   13164  1.1.6.2  bouyer #
   13165  1.1.6.2  bouyer ftst_not_norm:
   13166  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO		# weed out ZERO
   13167  1.1.6.2  bouyer 	beq.b		ftst_zero
   13168  1.1.6.2  bouyer 	cmpi.b		%d1,&INF		# weed out INF
   13169  1.1.6.2  bouyer 	beq.b		ftst_inf
   13170  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13171  1.1.6.2  bouyer 	beq.l		res_snan_1op
   13172  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN		# weed out QNAN
   13173  1.1.6.2  bouyer 	beq.l		res_qnan_1op
   13174  1.1.6.2  bouyer 
   13175  1.1.6.2  bouyer #
   13176  1.1.6.2  bouyer # Denorm:
   13177  1.1.6.2  bouyer #
   13178  1.1.6.2  bouyer ftst_denorm:
   13179  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   13180  1.1.6.2  bouyer 	bmi.b		ftst_denorm_m		# yes
   13181  1.1.6.2  bouyer 	rts
   13182  1.1.6.2  bouyer ftst_denorm_m:
   13183  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   13184  1.1.6.2  bouyer 	rts
   13185  1.1.6.2  bouyer 
   13186  1.1.6.2  bouyer #
   13187  1.1.6.2  bouyer # Infinity:
   13188  1.1.6.2  bouyer #
   13189  1.1.6.2  bouyer ftst_inf:
   13190  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   13191  1.1.6.2  bouyer 	bmi.b		ftst_inf_m		# yes
   13192  1.1.6.2  bouyer ftst_inf_p:
   13193  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13194  1.1.6.2  bouyer 	rts
   13195  1.1.6.2  bouyer ftst_inf_m:
   13196  1.1.6.2  bouyer 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'I','N' ccode bits
   13197  1.1.6.2  bouyer 	rts
   13198  1.1.6.2  bouyer 
   13199  1.1.6.2  bouyer #
   13200  1.1.6.2  bouyer # Zero:
   13201  1.1.6.2  bouyer #
   13202  1.1.6.2  bouyer ftst_zero:
   13203  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   13204  1.1.6.2  bouyer 	bmi.b		ftst_zero_m		# yes
   13205  1.1.6.2  bouyer ftst_zero_p:
   13206  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
   13207  1.1.6.2  bouyer 	rts
   13208  1.1.6.2  bouyer ftst_zero_m:
   13209  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set 'Z','N' ccode bits
   13210  1.1.6.2  bouyer 	rts
   13211  1.1.6.2  bouyer 
   13212  1.1.6.2  bouyer #########################################################################
   13213  1.1.6.2  bouyer # XDEF ****************************************************************	#
   13214  1.1.6.2  bouyer #	fint(): emulates the fint instruction				#
   13215  1.1.6.2  bouyer #									#
   13216  1.1.6.2  bouyer # XREF ****************************************************************	#
   13217  1.1.6.2  bouyer #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
   13218  1.1.6.2  bouyer #									#
   13219  1.1.6.2  bouyer # INPUT ***************************************************************	#
   13220  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   13221  1.1.6.2  bouyer #	d0 = round precision/mode					#
   13222  1.1.6.2  bouyer #									#
   13223  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   13224  1.1.6.2  bouyer #	fp0 = result							#
   13225  1.1.6.2  bouyer #									#
   13226  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   13227  1.1.6.2  bouyer # 	Separate according to operand type. Unnorms don't pass through 	#
   13228  1.1.6.2  bouyer # here. For norms, load the rounding mode/prec, execute a "fint", then 	#
   13229  1.1.6.2  bouyer # store the resulting FPSR bits.					#
   13230  1.1.6.2  bouyer # 	For denorms, force the j-bit to a one and do the same as for	#
   13231  1.1.6.2  bouyer # norms. Denorms are so low that the answer will either be a zero or a 	#
   13232  1.1.6.2  bouyer # one.									#
   13233  1.1.6.2  bouyer # 	For zeroes/infs/NANs, return the same while setting the FPSR	#
   13234  1.1.6.2  bouyer # as appropriate.							#
   13235  1.1.6.2  bouyer #									#
   13236  1.1.6.2  bouyer #########################################################################
   13237  1.1.6.2  bouyer 
   13238  1.1.6.2  bouyer 	global		fint
   13239  1.1.6.2  bouyer fint:
   13240  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   13241  1.1.6.2  bouyer 	bne.b		fint_not_norm		# optimize on non-norm input
   13242  1.1.6.2  bouyer 
   13243  1.1.6.2  bouyer #
   13244  1.1.6.2  bouyer # Norm:
   13245  1.1.6.2  bouyer #
   13246  1.1.6.2  bouyer fint_norm:
   13247  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# set prec = ext
   13248  1.1.6.2  bouyer 
   13249  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# set FPCR
   13250  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   13251  1.1.6.2  bouyer 
   13252  1.1.6.2  bouyer 	fint.x 		SRC(%a0),%fp0		# execute fint
   13253  1.1.6.2  bouyer 
   13254  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   13255  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# save FPSR
   13256  1.1.6.2  bouyer 	or.l		%d0,USER_FPSR(%a6)	# set exception bits
   13257  1.1.6.2  bouyer 
   13258  1.1.6.2  bouyer 	rts
   13259  1.1.6.2  bouyer 
   13260  1.1.6.2  bouyer #
   13261  1.1.6.2  bouyer # input is not normalized; what is it?
   13262  1.1.6.2  bouyer #
   13263  1.1.6.2  bouyer fint_not_norm:
   13264  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO		# weed out ZERO
   13265  1.1.6.2  bouyer 	beq.b		fint_zero
   13266  1.1.6.2  bouyer 	cmpi.b		%d1,&INF		# weed out INF
   13267  1.1.6.2  bouyer 	beq.b		fint_inf
   13268  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13269  1.1.6.2  bouyer 	beq.b		fint_denorm
   13270  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13271  1.1.6.2  bouyer 	beq.l		res_snan_1op
   13272  1.1.6.2  bouyer 	bra.l		res_qnan_1op		# weed out QNAN
   13273  1.1.6.2  bouyer 
   13274  1.1.6.2  bouyer #
   13275  1.1.6.2  bouyer # Denorm:
   13276  1.1.6.2  bouyer #
   13277  1.1.6.2  bouyer # for DENORMs, the result will be either (+/-)ZERO or (+/-)1.
   13278  1.1.6.2  bouyer # also, the INEX2 and AINEX exception bits will be set.
   13279  1.1.6.2  bouyer # so, we could either set these manually or force the DENORM
   13280  1.1.6.2  bouyer # to a very small NORM and ship it to the NORM routine.
   13281  1.1.6.2  bouyer # I do the latter.
   13282  1.1.6.2  bouyer #
   13283  1.1.6.2  bouyer fint_denorm:
   13284  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
   13285  1.1.6.2  bouyer 	mov.b		&0x80,FP_SCR0_HI(%a6)	# force DENORM ==> small NORM
   13286  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   13287  1.1.6.2  bouyer 	bra.b		fint_norm
   13288  1.1.6.2  bouyer 
   13289  1.1.6.2  bouyer #
   13290  1.1.6.2  bouyer # Zero:
   13291  1.1.6.2  bouyer #
   13292  1.1.6.2  bouyer fint_zero:
   13293  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is ZERO negative?
   13294  1.1.6.2  bouyer 	bmi.b		fint_zero_m		# yes
   13295  1.1.6.2  bouyer fint_zero_p:
   13296  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# return +ZERO in fp0
   13297  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13298  1.1.6.2  bouyer 	rts
   13299  1.1.6.2  bouyer fint_zero_m:
   13300  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# return -ZERO in fp0
   13301  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
   13302  1.1.6.2  bouyer 	rts
   13303  1.1.6.2  bouyer 
   13304  1.1.6.2  bouyer #
   13305  1.1.6.2  bouyer # Infinity:
   13306  1.1.6.2  bouyer #
   13307  1.1.6.2  bouyer fint_inf:
   13308  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   13309  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is INF negative?
   13310  1.1.6.2  bouyer 	bmi.b		fint_inf_m		# yes
   13311  1.1.6.2  bouyer fint_inf_p:
   13312  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13313  1.1.6.2  bouyer 	rts
   13314  1.1.6.2  bouyer fint_inf_m:
   13315  1.1.6.2  bouyer 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
   13316  1.1.6.2  bouyer 	rts
   13317  1.1.6.2  bouyer 
   13318  1.1.6.2  bouyer #########################################################################
   13319  1.1.6.2  bouyer # XDEF ****************************************************************	#
   13320  1.1.6.2  bouyer #	fintrz(): emulates the fintrz instruction			#
   13321  1.1.6.2  bouyer #									#
   13322  1.1.6.2  bouyer # XREF ****************************************************************	#
   13323  1.1.6.2  bouyer #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
   13324  1.1.6.2  bouyer #									#
   13325  1.1.6.2  bouyer # INPUT ***************************************************************	#
   13326  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   13327  1.1.6.2  bouyer #	d0 = round precision/mode					#
   13328  1.1.6.2  bouyer #									#
   13329  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   13330  1.1.6.2  bouyer # 	fp0 = result							#
   13331  1.1.6.2  bouyer #									#
   13332  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   13333  1.1.6.2  bouyer #	Separate according to operand type. Unnorms don't pass through	#
   13334  1.1.6.2  bouyer # here. For norms, load the rounding mode/prec, execute a "fintrz", 	#
   13335  1.1.6.2  bouyer # then store the resulting FPSR bits.					#
   13336  1.1.6.2  bouyer # 	For denorms, force the j-bit to a one and do the same as for	#
   13337  1.1.6.2  bouyer # norms. Denorms are so low that the answer will either be a zero or a	#
   13338  1.1.6.2  bouyer # one.									#
   13339  1.1.6.2  bouyer # 	For zeroes/infs/NANs, return the same while setting the FPSR	#
   13340  1.1.6.2  bouyer # as appropriate.							#
   13341  1.1.6.2  bouyer #									#
   13342  1.1.6.2  bouyer #########################################################################
   13343  1.1.6.2  bouyer 
   13344  1.1.6.2  bouyer 	global		fintrz
   13345  1.1.6.2  bouyer fintrz:
   13346  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   13347  1.1.6.2  bouyer 	bne.b		fintrz_not_norm		# optimize on non-norm input
   13348  1.1.6.2  bouyer 
   13349  1.1.6.2  bouyer #
   13350  1.1.6.2  bouyer # Norm:
   13351  1.1.6.2  bouyer #
   13352  1.1.6.2  bouyer fintrz_norm:
   13353  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   13354  1.1.6.2  bouyer 
   13355  1.1.6.2  bouyer 	fintrz.x	SRC(%a0),%fp0		# execute fintrz
   13356  1.1.6.2  bouyer 
   13357  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# save FPSR
   13358  1.1.6.2  bouyer 	or.l		%d0,USER_FPSR(%a6)	# set exception bits
   13359  1.1.6.2  bouyer 
   13360  1.1.6.2  bouyer 	rts
   13361  1.1.6.2  bouyer 
   13362  1.1.6.2  bouyer #
   13363  1.1.6.2  bouyer # input is not normalized; what is it?
   13364  1.1.6.2  bouyer #
   13365  1.1.6.2  bouyer fintrz_not_norm:
   13366  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO		# weed out ZERO
   13367  1.1.6.2  bouyer 	beq.b		fintrz_zero
   13368  1.1.6.2  bouyer 	cmpi.b		%d1,&INF		# weed out INF
   13369  1.1.6.2  bouyer 	beq.b		fintrz_inf
   13370  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13371  1.1.6.2  bouyer 	beq.b		fintrz_denorm
   13372  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13373  1.1.6.2  bouyer 	beq.l		res_snan_1op
   13374  1.1.6.2  bouyer 	bra.l		res_qnan_1op		# weed out QNAN
   13375  1.1.6.2  bouyer 
   13376  1.1.6.2  bouyer #
   13377  1.1.6.2  bouyer # Denorm:
   13378  1.1.6.2  bouyer #
   13379  1.1.6.2  bouyer # for DENORMs, the result will be (+/-)ZERO.
   13380  1.1.6.2  bouyer # also, the INEX2 and AINEX exception bits will be set.
   13381  1.1.6.2  bouyer # so, we could either set these manually or force the DENORM
   13382  1.1.6.2  bouyer # to a very small NORM and ship it to the NORM routine.
   13383  1.1.6.2  bouyer # I do the latter.
   13384  1.1.6.2  bouyer #
   13385  1.1.6.2  bouyer fintrz_denorm:
   13386  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
   13387  1.1.6.2  bouyer 	mov.b		&0x80,FP_SCR0_HI(%a6)	# force DENORM ==> small NORM
   13388  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   13389  1.1.6.2  bouyer 	bra.b		fintrz_norm
   13390  1.1.6.2  bouyer 
   13391  1.1.6.2  bouyer #
   13392  1.1.6.2  bouyer # Zero:
   13393  1.1.6.2  bouyer #
   13394  1.1.6.2  bouyer fintrz_zero:
   13395  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is ZERO negative?
   13396  1.1.6.2  bouyer 	bmi.b		fintrz_zero_m		# yes
   13397  1.1.6.2  bouyer fintrz_zero_p:
   13398  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# return +ZERO in fp0
   13399  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13400  1.1.6.2  bouyer 	rts
   13401  1.1.6.2  bouyer fintrz_zero_m:
   13402  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# return -ZERO in fp0
   13403  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
   13404  1.1.6.2  bouyer 	rts
   13405  1.1.6.2  bouyer 
   13406  1.1.6.2  bouyer #
   13407  1.1.6.2  bouyer # Infinity:
   13408  1.1.6.2  bouyer #
   13409  1.1.6.2  bouyer fintrz_inf:
   13410  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
   13411  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is INF negative?
   13412  1.1.6.2  bouyer 	bmi.b		fintrz_inf_m		# yes
   13413  1.1.6.2  bouyer fintrz_inf_p:
   13414  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13415  1.1.6.2  bouyer 	rts
   13416  1.1.6.2  bouyer fintrz_inf_m:
   13417  1.1.6.2  bouyer 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
   13418  1.1.6.2  bouyer 	rts
   13419  1.1.6.2  bouyer 
   13420  1.1.6.2  bouyer #########################################################################
   13421  1.1.6.2  bouyer # XDEF ****************************************************************	#
   13422  1.1.6.2  bouyer #	fabs():  emulates the fabs instruction				#
   13423  1.1.6.2  bouyer #	fsabs(): emulates the fsabs instruction				#
   13424  1.1.6.2  bouyer #	fdabs(): emulates the fdabs instruction				#
   13425  1.1.6.2  bouyer #									#
   13426  1.1.6.2  bouyer # XREF **************************************************************** #
   13427  1.1.6.2  bouyer #	norm() - normalize denorm mantissa to provide EXOP		#
   13428  1.1.6.2  bouyer #	scale_to_zero_src() - make exponent. = 0; get scale factor	#
   13429  1.1.6.2  bouyer #	unf_res() - calculate underflow result				#
   13430  1.1.6.2  bouyer #	ovf_res() - calculate overflow result				#
   13431  1.1.6.2  bouyer #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
   13432  1.1.6.2  bouyer #									#
   13433  1.1.6.2  bouyer # INPUT *************************************************************** #
   13434  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   13435  1.1.6.2  bouyer #	d0 = rnd precision/mode						#
   13436  1.1.6.2  bouyer #									#
   13437  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   13438  1.1.6.2  bouyer #	fp0 = result							#
   13439  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   13440  1.1.6.2  bouyer #									#
   13441  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   13442  1.1.6.2  bouyer #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   13443  1.1.6.2  bouyer # norms into extended, single, and double precision. 			#
   13444  1.1.6.2  bouyer # 	Simply clear sign for extended precision norm. Ext prec denorm	#
   13445  1.1.6.2  bouyer # gets an EXOP created for it since it's an underflow.			#
   13446  1.1.6.2  bouyer #	Double and single precision can overflow and underflow. First,	#
   13447  1.1.6.2  bouyer # scale the operand such that the exponent is zero. Perform an "fabs"	#
   13448  1.1.6.2  bouyer # using the correct rnd mode/prec. Check to see if the original 	#
   13449  1.1.6.2  bouyer # exponent would take an exception. If so, use unf_res() or ovf_res()	#
   13450  1.1.6.2  bouyer # to calculate the default result. Also, create the EXOP for the	#
   13451  1.1.6.2  bouyer # exceptional case. If no exception should occur, insert the correct 	#
   13452  1.1.6.2  bouyer # result exponent and return.						#
   13453  1.1.6.2  bouyer # 	Unnorms don't pass through here.				#
   13454  1.1.6.2  bouyer #									#
   13455  1.1.6.2  bouyer #########################################################################
   13456  1.1.6.2  bouyer 
   13457  1.1.6.2  bouyer 	global		fsabs
   13458  1.1.6.2  bouyer fsabs:
   13459  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   13460  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   13461  1.1.6.2  bouyer 	bra.b		fabs
   13462  1.1.6.2  bouyer 
   13463  1.1.6.2  bouyer 	global		fdabs
   13464  1.1.6.2  bouyer fdabs:
   13465  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   13466  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
   13467  1.1.6.2  bouyer 
   13468  1.1.6.2  bouyer 	global		fabs
   13469  1.1.6.2  bouyer fabs:
   13470  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   13471  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   13472  1.1.6.2  bouyer 	bne.w		fabs_not_norm		# optimize on non-norm input
   13473  1.1.6.2  bouyer 
   13474  1.1.6.2  bouyer #
   13475  1.1.6.2  bouyer # ABSOLUTE VALUE: norms and denorms ONLY!
   13476  1.1.6.2  bouyer #
   13477  1.1.6.2  bouyer fabs_norm:
   13478  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   13479  1.1.6.2  bouyer 	bne.b		fabs_not_ext		# no; go handle sgl or dbl
   13480  1.1.6.2  bouyer 
   13481  1.1.6.2  bouyer #
   13482  1.1.6.2  bouyer # precision selected is extended. so...we can not get an underflow
   13483  1.1.6.2  bouyer # or overflow because of rounding to the correct precision. so...
   13484  1.1.6.2  bouyer # skip the scaling and unscaling...
   13485  1.1.6.2  bouyer #
   13486  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13487  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13488  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d1
   13489  1.1.6.2  bouyer 	bclr		&15,%d1			# force absolute value
   13490  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert exponent
   13491  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   13492  1.1.6.2  bouyer 	rts
   13493  1.1.6.2  bouyer 
   13494  1.1.6.2  bouyer #
   13495  1.1.6.2  bouyer # for an extended precision DENORM, the UNFL exception bit is set
   13496  1.1.6.2  bouyer # the accrued bit is NOT set in this instance(no inexactness!)
   13497  1.1.6.2  bouyer #
   13498  1.1.6.2  bouyer fabs_denorm:
   13499  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   13500  1.1.6.2  bouyer 	bne.b		fabs_not_ext		# no
   13501  1.1.6.2  bouyer 
   13502  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   13503  1.1.6.2  bouyer 
   13504  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13505  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13506  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0
   13507  1.1.6.2  bouyer 	bclr		&15,%d0			# clear sign
   13508  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert exponent
   13509  1.1.6.2  bouyer 
   13510  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   13511  1.1.6.2  bouyer 
   13512  1.1.6.2  bouyer 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
   13513  1.1.6.2  bouyer 	bne.b		fabs_ext_unfl_ena
   13514  1.1.6.2  bouyer 	rts
   13515  1.1.6.2  bouyer 
   13516  1.1.6.2  bouyer #
   13517  1.1.6.2  bouyer # the input is an extended DENORM and underflow is enabled in the FPCR.
   13518  1.1.6.2  bouyer # normalize the mantissa and add the bias of 0x6000 to the resulting negative
   13519  1.1.6.2  bouyer # exponent and insert back into the operand.
   13520  1.1.6.2  bouyer #
   13521  1.1.6.2  bouyer fabs_ext_unfl_ena:
   13522  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   13523  1.1.6.2  bouyer 	bsr.l		norm			# normalize result
   13524  1.1.6.2  bouyer 	neg.w		%d0			# new exponent = -(shft val)
   13525  1.1.6.2  bouyer 	addi.w		&0x6000,%d0		# add new bias to exponent
   13526  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
   13527  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep old sign
   13528  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# clear sign position
   13529  1.1.6.2  bouyer 	or.w		%d1,%d0			# concat old sign, new exponent
   13530  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   13531  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   13532  1.1.6.2  bouyer 	rts
   13533  1.1.6.2  bouyer 
   13534  1.1.6.2  bouyer #
   13535  1.1.6.2  bouyer # operand is either single or double
   13536  1.1.6.2  bouyer #
   13537  1.1.6.2  bouyer fabs_not_ext:
   13538  1.1.6.2  bouyer 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
   13539  1.1.6.2  bouyer 	bne.b		fabs_dbl
   13540  1.1.6.2  bouyer 
   13541  1.1.6.2  bouyer #
   13542  1.1.6.2  bouyer # operand is to be rounded to single precision
   13543  1.1.6.2  bouyer #
   13544  1.1.6.2  bouyer fabs_sgl:
   13545  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13546  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13547  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13548  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# calculate scale factor
   13549  1.1.6.2  bouyer 
   13550  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
   13551  1.1.6.2  bouyer 	bge.w		fabs_sd_unfl		# yes; go handle underflow
   13552  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
   13553  1.1.6.2  bouyer 	beq.w		fabs_sd_may_ovfl	# maybe; go check
   13554  1.1.6.2  bouyer 	blt.w		fabs_sd_ovfl		# yes; go handle overflow
   13555  1.1.6.2  bouyer 
   13556  1.1.6.2  bouyer #
   13557  1.1.6.2  bouyer # operand will NOT overflow or underflow when moved in to the fp reg file
   13558  1.1.6.2  bouyer #
   13559  1.1.6.2  bouyer fabs_sd_normal:
   13560  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   13561  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13562  1.1.6.2  bouyer 
   13563  1.1.6.2  bouyer 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
   13564  1.1.6.2  bouyer 
   13565  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   13566  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   13567  1.1.6.2  bouyer 
   13568  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13569  1.1.6.2  bouyer 
   13570  1.1.6.2  bouyer fabs_sd_normal_exit:
   13571  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   13572  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   13573  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
   13574  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   13575  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   13576  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   13577  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   13578  1.1.6.2  bouyer 	or.w		%d1,%d2			# concat old sign,new exp
   13579  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   13580  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   13581  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   13582  1.1.6.2  bouyer 	rts
   13583  1.1.6.2  bouyer 
   13584  1.1.6.2  bouyer #
   13585  1.1.6.2  bouyer # operand is to be rounded to double precision
   13586  1.1.6.2  bouyer #
   13587  1.1.6.2  bouyer fabs_dbl:
   13588  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13589  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13590  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13591  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# calculate scale factor
   13592  1.1.6.2  bouyer 
   13593  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
   13594  1.1.6.2  bouyer 	bge.b		fabs_sd_unfl		# yes; go handle underflow
   13595  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
   13596  1.1.6.2  bouyer 	beq.w		fabs_sd_may_ovfl	# maybe; go check
   13597  1.1.6.2  bouyer 	blt.w		fabs_sd_ovfl		# yes; go handle overflow
   13598  1.1.6.2  bouyer 	bra.w		fabs_sd_normal		# no; ho handle normalized op
   13599  1.1.6.2  bouyer 
   13600  1.1.6.2  bouyer #
   13601  1.1.6.2  bouyer # operand WILL underflow when moved in to the fp register file
   13602  1.1.6.2  bouyer #
   13603  1.1.6.2  bouyer fabs_sd_unfl:
   13604  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   13605  1.1.6.2  bouyer 
   13606  1.1.6.2  bouyer 	bclr		&0x7,FP_SCR0_EX(%a6)	# force absolute value
   13607  1.1.6.2  bouyer 
   13608  1.1.6.2  bouyer # if underflow or inexact is enabled, go calculate EXOP first.
   13609  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   13610  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   13611  1.1.6.2  bouyer 	bne.b		fabs_sd_unfl_ena	# yes
   13612  1.1.6.2  bouyer 
   13613  1.1.6.2  bouyer fabs_sd_unfl_dis:
   13614  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   13615  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   13616  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   13617  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set possible 'Z' ccode
   13618  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   13619  1.1.6.2  bouyer 	rts
   13620  1.1.6.2  bouyer 
   13621  1.1.6.2  bouyer #
   13622  1.1.6.2  bouyer # operand will underflow AND underflow is enabled.
   13623  1.1.6.2  bouyer # therefore, we must return the result rounded to extended precision.
   13624  1.1.6.2  bouyer #
   13625  1.1.6.2  bouyer fabs_sd_unfl_ena:
   13626  1.1.6.2  bouyer 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   13627  1.1.6.2  bouyer 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   13628  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   13629  1.1.6.2  bouyer 
   13630  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   13631  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   13632  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   13633  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   13634  1.1.6.2  bouyer 	sub.l		%d0,%d1			# subtract scale factor
   13635  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add new bias
   13636  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   13637  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat new sign,new exp
   13638  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
   13639  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   13640  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   13641  1.1.6.2  bouyer 	bra.b		fabs_sd_unfl_dis
   13642  1.1.6.2  bouyer 
   13643  1.1.6.2  bouyer #
   13644  1.1.6.2  bouyer # operand WILL overflow.
   13645  1.1.6.2  bouyer #
   13646  1.1.6.2  bouyer fabs_sd_ovfl:
   13647  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   13648  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13649  1.1.6.2  bouyer 
   13650  1.1.6.2  bouyer 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
   13651  1.1.6.2  bouyer 
   13652  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   13653  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   13654  1.1.6.2  bouyer 
   13655  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13656  1.1.6.2  bouyer 
   13657  1.1.6.2  bouyer fabs_sd_ovfl_tst:
   13658  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   13659  1.1.6.2  bouyer 
   13660  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   13661  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   13662  1.1.6.2  bouyer 	bne.b		fabs_sd_ovfl_ena	# yes
   13663  1.1.6.2  bouyer 
   13664  1.1.6.2  bouyer #
   13665  1.1.6.2  bouyer # OVFL is not enabled; therefore, we must create the default result by
   13666  1.1.6.2  bouyer # calling ovf_res().
   13667  1.1.6.2  bouyer #
   13668  1.1.6.2  bouyer fabs_sd_ovfl_dis:
   13669  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   13670  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   13671  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   13672  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   13673  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   13674  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   13675  1.1.6.2  bouyer 	rts
   13676  1.1.6.2  bouyer 
   13677  1.1.6.2  bouyer #
   13678  1.1.6.2  bouyer # OVFL is enabled.
   13679  1.1.6.2  bouyer # the INEX2 bit has already been updated by the round to the correct precision.
   13680  1.1.6.2  bouyer # now, round to extended(and don't alter the FPSR).
   13681  1.1.6.2  bouyer #
   13682  1.1.6.2  bouyer fabs_sd_ovfl_ena:
   13683  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   13684  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   13685  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   13686  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   13687  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   13688  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   13689  1.1.6.2  bouyer 	subi.l		&0x6000,%d1		# subtract bias
   13690  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   13691  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sign,exp
   13692  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   13693  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   13694  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   13695  1.1.6.2  bouyer 	bra.b		fabs_sd_ovfl_dis
   13696  1.1.6.2  bouyer 
   13697  1.1.6.2  bouyer #
   13698  1.1.6.2  bouyer # the move in MAY underflow. so...
   13699  1.1.6.2  bouyer #
   13700  1.1.6.2  bouyer fabs_sd_may_ovfl:
   13701  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   13702  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   13703  1.1.6.2  bouyer 
   13704  1.1.6.2  bouyer 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
   13705  1.1.6.2  bouyer 
   13706  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   13707  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   13708  1.1.6.2  bouyer 
   13709  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   13710  1.1.6.2  bouyer 
   13711  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   13712  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   13713  1.1.6.2  bouyer 	fbge.w		fabs_sd_ovfl_tst	# yes; overflow has occurred
   13714  1.1.6.2  bouyer 
   13715  1.1.6.2  bouyer # no, it didn't overflow; we have correct result
   13716  1.1.6.2  bouyer 	bra.w		fabs_sd_normal_exit
   13717  1.1.6.2  bouyer 
   13718  1.1.6.2  bouyer ##########################################################################
   13719  1.1.6.2  bouyer 
   13720  1.1.6.2  bouyer #
   13721  1.1.6.2  bouyer # input is not normalized; what is it?
   13722  1.1.6.2  bouyer #
   13723  1.1.6.2  bouyer fabs_not_norm:
   13724  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM		# weed out DENORM
   13725  1.1.6.2  bouyer 	beq.w		fabs_denorm
   13726  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN		# weed out SNAN
   13727  1.1.6.2  bouyer 	beq.l		res_snan_1op
   13728  1.1.6.2  bouyer 	cmpi.b		%d1,&QNAN		# weed out QNAN
   13729  1.1.6.2  bouyer 	beq.l		res_qnan_1op
   13730  1.1.6.2  bouyer 
   13731  1.1.6.2  bouyer 	fabs.x		SRC(%a0),%fp0		# force absolute value
   13732  1.1.6.2  bouyer 
   13733  1.1.6.2  bouyer 	cmpi.b		%d1,&INF		# weed out INF
   13734  1.1.6.2  bouyer 	beq.b		fabs_inf
   13735  1.1.6.2  bouyer fabs_zero:
   13736  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13737  1.1.6.2  bouyer 	rts
   13738  1.1.6.2  bouyer fabs_inf:
   13739  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   13740  1.1.6.2  bouyer 	rts
   13741  1.1.6.2  bouyer 
   13742  1.1.6.2  bouyer #########################################################################
   13743  1.1.6.2  bouyer # XDEF ****************************************************************	#
   13744  1.1.6.2  bouyer # 	fcmp(): fp compare op routine					#
   13745  1.1.6.2  bouyer #									#
   13746  1.1.6.2  bouyer # XREF ****************************************************************	#
   13747  1.1.6.2  bouyer # 	res_qnan() - return QNAN result					#
   13748  1.1.6.2  bouyer #	res_snan() - return SNAN result					#
   13749  1.1.6.2  bouyer #									#
   13750  1.1.6.2  bouyer # INPUT ***************************************************************	#
   13751  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   13752  1.1.6.2  bouyer #	a1 = pointer to extended precision destination operand		#
   13753  1.1.6.2  bouyer #	d0 = round prec/mode						#
   13754  1.1.6.2  bouyer #									#
   13755  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   13756  1.1.6.2  bouyer #	None								#
   13757  1.1.6.2  bouyer #									#
   13758  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   13759  1.1.6.2  bouyer # 	Handle NANs and denorms as special cases. For everything else,	#
   13760  1.1.6.2  bouyer # just use the actual fcmp instruction to produce the correct condition	#
   13761  1.1.6.2  bouyer # codes.								#
   13762  1.1.6.2  bouyer #									#
   13763  1.1.6.2  bouyer #########################################################################
   13764  1.1.6.2  bouyer 
   13765  1.1.6.2  bouyer 	global		fcmp
   13766  1.1.6.2  bouyer fcmp:
   13767  1.1.6.2  bouyer 	clr.w		%d1
   13768  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   13769  1.1.6.2  bouyer 	lsl.b		&0x3,%d1
   13770  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1
   13771  1.1.6.2  bouyer 	bne.b		fcmp_not_norm		# optimize on non-norm input
   13772  1.1.6.2  bouyer 
   13773  1.1.6.2  bouyer #
   13774  1.1.6.2  bouyer # COMPARE FP OPs : NORMs, ZEROs, INFs, and "corrected" DENORMs
   13775  1.1.6.2  bouyer #
   13776  1.1.6.2  bouyer fcmp_norm:
   13777  1.1.6.2  bouyer 	fmovm.x		DST(%a1),&0x80		# load dst op
   13778  1.1.6.2  bouyer 
   13779  1.1.6.2  bouyer 	fcmp.x 		%fp0,SRC(%a0)		# do compare
   13780  1.1.6.2  bouyer 
   13781  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# save FPSR
   13782  1.1.6.2  bouyer 	rol.l		&0x8,%d0		# extract ccode bits
   13783  1.1.6.2  bouyer 	mov.b		%d0,FPSR_CC(%a6)	# set ccode bits(no exc bits are set)
   13784  1.1.6.2  bouyer 
   13785  1.1.6.2  bouyer 	rts
   13786  1.1.6.2  bouyer 
   13787  1.1.6.2  bouyer #
   13788  1.1.6.2  bouyer # fcmp: inputs are not both normalized; what are they?
   13789  1.1.6.2  bouyer #
   13790  1.1.6.2  bouyer fcmp_not_norm:
   13791  1.1.6.2  bouyer 	mov.w		(tbl_fcmp_op.b,%pc,%d1.w*2),%d1
   13792  1.1.6.2  bouyer 	jmp		(tbl_fcmp_op.b,%pc,%d1.w*1)
   13793  1.1.6.2  bouyer 
   13794  1.1.6.2  bouyer 	swbeg		&48
   13795  1.1.6.2  bouyer tbl_fcmp_op:
   13796  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # NORM - NORM
   13797  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # NORM - ZERO
   13798  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # NORM - INF
   13799  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # NORM - QNAN
   13800  1.1.6.2  bouyer 	short		fcmp_nrm_dnrm 	- tbl_fcmp_op # NORM - DENORM
   13801  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # NORM - SNAN
   13802  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13803  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13804  1.1.6.2  bouyer 
   13805  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # ZERO - NORM
   13806  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # ZERO - ZERO
   13807  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # ZERO - INF
   13808  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # ZERO - QNAN
   13809  1.1.6.2  bouyer 	short		fcmp_dnrm_s	- tbl_fcmp_op # ZERO - DENORM
   13810  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # ZERO - SNAN
   13811  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13812  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13813  1.1.6.2  bouyer 
   13814  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # INF - NORM
   13815  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # INF - ZERO
   13816  1.1.6.2  bouyer 	short		fcmp_norm	- tbl_fcmp_op # INF - INF
   13817  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # INF - QNAN
   13818  1.1.6.2  bouyer 	short		fcmp_dnrm_s	- tbl_fcmp_op # INF - DENORM
   13819  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # INF - SNAN
   13820  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13821  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13822  1.1.6.2  bouyer 
   13823  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - NORM
   13824  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - ZERO
   13825  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - INF
   13826  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - QNAN
   13827  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - DENORM
   13828  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # QNAN - SNAN
   13829  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13830  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13831  1.1.6.2  bouyer 
   13832  1.1.6.2  bouyer 	short		fcmp_dnrm_nrm	- tbl_fcmp_op # DENORM - NORM
   13833  1.1.6.2  bouyer 	short		fcmp_dnrm_d	- tbl_fcmp_op # DENORM - ZERO
   13834  1.1.6.2  bouyer 	short		fcmp_dnrm_d	- tbl_fcmp_op # DENORM - INF
   13835  1.1.6.2  bouyer 	short		fcmp_res_qnan	- tbl_fcmp_op # DENORM - QNAN
   13836  1.1.6.2  bouyer 	short		fcmp_dnrm_sd	- tbl_fcmp_op # DENORM - DENORM
   13837  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # DENORM - SNAN
   13838  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13839  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13840  1.1.6.2  bouyer 
   13841  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - NORM
   13842  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - ZERO
   13843  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - INF
   13844  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - QNAN
   13845  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - DENORM
   13846  1.1.6.2  bouyer 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - SNAN
   13847  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13848  1.1.6.2  bouyer 	short		tbl_fcmp_op	- tbl_fcmp_op #
   13849  1.1.6.2  bouyer 
   13850  1.1.6.2  bouyer # unlike all other functions for QNAN and SNAN, fcmp does NOT set the
   13851  1.1.6.2  bouyer # 'N' bit for a negative QNAN or SNAN input so we must squelch it here.
   13852  1.1.6.2  bouyer fcmp_res_qnan:
   13853  1.1.6.2  bouyer 	bsr.l		res_qnan
   13854  1.1.6.2  bouyer 	andi.b		&0xf7,FPSR_CC(%a6)
   13855  1.1.6.2  bouyer 	rts
   13856  1.1.6.2  bouyer fcmp_res_snan:
   13857  1.1.6.2  bouyer 	bsr.l		res_snan
   13858  1.1.6.2  bouyer 	andi.b		&0xf7,FPSR_CC(%a6)
   13859  1.1.6.2  bouyer 	rts
   13860  1.1.6.2  bouyer 
   13861  1.1.6.2  bouyer #
   13862  1.1.6.2  bouyer # DENORMs are a little more difficult.
   13863  1.1.6.2  bouyer # If you have a 2 DENORMs, then you can just force the j-bit to a one
   13864  1.1.6.2  bouyer # and use the fcmp_norm routine.
   13865  1.1.6.2  bouyer # If you have a DENORM and an INF or ZERO, just force the DENORM's j-bit to a one
   13866  1.1.6.2  bouyer # and use the fcmp_norm routine.
   13867  1.1.6.2  bouyer # If you have a DENORM and a NORM with opposite signs, then use fcmp_norm, also.
   13868  1.1.6.2  bouyer # But with a DENORM and a NORM of the same sign, the neg bit is set if the
   13869  1.1.6.2  bouyer # (1) signs are (+) and the DENORM is the dst or
   13870  1.1.6.2  bouyer # (2) signs are (-) and the DENORM is the src
   13871  1.1.6.2  bouyer #
   13872  1.1.6.2  bouyer 
   13873  1.1.6.2  bouyer fcmp_dnrm_s:
   13874  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13875  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),%d0
   13876  1.1.6.2  bouyer 	bset		&31,%d0			# DENORM src; make into small norm
   13877  1.1.6.2  bouyer 	mov.l		%d0,FP_SCR0_HI(%a6)
   13878  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13879  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   13880  1.1.6.2  bouyer 	bra.w		fcmp_norm
   13881  1.1.6.2  bouyer 
   13882  1.1.6.2  bouyer fcmp_dnrm_d:
   13883  1.1.6.2  bouyer 	mov.l		DST_EX(%a1),FP_SCR0_EX(%a6)
   13884  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),%d0
   13885  1.1.6.2  bouyer 	bset		&31,%d0			# DENORM src; make into small norm
   13886  1.1.6.2  bouyer 	mov.l		%d0,FP_SCR0_HI(%a6)
   13887  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
   13888  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a1
   13889  1.1.6.2  bouyer 	bra.w		fcmp_norm
   13890  1.1.6.2  bouyer 
   13891  1.1.6.2  bouyer fcmp_dnrm_sd:
   13892  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   13893  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13894  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),%d0
   13895  1.1.6.2  bouyer 	bset		&31,%d0			# DENORM dst; make into small norm
   13896  1.1.6.2  bouyer 	mov.l		%d0,FP_SCR1_HI(%a6)
   13897  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),%d0
   13898  1.1.6.2  bouyer 	bset		&31,%d0			# DENORM dst; make into small norm
   13899  1.1.6.2  bouyer 	mov.l		%d0,FP_SCR0_HI(%a6)
   13900  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   13901  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13902  1.1.6.2  bouyer 	lea		FP_SCR1(%a6),%a1
   13903  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   13904  1.1.6.2  bouyer 	bra.w		fcmp_norm
   13905  1.1.6.2  bouyer 
   13906  1.1.6.2  bouyer fcmp_nrm_dnrm:
   13907  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# determine if like signs
   13908  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   13909  1.1.6.2  bouyer 	eor.b		%d0,%d1
   13910  1.1.6.2  bouyer 	bmi.w		fcmp_dnrm_s
   13911  1.1.6.2  bouyer 
   13912  1.1.6.2  bouyer # signs are the same, so must determine the answer ourselves.
   13913  1.1.6.2  bouyer 	tst.b		%d0			# is src op negative?
   13914  1.1.6.2  bouyer 	bmi.b		fcmp_nrm_dnrm_m		# yes
   13915  1.1.6.2  bouyer 	rts
   13916  1.1.6.2  bouyer fcmp_nrm_dnrm_m:
   13917  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13918  1.1.6.2  bouyer 	rts
   13919  1.1.6.2  bouyer 
   13920  1.1.6.2  bouyer fcmp_dnrm_nrm:
   13921  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# determine if like signs
   13922  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   13923  1.1.6.2  bouyer 	eor.b		%d0,%d1
   13924  1.1.6.2  bouyer 	bmi.w		fcmp_dnrm_d
   13925  1.1.6.2  bouyer 
   13926  1.1.6.2  bouyer # signs are the same, so must determine the answer ourselves.
   13927  1.1.6.2  bouyer 	tst.b		%d0			# is src op negative?
   13928  1.1.6.2  bouyer 	bpl.b		fcmp_dnrm_nrm_m		# no
   13929  1.1.6.2  bouyer 	rts
   13930  1.1.6.2  bouyer fcmp_dnrm_nrm_m:
   13931  1.1.6.2  bouyer 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   13932  1.1.6.2  bouyer 	rts
   13933  1.1.6.2  bouyer 
   13934  1.1.6.2  bouyer #########################################################################
   13935  1.1.6.2  bouyer # XDEF ****************************************************************	#
   13936  1.1.6.2  bouyer # 	fsglmul(): emulates the fsglmul instruction			#
   13937  1.1.6.2  bouyer #									#
   13938  1.1.6.2  bouyer # XREF ****************************************************************	#
   13939  1.1.6.2  bouyer #	scale_to_zero_src() - scale src exponent to zero		#
   13940  1.1.6.2  bouyer #	scale_to_zero_dst() - scale dst exponent to zero		#
   13941  1.1.6.2  bouyer #	unf_res4() - return default underflow result for sglop		#
   13942  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   13943  1.1.6.2  bouyer # 	res_qnan() - return QNAN result					#
   13944  1.1.6.2  bouyer # 	res_snan() - return SNAN result					#
   13945  1.1.6.2  bouyer #									#
   13946  1.1.6.2  bouyer # INPUT ***************************************************************	#
   13947  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   13948  1.1.6.2  bouyer #	a1 = pointer to extended precision destination operand		#
   13949  1.1.6.2  bouyer #	d0  rnd prec,mode						#
   13950  1.1.6.2  bouyer #									#
   13951  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   13952  1.1.6.2  bouyer #	fp0 = result							#
   13953  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   13954  1.1.6.2  bouyer #									#
   13955  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   13956  1.1.6.2  bouyer #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   13957  1.1.6.2  bouyer # norms/denorms into ext/sgl/dbl precision.				#
   13958  1.1.6.2  bouyer #	For norms/denorms, scale the exponents such that a multiply	#
   13959  1.1.6.2  bouyer # instruction won't cause an exception. Use the regular fsglmul to	#
   13960  1.1.6.2  bouyer # compute a result. Check if the regular operands would have taken	#
   13961  1.1.6.2  bouyer # an exception. If so, return the default overflow/underflow result	#
   13962  1.1.6.2  bouyer # and return the EXOP if exceptions are enabled. Else, scale the 	#
   13963  1.1.6.2  bouyer # result operand to the proper exponent.				#
   13964  1.1.6.2  bouyer #									#
   13965  1.1.6.2  bouyer #########################################################################
   13966  1.1.6.2  bouyer 
   13967  1.1.6.2  bouyer 	global		fsglmul
   13968  1.1.6.2  bouyer fsglmul:
   13969  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   13970  1.1.6.2  bouyer 
   13971  1.1.6.2  bouyer 	clr.w		%d1
   13972  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   13973  1.1.6.2  bouyer 	lsl.b		&0x3,%d1
   13974  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1
   13975  1.1.6.2  bouyer 
   13976  1.1.6.2  bouyer 	bne.w		fsglmul_not_norm	# optimize on non-norm input
   13977  1.1.6.2  bouyer 
   13978  1.1.6.2  bouyer fsglmul_norm:
   13979  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   13980  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   13981  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   13982  1.1.6.2  bouyer 
   13983  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   13984  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   13985  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   13986  1.1.6.2  bouyer 
   13987  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# scale exponent
   13988  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save scale factor 1
   13989  1.1.6.2  bouyer 
   13990  1.1.6.2  bouyer 	bsr.l		scale_to_zero_dst	# scale dst exponent
   13991  1.1.6.2  bouyer 
   13992  1.1.6.2  bouyer 	add.l		(%sp)+,%d0		# SCALE_FACTOR = scale1 + scale2
   13993  1.1.6.2  bouyer 
   13994  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x7ffe 	# would result ovfl?
   13995  1.1.6.2  bouyer 	beq.w		fsglmul_may_ovfl	# result may rnd to overflow
   13996  1.1.6.2  bouyer 	blt.w		fsglmul_ovfl		# result will overflow
   13997  1.1.6.2  bouyer 
   13998  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff+0x0001 	# would result unfl?
   13999  1.1.6.2  bouyer 	beq.w		fsglmul_may_unfl	# result may rnd to no unfl
   14000  1.1.6.2  bouyer 	bgt.w		fsglmul_unfl		# result will underflow
   14001  1.1.6.2  bouyer 
   14002  1.1.6.2  bouyer fsglmul_normal:
   14003  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14004  1.1.6.2  bouyer 
   14005  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14006  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14007  1.1.6.2  bouyer 
   14008  1.1.6.2  bouyer 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14009  1.1.6.2  bouyer 
   14010  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14011  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14012  1.1.6.2  bouyer 
   14013  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14014  1.1.6.2  bouyer 
   14015  1.1.6.2  bouyer fsglmul_normal_exit:
   14016  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14017  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   14018  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   14019  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   14020  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14021  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   14022  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14023  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   14024  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14025  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14026  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   14027  1.1.6.2  bouyer 	rts
   14028  1.1.6.2  bouyer 
   14029  1.1.6.2  bouyer fsglmul_ovfl:
   14030  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14031  1.1.6.2  bouyer 
   14032  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14033  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14034  1.1.6.2  bouyer 
   14035  1.1.6.2  bouyer 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14036  1.1.6.2  bouyer 
   14037  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14038  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14039  1.1.6.2  bouyer 
   14040  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14041  1.1.6.2  bouyer 
   14042  1.1.6.2  bouyer fsglmul_ovfl_tst:
   14043  1.1.6.2  bouyer 
   14044  1.1.6.2  bouyer # save setting this until now because this is where fsglmul_may_ovfl may jump in
   14045  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask, USER_FPSR(%a6) # set ovfl/aovfl/ainex
   14046  1.1.6.2  bouyer 
   14047  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   14048  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   14049  1.1.6.2  bouyer 	bne.b		fsglmul_ovfl_ena	# yes
   14050  1.1.6.2  bouyer 
   14051  1.1.6.2  bouyer fsglmul_ovfl_dis:
   14052  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   14053  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   14054  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   14055  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# force prec = ext
   14056  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   14057  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   14058  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   14059  1.1.6.2  bouyer 	rts
   14060  1.1.6.2  bouyer 
   14061  1.1.6.2  bouyer fsglmul_ovfl_ena:
   14062  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   14063  1.1.6.2  bouyer 
   14064  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   14065  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14066  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   14067  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14068  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14069  1.1.6.2  bouyer 	subi.l		&0x6000,%d1		# subtract bias
   14070  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   14071  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   14072  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   14073  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14074  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14075  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14076  1.1.6.2  bouyer 	bra.b		fsglmul_ovfl_dis
   14077  1.1.6.2  bouyer 
   14078  1.1.6.2  bouyer fsglmul_may_ovfl:
   14079  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14080  1.1.6.2  bouyer 
   14081  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14082  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14083  1.1.6.2  bouyer 
   14084  1.1.6.2  bouyer 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14085  1.1.6.2  bouyer 
   14086  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14087  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14088  1.1.6.2  bouyer 
   14089  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14090  1.1.6.2  bouyer 
   14091  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   14092  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
   14093  1.1.6.2  bouyer 	fbge.w		fsglmul_ovfl_tst	# yes; overflow has occurred
   14094  1.1.6.2  bouyer 
   14095  1.1.6.2  bouyer # no, it didn't overflow; we have correct result
   14096  1.1.6.2  bouyer 	bra.w		fsglmul_normal_exit
   14097  1.1.6.2  bouyer 
   14098  1.1.6.2  bouyer fsglmul_unfl:
   14099  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   14100  1.1.6.2  bouyer 
   14101  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14102  1.1.6.2  bouyer 
   14103  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   14104  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14105  1.1.6.2  bouyer 
   14106  1.1.6.2  bouyer 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14107  1.1.6.2  bouyer 
   14108  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14109  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14110  1.1.6.2  bouyer 
   14111  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14112  1.1.6.2  bouyer 
   14113  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   14114  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   14115  1.1.6.2  bouyer 	bne.b		fsglmul_unfl_ena	# yes
   14116  1.1.6.2  bouyer 
   14117  1.1.6.2  bouyer fsglmul_unfl_dis:
   14118  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14119  1.1.6.2  bouyer 
   14120  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   14121  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   14122  1.1.6.2  bouyer 	bsr.l		unf_res4		# calculate default result
   14123  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
   14124  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   14125  1.1.6.2  bouyer 	rts
   14126  1.1.6.2  bouyer 
   14127  1.1.6.2  bouyer #
   14128  1.1.6.2  bouyer # UNFL is enabled.
   14129  1.1.6.2  bouyer #
   14130  1.1.6.2  bouyer fsglmul_unfl_ena:
   14131  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   14132  1.1.6.2  bouyer 
   14133  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14134  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14135  1.1.6.2  bouyer 
   14136  1.1.6.2  bouyer 	fsglmul.x	FP_SCR0(%a6),%fp1	# execute sgl multiply
   14137  1.1.6.2  bouyer 
   14138  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14139  1.1.6.2  bouyer 
   14140  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   14141  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   14142  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14143  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   14144  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14145  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   14146  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14147  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add bias
   14148  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   14149  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   14150  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14151  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14152  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14153  1.1.6.2  bouyer 	bra.w		fsglmul_unfl_dis
   14154  1.1.6.2  bouyer 
   14155  1.1.6.2  bouyer fsglmul_may_unfl:
   14156  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14157  1.1.6.2  bouyer 
   14158  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14159  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14160  1.1.6.2  bouyer 
   14161  1.1.6.2  bouyer 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
   14162  1.1.6.2  bouyer 
   14163  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14164  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14165  1.1.6.2  bouyer 
   14166  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14167  1.1.6.2  bouyer 
   14168  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   14169  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| > 2.b?
   14170  1.1.6.2  bouyer 	fbgt.w		fsglmul_normal_exit	# no; no underflow occurred
   14171  1.1.6.2  bouyer 	fblt.w		fsglmul_unfl		# yes; underflow occurred
   14172  1.1.6.2  bouyer 
   14173  1.1.6.2  bouyer #
   14174  1.1.6.2  bouyer # we still don't know if underflow occurred. result is ~ equal to 2. but,
   14175  1.1.6.2  bouyer # we don't know if the result was an underflow that rounded up to a 2 or
   14176  1.1.6.2  bouyer # a normalized number that rounded down to a 2. so, redo the entire operation
   14177  1.1.6.2  bouyer # using RZ as the rounding mode to see what the pre-rounded result is.
   14178  1.1.6.2  bouyer # this case should be relatively rare.
   14179  1.1.6.2  bouyer #
   14180  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   14181  1.1.6.2  bouyer 
   14182  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   14183  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# keep rnd prec
   14184  1.1.6.2  bouyer 	ori.b		&rz_mode*0x10,%d1	# insert RZ
   14185  1.1.6.2  bouyer 
   14186  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   14187  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14188  1.1.6.2  bouyer 
   14189  1.1.6.2  bouyer 	fsglmul.x	FP_SCR0(%a6),%fp1	# execute sgl multiply
   14190  1.1.6.2  bouyer 
   14191  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14192  1.1.6.2  bouyer 	fabs.x		%fp1			# make absolute value
   14193  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x2		# is |result| < 2.b?
   14194  1.1.6.2  bouyer 	fbge.w		fsglmul_normal_exit	# no; no underflow occurred
   14195  1.1.6.2  bouyer 	bra.w		fsglmul_unfl		# yes, underflow occurred
   14196  1.1.6.2  bouyer 
   14197  1.1.6.2  bouyer ##############################################################################
   14198  1.1.6.2  bouyer 
   14199  1.1.6.2  bouyer #
   14200  1.1.6.2  bouyer # Single Precision Multiply: inputs are not both normalized; what are they?
   14201  1.1.6.2  bouyer #
   14202  1.1.6.2  bouyer fsglmul_not_norm:
   14203  1.1.6.2  bouyer 	mov.w		(tbl_fsglmul_op.b,%pc,%d1.w*2),%d1
   14204  1.1.6.2  bouyer 	jmp		(tbl_fsglmul_op.b,%pc,%d1.w*1)
   14205  1.1.6.2  bouyer 
   14206  1.1.6.2  bouyer 	swbeg		&48
   14207  1.1.6.2  bouyer tbl_fsglmul_op:
   14208  1.1.6.2  bouyer 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x NORM
   14209  1.1.6.2  bouyer 	short		fsglmul_zero		- tbl_fsglmul_op # NORM x ZERO
   14210  1.1.6.2  bouyer 	short		fsglmul_inf_src		- tbl_fsglmul_op # NORM x INF
   14211  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # NORM x QNAN
   14212  1.1.6.2  bouyer 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x DENORM
   14213  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # NORM x SNAN
   14214  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14215  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14216  1.1.6.2  bouyer 
   14217  1.1.6.2  bouyer 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x NORM
   14218  1.1.6.2  bouyer 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x ZERO
   14219  1.1.6.2  bouyer 	short		fsglmul_res_operr	- tbl_fsglmul_op # ZERO x INF
   14220  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # ZERO x QNAN
   14221  1.1.6.2  bouyer 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x DENORM
   14222  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # ZERO x SNAN
   14223  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14224  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14225  1.1.6.2  bouyer 
   14226  1.1.6.2  bouyer 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x NORM
   14227  1.1.6.2  bouyer 	short		fsglmul_res_operr	- tbl_fsglmul_op # INF x ZERO
   14228  1.1.6.2  bouyer 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x INF
   14229  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # INF x QNAN
   14230  1.1.6.2  bouyer 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x DENORM
   14231  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # INF x SNAN
   14232  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14233  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14234  1.1.6.2  bouyer 
   14235  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x NORM
   14236  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x ZERO
   14237  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x INF
   14238  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x QNAN
   14239  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x DENORM
   14240  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # QNAN x SNAN
   14241  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14242  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14243  1.1.6.2  bouyer 
   14244  1.1.6.2  bouyer 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x NORM
   14245  1.1.6.2  bouyer 	short		fsglmul_zero		- tbl_fsglmul_op # NORM x ZERO
   14246  1.1.6.2  bouyer 	short		fsglmul_inf_src		- tbl_fsglmul_op # NORM x INF
   14247  1.1.6.2  bouyer 	short		fsglmul_res_qnan	- tbl_fsglmul_op # NORM x QNAN
   14248  1.1.6.2  bouyer 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x DENORM
   14249  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # NORM x SNAN
   14250  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14251  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14252  1.1.6.2  bouyer 
   14253  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x NORM
   14254  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x ZERO
   14255  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x INF
   14256  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x QNAN
   14257  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x DENORM
   14258  1.1.6.2  bouyer 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x SNAN
   14259  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14260  1.1.6.2  bouyer 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
   14261  1.1.6.2  bouyer 
   14262  1.1.6.2  bouyer fsglmul_res_operr:
   14263  1.1.6.2  bouyer 	bra.l		res_operr
   14264  1.1.6.2  bouyer fsglmul_res_snan:
   14265  1.1.6.2  bouyer 	bra.l		res_snan
   14266  1.1.6.2  bouyer fsglmul_res_qnan:
   14267  1.1.6.2  bouyer 	bra.l		res_qnan
   14268  1.1.6.2  bouyer fsglmul_zero:
   14269  1.1.6.2  bouyer 	bra.l		fmul_zero
   14270  1.1.6.2  bouyer fsglmul_inf_src:
   14271  1.1.6.2  bouyer 	bra.l		fmul_inf_src
   14272  1.1.6.2  bouyer fsglmul_inf_dst:
   14273  1.1.6.2  bouyer 	bra.l		fmul_inf_dst
   14274  1.1.6.2  bouyer 
   14275  1.1.6.2  bouyer #########################################################################
   14276  1.1.6.2  bouyer # XDEF ****************************************************************	#
   14277  1.1.6.2  bouyer # 	fsgldiv(): emulates the fsgldiv instruction			#
   14278  1.1.6.2  bouyer #									#
   14279  1.1.6.2  bouyer # XREF ****************************************************************	#
   14280  1.1.6.2  bouyer #	scale_to_zero_src() - scale src exponent to zero		#
   14281  1.1.6.2  bouyer #	scale_to_zero_dst() - scale dst exponent to zero		#
   14282  1.1.6.2  bouyer #	unf_res4() - return default underflow result for sglop		#
   14283  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   14284  1.1.6.2  bouyer # 	res_qnan() - return QNAN result					#
   14285  1.1.6.2  bouyer # 	res_snan() - return SNAN result					#
   14286  1.1.6.2  bouyer #									#
   14287  1.1.6.2  bouyer # INPUT ***************************************************************	#
   14288  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   14289  1.1.6.2  bouyer #	a1 = pointer to extended precision destination operand		#
   14290  1.1.6.2  bouyer #	d0  rnd prec,mode						#
   14291  1.1.6.2  bouyer #									#
   14292  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   14293  1.1.6.2  bouyer #	fp0 = result							#
   14294  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   14295  1.1.6.2  bouyer #									#
   14296  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   14297  1.1.6.2  bouyer #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   14298  1.1.6.2  bouyer # norms/denorms into ext/sgl/dbl precision.				#
   14299  1.1.6.2  bouyer #	For norms/denorms, scale the exponents such that a divide	#
   14300  1.1.6.2  bouyer # instruction won't cause an exception. Use the regular fsgldiv to	#
   14301  1.1.6.2  bouyer # compute a result. Check if the regular operands would have taken	#
   14302  1.1.6.2  bouyer # an exception. If so, return the default overflow/underflow result	#
   14303  1.1.6.2  bouyer # and return the EXOP if exceptions are enabled. Else, scale the 	#
   14304  1.1.6.2  bouyer # result operand to the proper exponent.				#
   14305  1.1.6.2  bouyer #									#
   14306  1.1.6.2  bouyer #########################################################################
   14307  1.1.6.2  bouyer 
   14308  1.1.6.2  bouyer 	global		fsgldiv
   14309  1.1.6.2  bouyer fsgldiv:
   14310  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   14311  1.1.6.2  bouyer 
   14312  1.1.6.2  bouyer 	clr.w		%d1
   14313  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   14314  1.1.6.2  bouyer 	lsl.b		&0x3,%d1
   14315  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1		# combine src tags
   14316  1.1.6.2  bouyer 
   14317  1.1.6.2  bouyer 	bne.w		fsgldiv_not_norm	# optimize on non-norm input
   14318  1.1.6.2  bouyer 
   14319  1.1.6.2  bouyer #
   14320  1.1.6.2  bouyer # DIVIDE: NORMs and DENORMs ONLY!
   14321  1.1.6.2  bouyer #
   14322  1.1.6.2  bouyer fsgldiv_norm:
   14323  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   14324  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   14325  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   14326  1.1.6.2  bouyer 
   14327  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   14328  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   14329  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   14330  1.1.6.2  bouyer 
   14331  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# calculate scale factor 1
   14332  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save scale factor 1
   14333  1.1.6.2  bouyer 
   14334  1.1.6.2  bouyer 	bsr.l		scale_to_zero_dst	# calculate scale factor 2
   14335  1.1.6.2  bouyer 
   14336  1.1.6.2  bouyer 	neg.l		(%sp)			# S.F. = scale1 - scale2
   14337  1.1.6.2  bouyer 	add.l		%d0,(%sp)
   14338  1.1.6.2  bouyer 
   14339  1.1.6.2  bouyer 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision,mode
   14340  1.1.6.2  bouyer 	lsr.b		&0x6,%d1
   14341  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   14342  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x7ffe
   14343  1.1.6.2  bouyer 	ble.w		fsgldiv_may_ovfl
   14344  1.1.6.2  bouyer 
   14345  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x0000 	# will result underflow?
   14346  1.1.6.2  bouyer 	beq.w		fsgldiv_may_unfl	# maybe
   14347  1.1.6.2  bouyer 	bgt.w		fsgldiv_unfl		# yes; go handle underflow
   14348  1.1.6.2  bouyer 
   14349  1.1.6.2  bouyer fsgldiv_normal:
   14350  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14351  1.1.6.2  bouyer 
   14352  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# save FPCR
   14353  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14354  1.1.6.2  bouyer 
   14355  1.1.6.2  bouyer 	fsgldiv.x	FP_SCR0(%a6),%fp0	# perform sgl divide
   14356  1.1.6.2  bouyer 
   14357  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   14358  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14359  1.1.6.2  bouyer 
   14360  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14361  1.1.6.2  bouyer 
   14362  1.1.6.2  bouyer fsgldiv_normal_exit:
   14363  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store result on stack
   14364  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   14365  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
   14366  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   14367  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14368  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   14369  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14370  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   14371  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14372  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14373  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   14374  1.1.6.2  bouyer 	rts
   14375  1.1.6.2  bouyer 
   14376  1.1.6.2  bouyer fsgldiv_may_ovfl:
   14377  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14378  1.1.6.2  bouyer 
   14379  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14380  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# set FPSR
   14381  1.1.6.2  bouyer 
   14382  1.1.6.2  bouyer 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute divide
   14383  1.1.6.2  bouyer 
   14384  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1
   14385  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr
   14386  1.1.6.2  bouyer 
   14387  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX,N
   14388  1.1.6.2  bouyer 
   14389  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save result to stack
   14390  1.1.6.2  bouyer 	mov.w		(%sp),%d1		# fetch new exponent
   14391  1.1.6.2  bouyer 	add.l		&0xc,%sp		# clear result
   14392  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14393  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14394  1.1.6.2  bouyer 	cmp.l		%d1,&0x7fff		# did divide overflow?
   14395  1.1.6.2  bouyer 	blt.b		fsgldiv_normal_exit
   14396  1.1.6.2  bouyer 
   14397  1.1.6.2  bouyer fsgldiv_ovfl_tst:
   14398  1.1.6.2  bouyer 	or.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
   14399  1.1.6.2  bouyer 
   14400  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   14401  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   14402  1.1.6.2  bouyer 	bne.b		fsgldiv_ovfl_ena	# yes
   14403  1.1.6.2  bouyer 
   14404  1.1.6.2  bouyer fsgldiv_ovfl_dis:
   14405  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6) 	# is result negative
   14406  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   14407  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   14408  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# kill precision
   14409  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   14410  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF if applicable
   14411  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   14412  1.1.6.2  bouyer 	rts
   14413  1.1.6.2  bouyer 
   14414  1.1.6.2  bouyer fsgldiv_ovfl_ena:
   14415  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
   14416  1.1.6.2  bouyer 
   14417  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   14418  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14419  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   14420  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14421  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   14422  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14423  1.1.6.2  bouyer 	subi.l		&0x6000,%d1		# subtract new bias
   14424  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1		# clear ms bit
   14425  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign,new exp
   14426  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14427  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14428  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14429  1.1.6.2  bouyer 	bra.b		fsgldiv_ovfl_dis
   14430  1.1.6.2  bouyer 
   14431  1.1.6.2  bouyer fsgldiv_unfl:
   14432  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   14433  1.1.6.2  bouyer 
   14434  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14435  1.1.6.2  bouyer 
   14436  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   14437  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14438  1.1.6.2  bouyer 
   14439  1.1.6.2  bouyer 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute sgl divide
   14440  1.1.6.2  bouyer 
   14441  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14442  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14443  1.1.6.2  bouyer 
   14444  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14445  1.1.6.2  bouyer 
   14446  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   14447  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   14448  1.1.6.2  bouyer 	bne.b		fsgldiv_unfl_ena	# yes
   14449  1.1.6.2  bouyer 
   14450  1.1.6.2  bouyer fsgldiv_unfl_dis:
   14451  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14452  1.1.6.2  bouyer 
   14453  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   14454  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   14455  1.1.6.2  bouyer 	bsr.l		unf_res4		# calculate default result
   14456  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
   14457  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   14458  1.1.6.2  bouyer 	rts
   14459  1.1.6.2  bouyer 
   14460  1.1.6.2  bouyer #
   14461  1.1.6.2  bouyer # UNFL is enabled.
   14462  1.1.6.2  bouyer #
   14463  1.1.6.2  bouyer fsgldiv_unfl_ena:
   14464  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   14465  1.1.6.2  bouyer 
   14466  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14467  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14468  1.1.6.2  bouyer 
   14469  1.1.6.2  bouyer 	fsgldiv.x	FP_SCR0(%a6),%fp1	# execute sgl divide
   14470  1.1.6.2  bouyer 
   14471  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14472  1.1.6.2  bouyer 
   14473  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   14474  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   14475  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14476  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   14477  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14478  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   14479  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14480  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add bias
   14481  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1		# clear top bit
   14482  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat old sign, new exp
   14483  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14484  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14485  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14486  1.1.6.2  bouyer 	bra.b		fsgldiv_unfl_dis
   14487  1.1.6.2  bouyer 
   14488  1.1.6.2  bouyer #
   14489  1.1.6.2  bouyer # the divide operation MAY underflow:
   14490  1.1.6.2  bouyer #
   14491  1.1.6.2  bouyer fsgldiv_may_unfl:
   14492  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14493  1.1.6.2  bouyer 
   14494  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14495  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14496  1.1.6.2  bouyer 
   14497  1.1.6.2  bouyer 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute sgl divide
   14498  1.1.6.2  bouyer 
   14499  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14500  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14501  1.1.6.2  bouyer 
   14502  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   14503  1.1.6.2  bouyer 
   14504  1.1.6.2  bouyer 	fabs.x		%fp0,%fp1		# make a copy of result
   14505  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x1		# is |result| > 1.b?
   14506  1.1.6.2  bouyer 	fbgt.w		fsgldiv_normal_exit	# no; no underflow occurred
   14507  1.1.6.2  bouyer 	fblt.w		fsgldiv_unfl		# yes; underflow occurred
   14508  1.1.6.2  bouyer 
   14509  1.1.6.2  bouyer #
   14510  1.1.6.2  bouyer # we still don't know if underflow occurred. result is ~ equal to 1. but,
   14511  1.1.6.2  bouyer # we don't know if the result was an underflow that rounded up to a 1
   14512  1.1.6.2  bouyer # or a normalized number that rounded down to a 1. so, redo the entire
   14513  1.1.6.2  bouyer # operation using RZ as the rounding mode to see what the pre-rounded
   14514  1.1.6.2  bouyer # result is. this case should be relatively rare.
   14515  1.1.6.2  bouyer #
   14516  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into %fp1
   14517  1.1.6.2  bouyer 
   14518  1.1.6.2  bouyer 	clr.l		%d1			# clear scratch register
   14519  1.1.6.2  bouyer 	ori.b		&rz_mode*0x10,%d1	# force RZ rnd mode
   14520  1.1.6.2  bouyer 
   14521  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   14522  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14523  1.1.6.2  bouyer 
   14524  1.1.6.2  bouyer 	fsgldiv.x	FP_SCR0(%a6),%fp1	# execute sgl divide
   14525  1.1.6.2  bouyer 
   14526  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14527  1.1.6.2  bouyer 	fabs.x		%fp1			# make absolute value
   14528  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x1		# is |result| < 1.b?
   14529  1.1.6.2  bouyer 	fbge.w		fsgldiv_normal_exit	# no; no underflow occurred
   14530  1.1.6.2  bouyer 	bra.w		fsgldiv_unfl		# yes; underflow occurred
   14531  1.1.6.2  bouyer 
   14532  1.1.6.2  bouyer ############################################################################
   14533  1.1.6.2  bouyer 
   14534  1.1.6.2  bouyer #
   14535  1.1.6.2  bouyer # Divide: inputs are not both normalized; what are they?
   14536  1.1.6.2  bouyer #
   14537  1.1.6.2  bouyer fsgldiv_not_norm:
   14538  1.1.6.2  bouyer 	mov.w		(tbl_fsgldiv_op.b,%pc,%d1.w*2),%d1
   14539  1.1.6.2  bouyer 	jmp		(tbl_fsgldiv_op.b,%pc,%d1.w*1)
   14540  1.1.6.2  bouyer 
   14541  1.1.6.2  bouyer 	swbeg		&48
   14542  1.1.6.2  bouyer tbl_fsgldiv_op:
   14543  1.1.6.2  bouyer 	short		fsgldiv_norm		- tbl_fsgldiv_op # NORM / NORM
   14544  1.1.6.2  bouyer 	short		fsgldiv_inf_load	- tbl_fsgldiv_op # NORM / ZERO
   14545  1.1.6.2  bouyer 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # NORM / INF
   14546  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # NORM / QNAN
   14547  1.1.6.2  bouyer 	short		fsgldiv_norm		- tbl_fsgldiv_op # NORM / DENORM
   14548  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # NORM / SNAN
   14549  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14550  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14551  1.1.6.2  bouyer 
   14552  1.1.6.2  bouyer 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / NORM
   14553  1.1.6.2  bouyer 	short		fsgldiv_res_operr	- tbl_fsgldiv_op # ZERO / ZERO
   14554  1.1.6.2  bouyer 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / INF
   14555  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # ZERO / QNAN
   14556  1.1.6.2  bouyer 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / DENORM
   14557  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # ZERO / SNAN
   14558  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14559  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14560  1.1.6.2  bouyer 
   14561  1.1.6.2  bouyer 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / NORM
   14562  1.1.6.2  bouyer 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / ZERO
   14563  1.1.6.2  bouyer 	short		fsgldiv_res_operr	- tbl_fsgldiv_op # INF / INF
   14564  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # INF / QNAN
   14565  1.1.6.2  bouyer 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / DENORM
   14566  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # INF / SNAN
   14567  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14568  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14569  1.1.6.2  bouyer 
   14570  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / NORM
   14571  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / ZERO
   14572  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / INF
   14573  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / QNAN
   14574  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / DENORM
   14575  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # QNAN / SNAN
   14576  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14577  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14578  1.1.6.2  bouyer 
   14579  1.1.6.2  bouyer 	short		fsgldiv_norm		- tbl_fsgldiv_op # DENORM / NORM
   14580  1.1.6.2  bouyer 	short		fsgldiv_inf_load	- tbl_fsgldiv_op # DENORM / ZERO
   14581  1.1.6.2  bouyer 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # DENORM / INF
   14582  1.1.6.2  bouyer 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # DENORM / QNAN
   14583  1.1.6.2  bouyer 	short		fsgldiv_norm		- tbl_fsgldiv_op # DENORM / DENORM
   14584  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # DENORM / SNAN
   14585  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14586  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14587  1.1.6.2  bouyer 
   14588  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / NORM
   14589  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / ZERO
   14590  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / INF
   14591  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / QNAN
   14592  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / DENORM
   14593  1.1.6.2  bouyer 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / SNAN
   14594  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14595  1.1.6.2  bouyer 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
   14596  1.1.6.2  bouyer 
   14597  1.1.6.2  bouyer fsgldiv_res_qnan:
   14598  1.1.6.2  bouyer 	bra.l		res_qnan
   14599  1.1.6.2  bouyer fsgldiv_res_snan:
   14600  1.1.6.2  bouyer 	bra.l		res_snan
   14601  1.1.6.2  bouyer fsgldiv_res_operr:
   14602  1.1.6.2  bouyer 	bra.l		res_operr
   14603  1.1.6.2  bouyer fsgldiv_inf_load:
   14604  1.1.6.2  bouyer 	bra.l		fdiv_inf_load
   14605  1.1.6.2  bouyer fsgldiv_zero_load:
   14606  1.1.6.2  bouyer 	bra.l		fdiv_zero_load
   14607  1.1.6.2  bouyer fsgldiv_inf_dst:
   14608  1.1.6.2  bouyer 	bra.l		fdiv_inf_dst
   14609  1.1.6.2  bouyer 
   14610  1.1.6.2  bouyer #########################################################################
   14611  1.1.6.2  bouyer # XDEF ****************************************************************	#
   14612  1.1.6.2  bouyer #	fadd(): emulates the fadd instruction				#
   14613  1.1.6.2  bouyer #	fsadd(): emulates the fadd instruction				#
   14614  1.1.6.2  bouyer #	fdadd(): emulates the fdadd instruction				#
   14615  1.1.6.2  bouyer #									#
   14616  1.1.6.2  bouyer # XREF ****************************************************************	#
   14617  1.1.6.2  bouyer # 	addsub_scaler2() - scale the operands so they won't take exc	#
   14618  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   14619  1.1.6.2  bouyer #	unf_res() - return default underflow result			#
   14620  1.1.6.2  bouyer #	res_qnan() - set QNAN result					#
   14621  1.1.6.2  bouyer # 	res_snan() - set SNAN result					#
   14622  1.1.6.2  bouyer #	res_operr() - set OPERR result					#
   14623  1.1.6.2  bouyer #	scale_to_zero_src() - set src operand exponent equal to zero	#
   14624  1.1.6.2  bouyer #	scale_to_zero_dst() - set dst operand exponent equal to zero	#
   14625  1.1.6.2  bouyer #									#
   14626  1.1.6.2  bouyer # INPUT ***************************************************************	#
   14627  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   14628  1.1.6.2  bouyer # 	a1 = pointer to extended precision destination operand		#
   14629  1.1.6.2  bouyer #									#
   14630  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   14631  1.1.6.2  bouyer #	fp0 = result							#
   14632  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   14633  1.1.6.2  bouyer #									#
   14634  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   14635  1.1.6.2  bouyer # 	Handle NANs, infinities, and zeroes as special cases. Divide	#
   14636  1.1.6.2  bouyer # norms into extended, single, and double precision.			#
   14637  1.1.6.2  bouyer #	Do addition after scaling exponents such that exception won't	#
   14638  1.1.6.2  bouyer # occur. Then, check result exponent to see if exception would have	#
   14639  1.1.6.2  bouyer # occurred. If so, return default result and maybe EXOP. Else, insert	#
   14640  1.1.6.2  bouyer # the correct result exponent and return. Set FPSR bits as appropriate.	#
   14641  1.1.6.2  bouyer #									#
   14642  1.1.6.2  bouyer #########################################################################
   14643  1.1.6.2  bouyer 
   14644  1.1.6.2  bouyer 	global		fsadd
   14645  1.1.6.2  bouyer fsadd:
   14646  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   14647  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   14648  1.1.6.2  bouyer 	bra.b		fadd
   14649  1.1.6.2  bouyer 
   14650  1.1.6.2  bouyer 	global		fdadd
   14651  1.1.6.2  bouyer fdadd:
   14652  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   14653  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   14654  1.1.6.2  bouyer 
   14655  1.1.6.2  bouyer 	global		fadd
   14656  1.1.6.2  bouyer fadd:
   14657  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   14658  1.1.6.2  bouyer 
   14659  1.1.6.2  bouyer 	clr.w		%d1
   14660  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   14661  1.1.6.2  bouyer 	lsl.b		&0x3,%d1
   14662  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1		# combine src tags
   14663  1.1.6.2  bouyer 
   14664  1.1.6.2  bouyer 	bne.w		fadd_not_norm		# optimize on non-norm input
   14665  1.1.6.2  bouyer 
   14666  1.1.6.2  bouyer #
   14667  1.1.6.2  bouyer # ADD: norms and denorms
   14668  1.1.6.2  bouyer #
   14669  1.1.6.2  bouyer fadd_norm:
   14670  1.1.6.2  bouyer 	bsr.l		addsub_scaler2		# scale exponents
   14671  1.1.6.2  bouyer 
   14672  1.1.6.2  bouyer fadd_zero_entry:
   14673  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14674  1.1.6.2  bouyer 
   14675  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14676  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14677  1.1.6.2  bouyer 
   14678  1.1.6.2  bouyer 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
   14679  1.1.6.2  bouyer 
   14680  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14681  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# fetch INEX2,N,Z
   14682  1.1.6.2  bouyer 
   14683  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save exc and ccode bits
   14684  1.1.6.2  bouyer 
   14685  1.1.6.2  bouyer 	fbeq.w		fadd_zero_exit		# if result is zero, end now
   14686  1.1.6.2  bouyer 
   14687  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   14688  1.1.6.2  bouyer 
   14689  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save result to stack
   14690  1.1.6.2  bouyer 
   14691  1.1.6.2  bouyer 	mov.w		2+L_SCR3(%a6),%d1
   14692  1.1.6.2  bouyer 	lsr.b		&0x6,%d1
   14693  1.1.6.2  bouyer 
   14694  1.1.6.2  bouyer 	mov.w		(%sp),%d2		# fetch new sign, exp
   14695  1.1.6.2  bouyer 	andi.l		&0x7fff,%d2		# strip sign
   14696  1.1.6.2  bouyer 	sub.l		%d0,%d2			# add scale factor
   14697  1.1.6.2  bouyer 
   14698  1.1.6.2  bouyer 	cmp.l		%d2,(tbl_fadd_ovfl.b,%pc,%d1.w*4) # is it an overflow?
   14699  1.1.6.2  bouyer 	bge.b		fadd_ovfl		# yes
   14700  1.1.6.2  bouyer 
   14701  1.1.6.2  bouyer 	cmp.l		%d2,(tbl_fadd_unfl.b,%pc,%d1.w*4) # is it an underflow?
   14702  1.1.6.2  bouyer 	blt.w		fadd_unfl		# yes
   14703  1.1.6.2  bouyer 	beq.w		fadd_may_unfl		# maybe; go find out
   14704  1.1.6.2  bouyer 
   14705  1.1.6.2  bouyer fadd_normal:
   14706  1.1.6.2  bouyer 	mov.w		(%sp),%d1
   14707  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep sign
   14708  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sign,new exp
   14709  1.1.6.2  bouyer 	mov.w		%d1,(%sp)		# insert new exponent
   14710  1.1.6.2  bouyer 
   14711  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x80		# return result in fp0
   14712  1.1.6.2  bouyer 
   14713  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14714  1.1.6.2  bouyer 	rts
   14715  1.1.6.2  bouyer 
   14716  1.1.6.2  bouyer fadd_zero_exit:
   14717  1.1.6.2  bouyer #	fmov.s		&0x00000000,%fp0	# return zero in fp0
   14718  1.1.6.2  bouyer 	rts
   14719  1.1.6.2  bouyer 
   14720  1.1.6.2  bouyer tbl_fadd_ovfl:
   14721  1.1.6.2  bouyer 	long		0x7fff			# ext ovfl
   14722  1.1.6.2  bouyer 	long		0x407f			# sgl ovfl
   14723  1.1.6.2  bouyer 	long		0x43ff			# dbl ovfl
   14724  1.1.6.2  bouyer 
   14725  1.1.6.2  bouyer tbl_fadd_unfl:
   14726  1.1.6.2  bouyer 	long	        0x0000			# ext unfl
   14727  1.1.6.2  bouyer 	long		0x3f81			# sgl unfl
   14728  1.1.6.2  bouyer 	long		0x3c01			# dbl unfl
   14729  1.1.6.2  bouyer 
   14730  1.1.6.2  bouyer fadd_ovfl:
   14731  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   14732  1.1.6.2  bouyer 
   14733  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   14734  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   14735  1.1.6.2  bouyer 	bne.b		fadd_ovfl_ena		# yes
   14736  1.1.6.2  bouyer 
   14737  1.1.6.2  bouyer 	add.l		&0xc,%sp
   14738  1.1.6.2  bouyer fadd_ovfl_dis:
   14739  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   14740  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   14741  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   14742  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   14743  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   14744  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   14745  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14746  1.1.6.2  bouyer 	rts
   14747  1.1.6.2  bouyer 
   14748  1.1.6.2  bouyer fadd_ovfl_ena:
   14749  1.1.6.2  bouyer 	mov.b		L_SCR3(%a6),%d1
   14750  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# is precision extended?
   14751  1.1.6.2  bouyer 	bne.b		fadd_ovfl_ena_sd	# no; prec = sgl or dbl
   14752  1.1.6.2  bouyer 
   14753  1.1.6.2  bouyer fadd_ovfl_ena_cont:
   14754  1.1.6.2  bouyer 	mov.w		(%sp),%d1
   14755  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep sign
   14756  1.1.6.2  bouyer 	subi.l		&0x6000,%d2		# add extra bias
   14757  1.1.6.2  bouyer 	andi.w		&0x7fff,%d2
   14758  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sign,new exp
   14759  1.1.6.2  bouyer 	mov.w		%d1,(%sp)		# insert new exponent
   14760  1.1.6.2  bouyer 
   14761  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x40		# return EXOP in fp1
   14762  1.1.6.2  bouyer 	bra.b		fadd_ovfl_dis
   14763  1.1.6.2  bouyer 
   14764  1.1.6.2  bouyer fadd_ovfl_ena_sd:
   14765  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14766  1.1.6.2  bouyer 
   14767  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   14768  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# keep rnd mode
   14769  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   14770  1.1.6.2  bouyer 
   14771  1.1.6.2  bouyer 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
   14772  1.1.6.2  bouyer 
   14773  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14774  1.1.6.2  bouyer 
   14775  1.1.6.2  bouyer 	add.l		&0xc,%sp
   14776  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)
   14777  1.1.6.2  bouyer 	bra.b		fadd_ovfl_ena_cont
   14778  1.1.6.2  bouyer 
   14779  1.1.6.2  bouyer fadd_unfl:
   14780  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   14781  1.1.6.2  bouyer 
   14782  1.1.6.2  bouyer 	add.l		&0xc,%sp
   14783  1.1.6.2  bouyer 
   14784  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   14785  1.1.6.2  bouyer 
   14786  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   14787  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14788  1.1.6.2  bouyer 
   14789  1.1.6.2  bouyer 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
   14790  1.1.6.2  bouyer 
   14791  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14792  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   14793  1.1.6.2  bouyer 
   14794  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX,N
   14795  1.1.6.2  bouyer 
   14796  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   14797  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   14798  1.1.6.2  bouyer 	bne.b		fadd_unfl_ena		# yes
   14799  1.1.6.2  bouyer 
   14800  1.1.6.2  bouyer fadd_unfl_dis:
   14801  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   14802  1.1.6.2  bouyer 
   14803  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   14804  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   14805  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   14806  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
   14807  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   14808  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   14809  1.1.6.2  bouyer 	rts
   14810  1.1.6.2  bouyer 
   14811  1.1.6.2  bouyer fadd_unfl_ena:
   14812  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
   14813  1.1.6.2  bouyer 
   14814  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   14815  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# is precision extended?
   14816  1.1.6.2  bouyer 	bne.b		fadd_unfl_ena_sd	# no; sgl or dbl
   14817  1.1.6.2  bouyer 
   14818  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   14819  1.1.6.2  bouyer 
   14820  1.1.6.2  bouyer fadd_unfl_ena_cont:
   14821  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14822  1.1.6.2  bouyer 
   14823  1.1.6.2  bouyer 	fadd.x		FP_SCR0(%a6),%fp1	# execute multiply
   14824  1.1.6.2  bouyer 
   14825  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14826  1.1.6.2  bouyer 
   14827  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
   14828  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   14829  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   14830  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   14831  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   14832  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   14833  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add new bias
   14834  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1		# clear top bit
   14835  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sign,new exp
   14836  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   14837  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   14838  1.1.6.2  bouyer 	bra.w		fadd_unfl_dis
   14839  1.1.6.2  bouyer 
   14840  1.1.6.2  bouyer fadd_unfl_ena_sd:
   14841  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   14842  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# use only rnd mode
   14843  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   14844  1.1.6.2  bouyer 
   14845  1.1.6.2  bouyer 	bra.b		fadd_unfl_ena_cont
   14846  1.1.6.2  bouyer 
   14847  1.1.6.2  bouyer #
   14848  1.1.6.2  bouyer # result is equal to the smallest normalized number in the selected precision
   14849  1.1.6.2  bouyer # if the precision is extended, this result could not have come from an
   14850  1.1.6.2  bouyer # underflow that rounded up.
   14851  1.1.6.2  bouyer #
   14852  1.1.6.2  bouyer fadd_may_unfl:
   14853  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   14854  1.1.6.2  bouyer 	andi.b		&0xc0,%d1
   14855  1.1.6.2  bouyer 	beq.w		fadd_normal		# yes; no underflow occurred
   14856  1.1.6.2  bouyer 
   14857  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d1		# extract hi(man)
   14858  1.1.6.2  bouyer 	cmpi.l		%d1,&0x80000000		# is hi(man) = 0x80000000?
   14859  1.1.6.2  bouyer 	bne.w		fadd_normal		# no; no underflow occurred
   14860  1.1.6.2  bouyer 
   14861  1.1.6.2  bouyer 	tst.l		0x8(%sp)		# is lo(man) = 0x0?
   14862  1.1.6.2  bouyer 	bne.w		fadd_normal		# no; no underflow occurred
   14863  1.1.6.2  bouyer 
   14864  1.1.6.2  bouyer 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
   14865  1.1.6.2  bouyer 	beq.w		fadd_normal		# no; no underflow occurred
   14866  1.1.6.2  bouyer 
   14867  1.1.6.2  bouyer #
   14868  1.1.6.2  bouyer # ok, so now the result has a exponent equal to the smallest normalized
   14869  1.1.6.2  bouyer # exponent for the selected precision. also, the mantissa is equal to
   14870  1.1.6.2  bouyer # 0x8000000000000000 and this mantissa is the result of rounding non-zero
   14871  1.1.6.2  bouyer # g,r,s.
   14872  1.1.6.2  bouyer # now, we must determine whether the pre-rounded result was an underflow
   14873  1.1.6.2  bouyer # rounded "up" or a normalized number rounded "down".
   14874  1.1.6.2  bouyer # so, we do this be re-executing the add using RZ as the rounding mode and
   14875  1.1.6.2  bouyer # seeing if the new result is smaller or equal to the current result.
   14876  1.1.6.2  bouyer #
   14877  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   14878  1.1.6.2  bouyer 
   14879  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   14880  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# keep rnd prec
   14881  1.1.6.2  bouyer 	ori.b		&rz_mode*0x10,%d1	# insert rnd mode
   14882  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   14883  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   14884  1.1.6.2  bouyer 
   14885  1.1.6.2  bouyer 	fadd.x		FP_SCR0(%a6),%fp1	# execute add
   14886  1.1.6.2  bouyer 
   14887  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   14888  1.1.6.2  bouyer 
   14889  1.1.6.2  bouyer 	fabs.x		%fp0			# compare absolute values
   14890  1.1.6.2  bouyer 	fabs.x		%fp1
   14891  1.1.6.2  bouyer 	fcmp.x		%fp0,%fp1		# is first result > second?
   14892  1.1.6.2  bouyer 
   14893  1.1.6.2  bouyer 	fbgt.w		fadd_unfl		# yes; it's an underflow
   14894  1.1.6.2  bouyer 	bra.w		fadd_normal		# no; it's not an underflow
   14895  1.1.6.2  bouyer 
   14896  1.1.6.2  bouyer ##########################################################################
   14897  1.1.6.2  bouyer 
   14898  1.1.6.2  bouyer #
   14899  1.1.6.2  bouyer # Add: inputs are not both normalized; what are they?
   14900  1.1.6.2  bouyer #
   14901  1.1.6.2  bouyer fadd_not_norm:
   14902  1.1.6.2  bouyer 	mov.w		(tbl_fadd_op.b,%pc,%d1.w*2),%d1
   14903  1.1.6.2  bouyer 	jmp		(tbl_fadd_op.b,%pc,%d1.w*1)
   14904  1.1.6.2  bouyer 
   14905  1.1.6.2  bouyer 	swbeg		&48
   14906  1.1.6.2  bouyer tbl_fadd_op:
   14907  1.1.6.2  bouyer 	short		fadd_norm	- tbl_fadd_op # NORM + NORM
   14908  1.1.6.2  bouyer 	short		fadd_zero_src	- tbl_fadd_op # NORM + ZERO
   14909  1.1.6.2  bouyer 	short		fadd_inf_src	- tbl_fadd_op # NORM + INF
   14910  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14911  1.1.6.2  bouyer 	short		fadd_norm	- tbl_fadd_op # NORM + DENORM
   14912  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14913  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14914  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14915  1.1.6.2  bouyer 
   14916  1.1.6.2  bouyer 	short		fadd_zero_dst	- tbl_fadd_op # ZERO + NORM
   14917  1.1.6.2  bouyer 	short		fadd_zero_2	- tbl_fadd_op # ZERO + ZERO
   14918  1.1.6.2  bouyer 	short		fadd_inf_src	- tbl_fadd_op # ZERO + INF
   14919  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14920  1.1.6.2  bouyer 	short		fadd_zero_dst	- tbl_fadd_op # ZERO + DENORM
   14921  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14922  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14923  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14924  1.1.6.2  bouyer 
   14925  1.1.6.2  bouyer 	short		fadd_inf_dst	- tbl_fadd_op # INF + NORM
   14926  1.1.6.2  bouyer 	short		fadd_inf_dst	- tbl_fadd_op # INF + ZERO
   14927  1.1.6.2  bouyer 	short		fadd_inf_2	- tbl_fadd_op # INF + INF
   14928  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14929  1.1.6.2  bouyer 	short		fadd_inf_dst	- tbl_fadd_op # INF + DENORM
   14930  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14931  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14932  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14933  1.1.6.2  bouyer 
   14934  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + NORM
   14935  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + ZERO
   14936  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + INF
   14937  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + QNAN
   14938  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + DENORM
   14939  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # QNAN + SNAN
   14940  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14941  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14942  1.1.6.2  bouyer 
   14943  1.1.6.2  bouyer 	short		fadd_norm	- tbl_fadd_op # DENORM + NORM
   14944  1.1.6.2  bouyer 	short		fadd_zero_src	- tbl_fadd_op # DENORM + ZERO
   14945  1.1.6.2  bouyer 	short		fadd_inf_src	- tbl_fadd_op # DENORM + INF
   14946  1.1.6.2  bouyer 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
   14947  1.1.6.2  bouyer 	short		fadd_norm	- tbl_fadd_op # DENORM + DENORM
   14948  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
   14949  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14950  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14951  1.1.6.2  bouyer 
   14952  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # SNAN + NORM
   14953  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # SNAN + ZERO
   14954  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # SNAN + INF
   14955  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # SNAN + QNAN
   14956  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # SNAN + DENORM
   14957  1.1.6.2  bouyer 	short		fadd_res_snan	- tbl_fadd_op # SNAN + SNAN
   14958  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14959  1.1.6.2  bouyer 	short		tbl_fadd_op	- tbl_fadd_op #
   14960  1.1.6.2  bouyer 
   14961  1.1.6.2  bouyer fadd_res_qnan:
   14962  1.1.6.2  bouyer 	bra.l		res_qnan
   14963  1.1.6.2  bouyer fadd_res_snan:
   14964  1.1.6.2  bouyer 	bra.l		res_snan
   14965  1.1.6.2  bouyer 
   14966  1.1.6.2  bouyer #
   14967  1.1.6.2  bouyer # both operands are ZEROes
   14968  1.1.6.2  bouyer #
   14969  1.1.6.2  bouyer fadd_zero_2:
   14970  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# are the signs opposite
   14971  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   14972  1.1.6.2  bouyer 	eor.b		%d0,%d1
   14973  1.1.6.2  bouyer 	bmi.w		fadd_zero_2_chk_rm	# weed out (-ZERO)+(+ZERO)
   14974  1.1.6.2  bouyer 
   14975  1.1.6.2  bouyer # the signs are the same. so determine whether they are positive or negative
   14976  1.1.6.2  bouyer # and return the appropriately signed zero.
   14977  1.1.6.2  bouyer 	tst.b		%d0			# are ZEROes positive or negative?
   14978  1.1.6.2  bouyer 	bmi.b		fadd_zero_rm		# negative
   14979  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# return +ZERO
   14980  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   14981  1.1.6.2  bouyer 	rts
   14982  1.1.6.2  bouyer 
   14983  1.1.6.2  bouyer #
   14984  1.1.6.2  bouyer # the ZEROes have opposite signs:
   14985  1.1.6.2  bouyer # - therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
   14986  1.1.6.2  bouyer # - -ZERO is returned in the case of RM.
   14987  1.1.6.2  bouyer #
   14988  1.1.6.2  bouyer fadd_zero_2_chk_rm:
   14989  1.1.6.2  bouyer 	mov.b		3+L_SCR3(%a6),%d1
   14990  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# extract rnd mode
   14991  1.1.6.2  bouyer 	cmpi.b		%d1,&rm_mode*0x10	# is rnd mode == RM?
   14992  1.1.6.2  bouyer 	beq.b		fadd_zero_rm		# yes
   14993  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# return +ZERO
   14994  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   14995  1.1.6.2  bouyer 	rts
   14996  1.1.6.2  bouyer 
   14997  1.1.6.2  bouyer fadd_zero_rm:
   14998  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# return -ZERO
   14999  1.1.6.2  bouyer 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set NEG/Z
   15000  1.1.6.2  bouyer 	rts
   15001  1.1.6.2  bouyer 
   15002  1.1.6.2  bouyer #
   15003  1.1.6.2  bouyer # one operand is a ZERO and the other is a DENORM or NORM. scale
   15004  1.1.6.2  bouyer # the DENORM or NORM and jump to the regular fadd routine.
   15005  1.1.6.2  bouyer #
   15006  1.1.6.2  bouyer fadd_zero_dst:
   15007  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15008  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15009  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15010  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# scale the operand
   15011  1.1.6.2  bouyer 	clr.w		FP_SCR1_EX(%a6)
   15012  1.1.6.2  bouyer 	clr.l		FP_SCR1_HI(%a6)
   15013  1.1.6.2  bouyer 	clr.l		FP_SCR1_LO(%a6)
   15014  1.1.6.2  bouyer 	bra.w		fadd_zero_entry		# go execute fadd
   15015  1.1.6.2  bouyer 
   15016  1.1.6.2  bouyer fadd_zero_src:
   15017  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   15018  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   15019  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   15020  1.1.6.2  bouyer 	bsr.l		scale_to_zero_dst	# scale the operand
   15021  1.1.6.2  bouyer 	clr.w		FP_SCR0_EX(%a6)
   15022  1.1.6.2  bouyer 	clr.l		FP_SCR0_HI(%a6)
   15023  1.1.6.2  bouyer 	clr.l		FP_SCR0_LO(%a6)
   15024  1.1.6.2  bouyer 	bra.w		fadd_zero_entry		# go execute fadd
   15025  1.1.6.2  bouyer 
   15026  1.1.6.2  bouyer #
   15027  1.1.6.2  bouyer # both operands are INFs. an OPERR will result if the INFs have
   15028  1.1.6.2  bouyer # different signs. else, an INF of the same sign is returned
   15029  1.1.6.2  bouyer #
   15030  1.1.6.2  bouyer fadd_inf_2:
   15031  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   15032  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   15033  1.1.6.2  bouyer 	eor.b		%d1,%d0
   15034  1.1.6.2  bouyer 	bmi.l		res_operr		# weed out (-INF)+(+INF)
   15035  1.1.6.2  bouyer 
   15036  1.1.6.2  bouyer # ok, so it's not an OPERR. but, we do have to remember to return the
   15037  1.1.6.2  bouyer # src INF since that's where the 881/882 gets the j-bit from...
   15038  1.1.6.2  bouyer 
   15039  1.1.6.2  bouyer #
   15040  1.1.6.2  bouyer # operands are INF and one of {ZERO, INF, DENORM, NORM}
   15041  1.1.6.2  bouyer #
   15042  1.1.6.2  bouyer fadd_inf_src:
   15043  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return src INF
   15044  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is INF positive?
   15045  1.1.6.2  bouyer 	bpl.b		fadd_inf_done		# yes; we're done
   15046  1.1.6.2  bouyer 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15047  1.1.6.2  bouyer 	rts
   15048  1.1.6.2  bouyer 
   15049  1.1.6.2  bouyer #
   15050  1.1.6.2  bouyer # operands are INF and one of {ZERO, INF, DENORM, NORM}
   15051  1.1.6.2  bouyer #
   15052  1.1.6.2  bouyer fadd_inf_dst:
   15053  1.1.6.2  bouyer 	fmovm.x		DST(%a1),&0x80		# return dst INF
   15054  1.1.6.2  bouyer 	tst.b		DST_EX(%a1)		# is INF positive?
   15055  1.1.6.2  bouyer 	bpl.b		fadd_inf_done		# yes; we're done
   15056  1.1.6.2  bouyer 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15057  1.1.6.2  bouyer 	rts
   15058  1.1.6.2  bouyer 
   15059  1.1.6.2  bouyer fadd_inf_done:
   15060  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6) # set INF
   15061  1.1.6.2  bouyer 	rts
   15062  1.1.6.2  bouyer 
   15063  1.1.6.2  bouyer #########################################################################
   15064  1.1.6.2  bouyer # XDEF ****************************************************************	#
   15065  1.1.6.2  bouyer #	fsub(): emulates the fsub instruction				#
   15066  1.1.6.2  bouyer #	fssub(): emulates the fssub instruction				#
   15067  1.1.6.2  bouyer #	fdsub(): emulates the fdsub instruction				#
   15068  1.1.6.2  bouyer #									#
   15069  1.1.6.2  bouyer # XREF ****************************************************************	#
   15070  1.1.6.2  bouyer # 	addsub_scaler2() - scale the operands so they won't take exc	#
   15071  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   15072  1.1.6.2  bouyer #	unf_res() - return default underflow result			#
   15073  1.1.6.2  bouyer #	res_qnan() - set QNAN result					#
   15074  1.1.6.2  bouyer # 	res_snan() - set SNAN result					#
   15075  1.1.6.2  bouyer #	res_operr() - set OPERR result					#
   15076  1.1.6.2  bouyer #	scale_to_zero_src() - set src operand exponent equal to zero	#
   15077  1.1.6.2  bouyer #	scale_to_zero_dst() - set dst operand exponent equal to zero	#
   15078  1.1.6.2  bouyer #									#
   15079  1.1.6.2  bouyer # INPUT ***************************************************************	#
   15080  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   15081  1.1.6.2  bouyer # 	a1 = pointer to extended precision destination operand		#
   15082  1.1.6.2  bouyer #									#
   15083  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   15084  1.1.6.2  bouyer #	fp0 = result							#
   15085  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   15086  1.1.6.2  bouyer #									#
   15087  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   15088  1.1.6.2  bouyer # 	Handle NANs, infinities, and zeroes as special cases. Divide	#
   15089  1.1.6.2  bouyer # norms into extended, single, and double precision.			#
   15090  1.1.6.2  bouyer #	Do subtraction after scaling exponents such that exception won't#
   15091  1.1.6.2  bouyer # occur. Then, check result exponent to see if exception would have	#
   15092  1.1.6.2  bouyer # occurred. If so, return default result and maybe EXOP. Else, insert	#
   15093  1.1.6.2  bouyer # the correct result exponent and return. Set FPSR bits as appropriate.	#
   15094  1.1.6.2  bouyer #									#
   15095  1.1.6.2  bouyer #########################################################################
   15096  1.1.6.2  bouyer 
   15097  1.1.6.2  bouyer 	global		fssub
   15098  1.1.6.2  bouyer fssub:
   15099  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   15100  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   15101  1.1.6.2  bouyer 	bra.b		fsub
   15102  1.1.6.2  bouyer 
   15103  1.1.6.2  bouyer 	global		fdsub
   15104  1.1.6.2  bouyer fdsub:
   15105  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   15106  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   15107  1.1.6.2  bouyer 
   15108  1.1.6.2  bouyer 	global		fsub
   15109  1.1.6.2  bouyer fsub:
   15110  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   15111  1.1.6.2  bouyer 
   15112  1.1.6.2  bouyer 	clr.w		%d1
   15113  1.1.6.2  bouyer 	mov.b		DTAG(%a6),%d1
   15114  1.1.6.2  bouyer 	lsl.b		&0x3,%d1
   15115  1.1.6.2  bouyer 	or.b		STAG(%a6),%d1		# combine src tags
   15116  1.1.6.2  bouyer 
   15117  1.1.6.2  bouyer 	bne.w		fsub_not_norm		# optimize on non-norm input
   15118  1.1.6.2  bouyer 
   15119  1.1.6.2  bouyer #
   15120  1.1.6.2  bouyer # SUB: norms and denorms
   15121  1.1.6.2  bouyer #
   15122  1.1.6.2  bouyer fsub_norm:
   15123  1.1.6.2  bouyer 	bsr.l		addsub_scaler2		# scale exponents
   15124  1.1.6.2  bouyer 
   15125  1.1.6.2  bouyer fsub_zero_entry:
   15126  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   15127  1.1.6.2  bouyer 
   15128  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15129  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15130  1.1.6.2  bouyer 
   15131  1.1.6.2  bouyer 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
   15132  1.1.6.2  bouyer 
   15133  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15134  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# fetch INEX2, N, Z
   15135  1.1.6.2  bouyer 
   15136  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save exc and ccode bits
   15137  1.1.6.2  bouyer 
   15138  1.1.6.2  bouyer 	fbeq.w		fsub_zero_exit		# if result zero, end now
   15139  1.1.6.2  bouyer 
   15140  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   15141  1.1.6.2  bouyer 
   15142  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)		# save result to stack
   15143  1.1.6.2  bouyer 
   15144  1.1.6.2  bouyer 	mov.w		2+L_SCR3(%a6),%d1
   15145  1.1.6.2  bouyer 	lsr.b		&0x6,%d1
   15146  1.1.6.2  bouyer 
   15147  1.1.6.2  bouyer 	mov.w		(%sp),%d2		# fetch new exponent
   15148  1.1.6.2  bouyer 	andi.l		&0x7fff,%d2		# strip sign
   15149  1.1.6.2  bouyer 	sub.l		%d0,%d2			# add scale factor
   15150  1.1.6.2  bouyer 
   15151  1.1.6.2  bouyer 	cmp.l		%d2,(tbl_fsub_ovfl.b,%pc,%d1.w*4) # is it an overflow?
   15152  1.1.6.2  bouyer 	bge.b		fsub_ovfl		# yes
   15153  1.1.6.2  bouyer 
   15154  1.1.6.2  bouyer 	cmp.l		%d2,(tbl_fsub_unfl.b,%pc,%d1.w*4) # is it an underflow?
   15155  1.1.6.2  bouyer 	blt.w		fsub_unfl		# yes
   15156  1.1.6.2  bouyer 	beq.w		fsub_may_unfl		# maybe; go find out
   15157  1.1.6.2  bouyer 
   15158  1.1.6.2  bouyer fsub_normal:
   15159  1.1.6.2  bouyer 	mov.w		(%sp),%d1
   15160  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep sign
   15161  1.1.6.2  bouyer 	or.w		%d2,%d1			# insert new exponent
   15162  1.1.6.2  bouyer 	mov.w		%d1,(%sp)		# insert new exponent
   15163  1.1.6.2  bouyer 
   15164  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x80		# return result in fp0
   15165  1.1.6.2  bouyer 
   15166  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   15167  1.1.6.2  bouyer 	rts
   15168  1.1.6.2  bouyer 
   15169  1.1.6.2  bouyer fsub_zero_exit:
   15170  1.1.6.2  bouyer #	fmov.s		&0x00000000,%fp0	# return zero in fp0
   15171  1.1.6.2  bouyer 	rts
   15172  1.1.6.2  bouyer 
   15173  1.1.6.2  bouyer tbl_fsub_ovfl:
   15174  1.1.6.2  bouyer 	long		0x7fff			# ext ovfl
   15175  1.1.6.2  bouyer 	long		0x407f			# sgl ovfl
   15176  1.1.6.2  bouyer 	long		0x43ff			# dbl ovfl
   15177  1.1.6.2  bouyer 
   15178  1.1.6.2  bouyer tbl_fsub_unfl:
   15179  1.1.6.2  bouyer 	long	        0x0000			# ext unfl
   15180  1.1.6.2  bouyer 	long		0x3f81			# sgl unfl
   15181  1.1.6.2  bouyer 	long		0x3c01			# dbl unfl
   15182  1.1.6.2  bouyer 
   15183  1.1.6.2  bouyer fsub_ovfl:
   15184  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   15185  1.1.6.2  bouyer 
   15186  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   15187  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   15188  1.1.6.2  bouyer 	bne.b		fsub_ovfl_ena		# yes
   15189  1.1.6.2  bouyer 
   15190  1.1.6.2  bouyer 	add.l		&0xc,%sp
   15191  1.1.6.2  bouyer fsub_ovfl_dis:
   15192  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   15193  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   15194  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
   15195  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   15196  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   15197  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   15198  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   15199  1.1.6.2  bouyer 	rts
   15200  1.1.6.2  bouyer 
   15201  1.1.6.2  bouyer fsub_ovfl_ena:
   15202  1.1.6.2  bouyer 	mov.b		L_SCR3(%a6),%d1
   15203  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# is precision extended?
   15204  1.1.6.2  bouyer 	bne.b		fsub_ovfl_ena_sd	# no
   15205  1.1.6.2  bouyer 
   15206  1.1.6.2  bouyer fsub_ovfl_ena_cont:
   15207  1.1.6.2  bouyer 	mov.w		(%sp),%d1		# fetch {sgn,exp}
   15208  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep sign
   15209  1.1.6.2  bouyer 	subi.l		&0x6000,%d2		# subtract new bias
   15210  1.1.6.2  bouyer 	andi.w		&0x7fff,%d2		# clear top bit
   15211  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sign,exp
   15212  1.1.6.2  bouyer 	mov.w		%d1,(%sp)		# insert new exponent
   15213  1.1.6.2  bouyer 
   15214  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x40		# return EXOP in fp1
   15215  1.1.6.2  bouyer 	bra.b		fsub_ovfl_dis
   15216  1.1.6.2  bouyer 
   15217  1.1.6.2  bouyer fsub_ovfl_ena_sd:
   15218  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   15219  1.1.6.2  bouyer 
   15220  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   15221  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# clear rnd prec
   15222  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   15223  1.1.6.2  bouyer 
   15224  1.1.6.2  bouyer 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
   15225  1.1.6.2  bouyer 
   15226  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15227  1.1.6.2  bouyer 
   15228  1.1.6.2  bouyer 	add.l		&0xc,%sp
   15229  1.1.6.2  bouyer 	fmovm.x		&0x01,-(%sp)
   15230  1.1.6.2  bouyer 	bra.b		fsub_ovfl_ena_cont
   15231  1.1.6.2  bouyer 
   15232  1.1.6.2  bouyer fsub_unfl:
   15233  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   15234  1.1.6.2  bouyer 
   15235  1.1.6.2  bouyer 	add.l		&0xc,%sp
   15236  1.1.6.2  bouyer 
   15237  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
   15238  1.1.6.2  bouyer 
   15239  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   15240  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15241  1.1.6.2  bouyer 
   15242  1.1.6.2  bouyer 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
   15243  1.1.6.2  bouyer 
   15244  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15245  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   15246  1.1.6.2  bouyer 
   15247  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)
   15248  1.1.6.2  bouyer 
   15249  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   15250  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   15251  1.1.6.2  bouyer 	bne.b		fsub_unfl_ena		# yes
   15252  1.1.6.2  bouyer 
   15253  1.1.6.2  bouyer fsub_unfl_dis:
   15254  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   15255  1.1.6.2  bouyer 
   15256  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   15257  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   15258  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   15259  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# 'Z' may have been set
   15260  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   15261  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   15262  1.1.6.2  bouyer 	rts
   15263  1.1.6.2  bouyer 
   15264  1.1.6.2  bouyer fsub_unfl_ena:
   15265  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40
   15266  1.1.6.2  bouyer 
   15267  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   15268  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# is precision extended?
   15269  1.1.6.2  bouyer 	bne.b		fsub_unfl_ena_sd	# no
   15270  1.1.6.2  bouyer 
   15271  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15272  1.1.6.2  bouyer 
   15273  1.1.6.2  bouyer fsub_unfl_ena_cont:
   15274  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15275  1.1.6.2  bouyer 
   15276  1.1.6.2  bouyer 	fsub.x		FP_SCR0(%a6),%fp1	# execute subtract
   15277  1.1.6.2  bouyer 
   15278  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15279  1.1.6.2  bouyer 
   15280  1.1.6.2  bouyer 	fmovm.x		&0x40,FP_SCR0(%a6)	# store result to stack
   15281  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   15282  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   15283  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   15284  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   15285  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   15286  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# subtract new bias
   15287  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1		# clear top bit
   15288  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sgn,exp
   15289  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   15290  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   15291  1.1.6.2  bouyer 	bra.w		fsub_unfl_dis
   15292  1.1.6.2  bouyer 
   15293  1.1.6.2  bouyer fsub_unfl_ena_sd:
   15294  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   15295  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# clear rnd prec
   15296  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   15297  1.1.6.2  bouyer 
   15298  1.1.6.2  bouyer 	bra.b		fsub_unfl_ena_cont
   15299  1.1.6.2  bouyer 
   15300  1.1.6.2  bouyer #
   15301  1.1.6.2  bouyer # result is equal to the smallest normalized number in the selected precision
   15302  1.1.6.2  bouyer # if the precision is extended, this result could not have come from an
   15303  1.1.6.2  bouyer # underflow that rounded up.
   15304  1.1.6.2  bouyer #
   15305  1.1.6.2  bouyer fsub_may_unfl:
   15306  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   15307  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# fetch rnd prec
   15308  1.1.6.2  bouyer 	beq.w		fsub_normal		# yes; no underflow occurred
   15309  1.1.6.2  bouyer 
   15310  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d1
   15311  1.1.6.2  bouyer 	cmpi.l		%d1,&0x80000000		# is hi(man) = 0x80000000?
   15312  1.1.6.2  bouyer 	bne.w		fsub_normal		# no; no underflow occurred
   15313  1.1.6.2  bouyer 
   15314  1.1.6.2  bouyer 	tst.l		0x8(%sp)		# is lo(man) = 0x0?
   15315  1.1.6.2  bouyer 	bne.w		fsub_normal		# no; no underflow occurred
   15316  1.1.6.2  bouyer 
   15317  1.1.6.2  bouyer 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
   15318  1.1.6.2  bouyer 	beq.w		fsub_normal		# no; no underflow occurred
   15319  1.1.6.2  bouyer 
   15320  1.1.6.2  bouyer #
   15321  1.1.6.2  bouyer # ok, so now the result has a exponent equal to the smallest normalized
   15322  1.1.6.2  bouyer # exponent for the selected precision. also, the mantissa is equal to
   15323  1.1.6.2  bouyer # 0x8000000000000000 and this mantissa is the result of rounding non-zero
   15324  1.1.6.2  bouyer # g,r,s.
   15325  1.1.6.2  bouyer # now, we must determine whether the pre-rounded result was an underflow
   15326  1.1.6.2  bouyer # rounded "up" or a normalized number rounded "down".
   15327  1.1.6.2  bouyer # so, we do this be re-executing the add using RZ as the rounding mode and
   15328  1.1.6.2  bouyer # seeing if the new result is smaller or equal to the current result.
   15329  1.1.6.2  bouyer #
   15330  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
   15331  1.1.6.2  bouyer 
   15332  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1
   15333  1.1.6.2  bouyer 	andi.b		&0xc0,%d1		# keep rnd prec
   15334  1.1.6.2  bouyer 	ori.b		&rz_mode*0x10,%d1	# insert rnd mode
   15335  1.1.6.2  bouyer 	fmov.l		%d1,%fpcr		# set FPCR
   15336  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15337  1.1.6.2  bouyer 
   15338  1.1.6.2  bouyer 	fsub.x		FP_SCR0(%a6),%fp1	# execute subtract
   15339  1.1.6.2  bouyer 
   15340  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15341  1.1.6.2  bouyer 
   15342  1.1.6.2  bouyer 	fabs.x		%fp0			# compare absolute values
   15343  1.1.6.2  bouyer 	fabs.x		%fp1
   15344  1.1.6.2  bouyer 	fcmp.x		%fp0,%fp1		# is first result > second?
   15345  1.1.6.2  bouyer 
   15346  1.1.6.2  bouyer 	fbgt.w		fsub_unfl		# yes; it's an underflow
   15347  1.1.6.2  bouyer 	bra.w		fsub_normal		# no; it's not an underflow
   15348  1.1.6.2  bouyer 
   15349  1.1.6.2  bouyer ##########################################################################
   15350  1.1.6.2  bouyer 
   15351  1.1.6.2  bouyer #
   15352  1.1.6.2  bouyer # Sub: inputs are not both normalized; what are they?
   15353  1.1.6.2  bouyer #
   15354  1.1.6.2  bouyer fsub_not_norm:
   15355  1.1.6.2  bouyer 	mov.w		(tbl_fsub_op.b,%pc,%d1.w*2),%d1
   15356  1.1.6.2  bouyer 	jmp		(tbl_fsub_op.b,%pc,%d1.w*1)
   15357  1.1.6.2  bouyer 
   15358  1.1.6.2  bouyer 	swbeg		&48
   15359  1.1.6.2  bouyer tbl_fsub_op:
   15360  1.1.6.2  bouyer 	short		fsub_norm	- tbl_fsub_op # NORM - NORM
   15361  1.1.6.2  bouyer 	short		fsub_zero_src	- tbl_fsub_op # NORM - ZERO
   15362  1.1.6.2  bouyer 	short		fsub_inf_src	- tbl_fsub_op # NORM - INF
   15363  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15364  1.1.6.2  bouyer 	short		fsub_norm	- tbl_fsub_op # NORM - DENORM
   15365  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15366  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15367  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15368  1.1.6.2  bouyer 
   15369  1.1.6.2  bouyer 	short		fsub_zero_dst	- tbl_fsub_op # ZERO - NORM
   15370  1.1.6.2  bouyer 	short		fsub_zero_2	- tbl_fsub_op # ZERO - ZERO
   15371  1.1.6.2  bouyer 	short		fsub_inf_src	- tbl_fsub_op # ZERO - INF
   15372  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15373  1.1.6.2  bouyer 	short		fsub_zero_dst	- tbl_fsub_op # ZERO - DENORM
   15374  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15375  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15376  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15377  1.1.6.2  bouyer 
   15378  1.1.6.2  bouyer 	short		fsub_inf_dst	- tbl_fsub_op # INF - NORM
   15379  1.1.6.2  bouyer 	short		fsub_inf_dst	- tbl_fsub_op # INF - ZERO
   15380  1.1.6.2  bouyer 	short		fsub_inf_2	- tbl_fsub_op # INF - INF
   15381  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15382  1.1.6.2  bouyer 	short		fsub_inf_dst	- tbl_fsub_op # INF - DENORM
   15383  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15384  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15385  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15386  1.1.6.2  bouyer 
   15387  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - NORM
   15388  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - ZERO
   15389  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - INF
   15390  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - QNAN
   15391  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - DENORM
   15392  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # QNAN - SNAN
   15393  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15394  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15395  1.1.6.2  bouyer 
   15396  1.1.6.2  bouyer 	short		fsub_norm	- tbl_fsub_op # DENORM - NORM
   15397  1.1.6.2  bouyer 	short		fsub_zero_src	- tbl_fsub_op # DENORM - ZERO
   15398  1.1.6.2  bouyer 	short		fsub_inf_src	- tbl_fsub_op # DENORM - INF
   15399  1.1.6.2  bouyer 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
   15400  1.1.6.2  bouyer 	short		fsub_norm	- tbl_fsub_op # DENORM - DENORM
   15401  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
   15402  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15403  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15404  1.1.6.2  bouyer 
   15405  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # SNAN - NORM
   15406  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # SNAN - ZERO
   15407  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # SNAN - INF
   15408  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # SNAN - QNAN
   15409  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # SNAN - DENORM
   15410  1.1.6.2  bouyer 	short		fsub_res_snan	- tbl_fsub_op # SNAN - SNAN
   15411  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15412  1.1.6.2  bouyer 	short		tbl_fsub_op	- tbl_fsub_op #
   15413  1.1.6.2  bouyer 
   15414  1.1.6.2  bouyer fsub_res_qnan:
   15415  1.1.6.2  bouyer 	bra.l		res_qnan
   15416  1.1.6.2  bouyer fsub_res_snan:
   15417  1.1.6.2  bouyer 	bra.l		res_snan
   15418  1.1.6.2  bouyer 
   15419  1.1.6.2  bouyer #
   15420  1.1.6.2  bouyer # both operands are ZEROes
   15421  1.1.6.2  bouyer #
   15422  1.1.6.2  bouyer fsub_zero_2:
   15423  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0
   15424  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   15425  1.1.6.2  bouyer 	eor.b		%d1,%d0
   15426  1.1.6.2  bouyer 	bpl.b		fsub_zero_2_chk_rm
   15427  1.1.6.2  bouyer 
   15428  1.1.6.2  bouyer # the signs are opposite, so, return a ZERO w/ the sign of the dst ZERO
   15429  1.1.6.2  bouyer 	tst.b		%d0			# is dst negative?
   15430  1.1.6.2  bouyer 	bmi.b		fsub_zero_2_rm		# yes
   15431  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# no; return +ZERO
   15432  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   15433  1.1.6.2  bouyer 	rts
   15434  1.1.6.2  bouyer 
   15435  1.1.6.2  bouyer #
   15436  1.1.6.2  bouyer # the ZEROes have the same signs:
   15437  1.1.6.2  bouyer # - therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
   15438  1.1.6.2  bouyer # - -ZERO is returned in the case of RM.
   15439  1.1.6.2  bouyer #
   15440  1.1.6.2  bouyer fsub_zero_2_chk_rm:
   15441  1.1.6.2  bouyer 	mov.b		3+L_SCR3(%a6),%d1
   15442  1.1.6.2  bouyer 	andi.b		&0x30,%d1		# extract rnd mode
   15443  1.1.6.2  bouyer 	cmpi.b		%d1,&rm_mode*0x10	# is rnd mode = RM?
   15444  1.1.6.2  bouyer 	beq.b		fsub_zero_2_rm		# yes
   15445  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# no; return +ZERO
   15446  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
   15447  1.1.6.2  bouyer 	rts
   15448  1.1.6.2  bouyer 
   15449  1.1.6.2  bouyer fsub_zero_2_rm:
   15450  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# return -ZERO
   15451  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set Z/NEG
   15452  1.1.6.2  bouyer 	rts
   15453  1.1.6.2  bouyer 
   15454  1.1.6.2  bouyer #
   15455  1.1.6.2  bouyer # one operand is a ZERO and the other is a DENORM or a NORM.
   15456  1.1.6.2  bouyer # scale the DENORM or NORM and jump to the regular fsub routine.
   15457  1.1.6.2  bouyer #
   15458  1.1.6.2  bouyer fsub_zero_dst:
   15459  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15460  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15461  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15462  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src	# scale the operand
   15463  1.1.6.2  bouyer 	clr.w		FP_SCR1_EX(%a6)
   15464  1.1.6.2  bouyer 	clr.l		FP_SCR1_HI(%a6)
   15465  1.1.6.2  bouyer 	clr.l		FP_SCR1_LO(%a6)
   15466  1.1.6.2  bouyer 	bra.w		fsub_zero_entry		# go execute fsub
   15467  1.1.6.2  bouyer 
   15468  1.1.6.2  bouyer fsub_zero_src:
   15469  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
   15470  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   15471  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   15472  1.1.6.2  bouyer 	bsr.l		scale_to_zero_dst	# scale the operand
   15473  1.1.6.2  bouyer 	clr.w		FP_SCR0_EX(%a6)
   15474  1.1.6.2  bouyer 	clr.l		FP_SCR0_HI(%a6)
   15475  1.1.6.2  bouyer 	clr.l		FP_SCR0_LO(%a6)
   15476  1.1.6.2  bouyer 	bra.w		fsub_zero_entry		# go execute fsub
   15477  1.1.6.2  bouyer 
   15478  1.1.6.2  bouyer #
   15479  1.1.6.2  bouyer # both operands are INFs. an OPERR will result if the INFs have the
   15480  1.1.6.2  bouyer # same signs. else,
   15481  1.1.6.2  bouyer #
   15482  1.1.6.2  bouyer fsub_inf_2:
   15483  1.1.6.2  bouyer 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
   15484  1.1.6.2  bouyer 	mov.b		DST_EX(%a1),%d1
   15485  1.1.6.2  bouyer 	eor.b		%d1,%d0
   15486  1.1.6.2  bouyer 	bpl.l		res_operr		# weed out (-INF)+(+INF)
   15487  1.1.6.2  bouyer 
   15488  1.1.6.2  bouyer # ok, so it's not an OPERR. but we do have to remember to return
   15489  1.1.6.2  bouyer # the src INF since that's where the 881/882 gets the j-bit.
   15490  1.1.6.2  bouyer 
   15491  1.1.6.2  bouyer fsub_inf_src:
   15492  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return src INF
   15493  1.1.6.2  bouyer 	fneg.x		%fp0			# invert sign
   15494  1.1.6.2  bouyer 	fbge.w		fsub_inf_done		# sign is now positive
   15495  1.1.6.2  bouyer 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15496  1.1.6.2  bouyer 	rts
   15497  1.1.6.2  bouyer 
   15498  1.1.6.2  bouyer fsub_inf_dst:
   15499  1.1.6.2  bouyer 	fmovm.x		DST(%a1),&0x80		# return dst INF
   15500  1.1.6.2  bouyer 	tst.b		DST_EX(%a1)		# is INF negative?
   15501  1.1.6.2  bouyer 	bpl.b		fsub_inf_done		# no
   15502  1.1.6.2  bouyer 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
   15503  1.1.6.2  bouyer 	rts
   15504  1.1.6.2  bouyer 
   15505  1.1.6.2  bouyer fsub_inf_done:
   15506  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
   15507  1.1.6.2  bouyer 	rts
   15508  1.1.6.2  bouyer 
   15509  1.1.6.2  bouyer #########################################################################
   15510  1.1.6.2  bouyer # XDEF ****************************************************************	#
   15511  1.1.6.2  bouyer # 	fsqrt(): emulates the fsqrt instruction				#
   15512  1.1.6.2  bouyer #	fssqrt(): emulates the fssqrt instruction			#
   15513  1.1.6.2  bouyer #	fdsqrt(): emulates the fdsqrt instruction			#
   15514  1.1.6.2  bouyer #									#
   15515  1.1.6.2  bouyer # XREF ****************************************************************	#
   15516  1.1.6.2  bouyer #	scale_sqrt() - scale the source operand				#
   15517  1.1.6.2  bouyer #	unf_res() - return default underflow result			#
   15518  1.1.6.2  bouyer #	ovf_res() - return default overflow result			#
   15519  1.1.6.2  bouyer # 	res_qnan_1op() - return QNAN result				#
   15520  1.1.6.2  bouyer # 	res_snan_1op() - return SNAN result				#
   15521  1.1.6.2  bouyer #									#
   15522  1.1.6.2  bouyer # INPUT ***************************************************************	#
   15523  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   15524  1.1.6.2  bouyer #	d0  rnd prec,mode						#
   15525  1.1.6.2  bouyer #									#
   15526  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   15527  1.1.6.2  bouyer #	fp0 = result							#
   15528  1.1.6.2  bouyer #	fp1 = EXOP (if exception occurred)				#
   15529  1.1.6.2  bouyer #									#
   15530  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   15531  1.1.6.2  bouyer #	Handle NANs, infinities, and zeroes as special cases. Divide	#
   15532  1.1.6.2  bouyer # norms/denorms into ext/sgl/dbl precision.				#
   15533  1.1.6.2  bouyer #	For norms/denorms, scale the exponents such that a sqrt		#
   15534  1.1.6.2  bouyer # instruction won't cause an exception. Use the regular fsqrt to	#
   15535  1.1.6.2  bouyer # compute a result. Check if the regular operands would have taken	#
   15536  1.1.6.2  bouyer # an exception. If so, return the default overflow/underflow result	#
   15537  1.1.6.2  bouyer # and return the EXOP if exceptions are enabled. Else, scale the 	#
   15538  1.1.6.2  bouyer # result operand to the proper exponent.				#
   15539  1.1.6.2  bouyer #									#
   15540  1.1.6.2  bouyer #########################################################################
   15541  1.1.6.2  bouyer 
   15542  1.1.6.2  bouyer 	global		fssqrt
   15543  1.1.6.2  bouyer fssqrt:
   15544  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   15545  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
   15546  1.1.6.2  bouyer 	bra.b		fsqrt
   15547  1.1.6.2  bouyer 
   15548  1.1.6.2  bouyer 	global		fdsqrt
   15549  1.1.6.2  bouyer fdsqrt:
   15550  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   15551  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
   15552  1.1.6.2  bouyer 
   15553  1.1.6.2  bouyer 	global		fsqrt
   15554  1.1.6.2  bouyer fsqrt:
   15555  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
   15556  1.1.6.2  bouyer 	clr.w		%d1
   15557  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d1
   15558  1.1.6.2  bouyer 	bne.w		fsqrt_not_norm		# optimize on non-norm input
   15559  1.1.6.2  bouyer 
   15560  1.1.6.2  bouyer #
   15561  1.1.6.2  bouyer # SQUARE ROOT: norms and denorms ONLY!
   15562  1.1.6.2  bouyer #
   15563  1.1.6.2  bouyer fsqrt_norm:
   15564  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   15565  1.1.6.2  bouyer 	bmi.l		res_operr		# yes
   15566  1.1.6.2  bouyer 
   15567  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   15568  1.1.6.2  bouyer 	bne.b		fsqrt_not_ext		# no; go handle sgl or dbl
   15569  1.1.6.2  bouyer 
   15570  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15571  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15572  1.1.6.2  bouyer 
   15573  1.1.6.2  bouyer 	fsqrt.x		(%a0),%fp0		# execute square root
   15574  1.1.6.2  bouyer 
   15575  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1
   15576  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# set N,INEX
   15577  1.1.6.2  bouyer 
   15578  1.1.6.2  bouyer 	rts
   15579  1.1.6.2  bouyer 
   15580  1.1.6.2  bouyer fsqrt_denorm:
   15581  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   15582  1.1.6.2  bouyer 	bmi.l		res_operr		# yes
   15583  1.1.6.2  bouyer 
   15584  1.1.6.2  bouyer 	andi.b		&0xc0,%d0		# is precision extended?
   15585  1.1.6.2  bouyer 	bne.b		fsqrt_not_ext		# no; go handle sgl or dbl
   15586  1.1.6.2  bouyer 
   15587  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15588  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15589  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15590  1.1.6.2  bouyer 
   15591  1.1.6.2  bouyer 	bsr.l		scale_sqrt		# calculate scale factor
   15592  1.1.6.2  bouyer 
   15593  1.1.6.2  bouyer 	bra.w		fsqrt_sd_normal
   15594  1.1.6.2  bouyer 
   15595  1.1.6.2  bouyer #
   15596  1.1.6.2  bouyer # operand is either single or double
   15597  1.1.6.2  bouyer #
   15598  1.1.6.2  bouyer fsqrt_not_ext:
   15599  1.1.6.2  bouyer 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
   15600  1.1.6.2  bouyer 	bne.w		fsqrt_dbl
   15601  1.1.6.2  bouyer 
   15602  1.1.6.2  bouyer #
   15603  1.1.6.2  bouyer # operand is to be rounded to single precision
   15604  1.1.6.2  bouyer #
   15605  1.1.6.2  bouyer fsqrt_sgl:
   15606  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15607  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15608  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15609  1.1.6.2  bouyer 
   15610  1.1.6.2  bouyer 	bsr.l		scale_sqrt		# calculate scale factor
   15611  1.1.6.2  bouyer 
   15612  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3f81	# will move in underflow?
   15613  1.1.6.2  bouyer 	beq.w		fsqrt_sd_may_unfl
   15614  1.1.6.2  bouyer 	bgt.w		fsqrt_sd_unfl		# yes; go handle underflow
   15615  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x407f	# will move in overflow?
   15616  1.1.6.2  bouyer 	beq.w		fsqrt_sd_may_ovfl	# maybe; go check
   15617  1.1.6.2  bouyer 	blt.w		fsqrt_sd_ovfl		# yes; go handle overflow
   15618  1.1.6.2  bouyer 
   15619  1.1.6.2  bouyer #
   15620  1.1.6.2  bouyer # operand will NOT overflow or underflow when moved in to the fp reg file
   15621  1.1.6.2  bouyer #
   15622  1.1.6.2  bouyer fsqrt_sd_normal:
   15623  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15624  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15625  1.1.6.2  bouyer 
   15626  1.1.6.2  bouyer 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform absolute
   15627  1.1.6.2  bouyer 
   15628  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   15629  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15630  1.1.6.2  bouyer 
   15631  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15632  1.1.6.2  bouyer 
   15633  1.1.6.2  bouyer fsqrt_sd_normal_exit:
   15634  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   15635  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   15636  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
   15637  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   15638  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   15639  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   15640  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   15641  1.1.6.2  bouyer 	or.w		%d1,%d2			# concat old sign,new exp
   15642  1.1.6.2  bouyer 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
   15643  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   15644  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
   15645  1.1.6.2  bouyer 	rts
   15646  1.1.6.2  bouyer 
   15647  1.1.6.2  bouyer #
   15648  1.1.6.2  bouyer # operand is to be rounded to double precision
   15649  1.1.6.2  bouyer #
   15650  1.1.6.2  bouyer fsqrt_dbl:
   15651  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   15652  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15653  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15654  1.1.6.2  bouyer 
   15655  1.1.6.2  bouyer 	bsr.l		scale_sqrt		# calculate scale factor
   15656  1.1.6.2  bouyer 
   15657  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x3c01	# will move in underflow?
   15658  1.1.6.2  bouyer 	beq.w		fsqrt_sd_may_unfl
   15659  1.1.6.2  bouyer 	bgt.b		fsqrt_sd_unfl		# yes; go handle underflow
   15660  1.1.6.2  bouyer 	cmpi.l		%d0,&0x3fff-0x43ff	# will move in overflow?
   15661  1.1.6.2  bouyer 	beq.w		fsqrt_sd_may_ovfl	# maybe; go check
   15662  1.1.6.2  bouyer 	blt.w		fsqrt_sd_ovfl		# yes; go handle overflow
   15663  1.1.6.2  bouyer 	bra.w		fsqrt_sd_normal		# no; ho handle normalized op
   15664  1.1.6.2  bouyer 
   15665  1.1.6.2  bouyer # we're on the line here and the distinguising characteristic is whether
   15666  1.1.6.2  bouyer # the exponent is 3fff or 3ffe. if it's 3ffe, then it's a safe number
   15667  1.1.6.2  bouyer # elsewise fall through to underflow.
   15668  1.1.6.2  bouyer fsqrt_sd_may_unfl:
   15669  1.1.6.2  bouyer 	btst		&0x0,1+FP_SCR0_EX(%a6)	# is exponent 0x3fff?
   15670  1.1.6.2  bouyer 	bne.w		fsqrt_sd_normal		# yes, so no underflow
   15671  1.1.6.2  bouyer 
   15672  1.1.6.2  bouyer #
   15673  1.1.6.2  bouyer # operand WILL underflow when moved in to the fp register file
   15674  1.1.6.2  bouyer #
   15675  1.1.6.2  bouyer fsqrt_sd_unfl:
   15676  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
   15677  1.1.6.2  bouyer 
   15678  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
   15679  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15680  1.1.6.2  bouyer 
   15681  1.1.6.2  bouyer 	fsqrt.x 	FP_SCR0(%a6),%fp0	# execute square root
   15682  1.1.6.2  bouyer 
   15683  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   15684  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15685  1.1.6.2  bouyer 
   15686  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15687  1.1.6.2  bouyer 
   15688  1.1.6.2  bouyer # if underflow or inexact is enabled, go calculate EXOP first.
   15689  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   15690  1.1.6.2  bouyer 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
   15691  1.1.6.2  bouyer 	bne.b		fsqrt_sd_unfl_ena	# yes
   15692  1.1.6.2  bouyer 
   15693  1.1.6.2  bouyer fsqrt_sd_unfl_dis:
   15694  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
   15695  1.1.6.2  bouyer 
   15696  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: result addr
   15697  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   15698  1.1.6.2  bouyer 	bsr.l		unf_res			# calculate default result
   15699  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set possible 'Z' ccode
   15700  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
   15701  1.1.6.2  bouyer 	rts
   15702  1.1.6.2  bouyer 
   15703  1.1.6.2  bouyer #
   15704  1.1.6.2  bouyer # operand will underflow AND underflow is enabled.
   15705  1.1.6.2  bouyer # therefore, we must return the result rounded to extended precision.
   15706  1.1.6.2  bouyer #
   15707  1.1.6.2  bouyer fsqrt_sd_unfl_ena:
   15708  1.1.6.2  bouyer 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
   15709  1.1.6.2  bouyer 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
   15710  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
   15711  1.1.6.2  bouyer 
   15712  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   15713  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   15714  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   15715  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   15716  1.1.6.2  bouyer 	sub.l		%d0,%d1			# subtract scale factor
   15717  1.1.6.2  bouyer 	addi.l		&0x6000,%d1		# add new bias
   15718  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   15719  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat new sign,new exp
   15720  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
   15721  1.1.6.2  bouyer 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
   15722  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   15723  1.1.6.2  bouyer 	bra.b		fsqrt_sd_unfl_dis
   15724  1.1.6.2  bouyer 
   15725  1.1.6.2  bouyer #
   15726  1.1.6.2  bouyer # operand WILL overflow.
   15727  1.1.6.2  bouyer #
   15728  1.1.6.2  bouyer fsqrt_sd_ovfl:
   15729  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15730  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15731  1.1.6.2  bouyer 
   15732  1.1.6.2  bouyer 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform square root
   15733  1.1.6.2  bouyer 
   15734  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15735  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   15736  1.1.6.2  bouyer 
   15737  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15738  1.1.6.2  bouyer 
   15739  1.1.6.2  bouyer fsqrt_sd_ovfl_tst:
   15740  1.1.6.2  bouyer 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
   15741  1.1.6.2  bouyer 
   15742  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   15743  1.1.6.2  bouyer 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
   15744  1.1.6.2  bouyer 	bne.b		fsqrt_sd_ovfl_ena	# yes
   15745  1.1.6.2  bouyer 
   15746  1.1.6.2  bouyer #
   15747  1.1.6.2  bouyer # OVFL is not enabled; therefore, we must create the default result by
   15748  1.1.6.2  bouyer # calling ovf_res().
   15749  1.1.6.2  bouyer #
   15750  1.1.6.2  bouyer fsqrt_sd_ovfl_dis:
   15751  1.1.6.2  bouyer 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
   15752  1.1.6.2  bouyer 	sne		%d1			# set sign param accordingly
   15753  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
   15754  1.1.6.2  bouyer 	bsr.l		ovf_res			# calculate default result
   15755  1.1.6.2  bouyer 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
   15756  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# return default result in fp0
   15757  1.1.6.2  bouyer 	rts
   15758  1.1.6.2  bouyer 
   15759  1.1.6.2  bouyer #
   15760  1.1.6.2  bouyer # OVFL is enabled.
   15761  1.1.6.2  bouyer # the INEX2 bit has already been updated by the round to the correct precision.
   15762  1.1.6.2  bouyer # now, round to extended(and don't alter the FPSR).
   15763  1.1.6.2  bouyer #
   15764  1.1.6.2  bouyer fsqrt_sd_ovfl_ena:
   15765  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   15766  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
   15767  1.1.6.2  bouyer 	mov.l		%d1,%d2			# make a copy
   15768  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# strip sign
   15769  1.1.6.2  bouyer 	andi.w		&0x8000,%d2		# keep old sign
   15770  1.1.6.2  bouyer 	sub.l		%d0,%d1			# add scale factor
   15771  1.1.6.2  bouyer 	subi.l		&0x6000,%d1		# subtract bias
   15772  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   15773  1.1.6.2  bouyer 	or.w		%d2,%d1			# concat sign,exp
   15774  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
   15775  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   15776  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore d2
   15777  1.1.6.2  bouyer 	bra.b		fsqrt_sd_ovfl_dis
   15778  1.1.6.2  bouyer 
   15779  1.1.6.2  bouyer #
   15780  1.1.6.2  bouyer # the move in MAY underflow. so...
   15781  1.1.6.2  bouyer #
   15782  1.1.6.2  bouyer fsqrt_sd_may_ovfl:
   15783  1.1.6.2  bouyer 	btst		&0x0,1+FP_SCR0_EX(%a6)	# is exponent 0x3fff?
   15784  1.1.6.2  bouyer 	bne.w		fsqrt_sd_ovfl		# yes, so overflow
   15785  1.1.6.2  bouyer 
   15786  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   15787  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   15788  1.1.6.2  bouyer 
   15789  1.1.6.2  bouyer 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform absolute
   15790  1.1.6.2  bouyer 
   15791  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save status
   15792  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   15793  1.1.6.2  bouyer 
   15794  1.1.6.2  bouyer 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
   15795  1.1.6.2  bouyer 
   15796  1.1.6.2  bouyer 	fmov.x		%fp0,%fp1		# make a copy of result
   15797  1.1.6.2  bouyer 	fcmp.b		%fp1,&0x1		# is |result| >= 1.b?
   15798  1.1.6.2  bouyer 	fbge.w		fsqrt_sd_ovfl_tst	# yes; overflow has occurred
   15799  1.1.6.2  bouyer 
   15800  1.1.6.2  bouyer # no, it didn't overflow; we have correct result
   15801  1.1.6.2  bouyer 	bra.w		fsqrt_sd_normal_exit
   15802  1.1.6.2  bouyer 
   15803  1.1.6.2  bouyer ##########################################################################
   15804  1.1.6.2  bouyer 
   15805  1.1.6.2  bouyer #
   15806  1.1.6.2  bouyer # input is not normalized; what is it?
   15807  1.1.6.2  bouyer #
   15808  1.1.6.2  bouyer fsqrt_not_norm:
   15809  1.1.6.2  bouyer 	cmpi.b		%d1,&DENORM		# weed out DENORM
   15810  1.1.6.2  bouyer 	beq.w		fsqrt_denorm
   15811  1.1.6.2  bouyer 	cmpi.b		%d1,&ZERO		# weed out ZERO
   15812  1.1.6.2  bouyer 	beq.b		fsqrt_zero
   15813  1.1.6.2  bouyer 	cmpi.b		%d1,&INF		# weed out INF
   15814  1.1.6.2  bouyer 	beq.b		fsqrt_inf
   15815  1.1.6.2  bouyer 	cmpi.b		%d1,&SNAN		# weed out SNAN
   15816  1.1.6.2  bouyer 	beq.l		res_snan_1op
   15817  1.1.6.2  bouyer 	bra.l		res_qnan_1op
   15818  1.1.6.2  bouyer 
   15819  1.1.6.2  bouyer #
   15820  1.1.6.2  bouyer # 	fsqrt(+0) = +0
   15821  1.1.6.2  bouyer # 	fsqrt(-0) = -0
   15822  1.1.6.2  bouyer #	fsqrt(+INF) = +INF
   15823  1.1.6.2  bouyer # 	fsqrt(-INF) = OPERR
   15824  1.1.6.2  bouyer #
   15825  1.1.6.2  bouyer fsqrt_zero:
   15826  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is ZERO positive or negative?
   15827  1.1.6.2  bouyer 	bmi.b		fsqrt_zero_m		# negative
   15828  1.1.6.2  bouyer fsqrt_zero_p:
   15829  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# return +ZERO
   15830  1.1.6.2  bouyer 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
   15831  1.1.6.2  bouyer 	rts
   15832  1.1.6.2  bouyer fsqrt_zero_m:
   15833  1.1.6.2  bouyer 	fmov.s		&0x80000000,%fp0	# return -ZERO
   15834  1.1.6.2  bouyer 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set 'Z','N' ccode bits
   15835  1.1.6.2  bouyer 	rts
   15836  1.1.6.2  bouyer 
   15837  1.1.6.2  bouyer fsqrt_inf:
   15838  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is INF positive or negative?
   15839  1.1.6.2  bouyer 	bmi.l		res_operr		# negative
   15840  1.1.6.2  bouyer fsqrt_inf_p:
   15841  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return +INF in fp0
   15842  1.1.6.2  bouyer 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
   15843  1.1.6.2  bouyer 	rts
   15844  1.1.6.2  bouyer 
   15845  1.1.6.2  bouyer ##########################################################################
   15846  1.1.6.2  bouyer 
   15847  1.1.6.2  bouyer #########################################################################
   15848  1.1.6.2  bouyer # XDEF ****************************************************************	#
   15849  1.1.6.2  bouyer #	addsub_scaler2(): scale inputs to fadd/fsub such that no	#
   15850  1.1.6.2  bouyer #			  OVFL/UNFL exceptions will result		#
   15851  1.1.6.2  bouyer #									#
   15852  1.1.6.2  bouyer # XREF ****************************************************************	#
   15853  1.1.6.2  bouyer #	norm() - normalize mantissa after adjusting exponent		#
   15854  1.1.6.2  bouyer #									#
   15855  1.1.6.2  bouyer # INPUT ***************************************************************	#
   15856  1.1.6.2  bouyer #	FP_SRC(a6) = fp op1(src)					#
   15857  1.1.6.2  bouyer #	FP_DST(a6) = fp op2(dst)					#
   15858  1.1.6.2  bouyer # 									#
   15859  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   15860  1.1.6.2  bouyer #	FP_SRC(a6) = fp op1 scaled(src)					#
   15861  1.1.6.2  bouyer #	FP_DST(a6) = fp op2 scaled(dst)					#
   15862  1.1.6.2  bouyer #	d0         = scale amount					#
   15863  1.1.6.2  bouyer #									#
   15864  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   15865  1.1.6.2  bouyer # 	If the DST exponent is > the SRC exponent, set the DST exponent	#
   15866  1.1.6.2  bouyer # equal to 0x3fff and scale the SRC exponent by the value that the	#
   15867  1.1.6.2  bouyer # DST exponent was scaled by. If the SRC exponent is greater or equal,	#
   15868  1.1.6.2  bouyer # do the opposite. Return this scale factor in d0.			#
   15869  1.1.6.2  bouyer #	If the two exponents differ by > the number of mantissa bits	#
   15870  1.1.6.2  bouyer # plus two, then set the smallest exponent to a very small value as a	#
   15871  1.1.6.2  bouyer # quick shortcut.							#
   15872  1.1.6.2  bouyer #									#
   15873  1.1.6.2  bouyer #########################################################################
   15874  1.1.6.2  bouyer 
   15875  1.1.6.2  bouyer 	global		addsub_scaler2
   15876  1.1.6.2  bouyer addsub_scaler2:
   15877  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   15878  1.1.6.2  bouyer 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
   15879  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   15880  1.1.6.2  bouyer 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
   15881  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0
   15882  1.1.6.2  bouyer 	mov.w		DST_EX(%a1),%d1
   15883  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)
   15884  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR1_EX(%a6)
   15885  1.1.6.2  bouyer 
   15886  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0
   15887  1.1.6.2  bouyer 	andi.w		&0x7fff,%d1
   15888  1.1.6.2  bouyer 	mov.w		%d0,L_SCR1(%a6)		# store src exponent
   15889  1.1.6.2  bouyer 	mov.w		%d1,2+L_SCR1(%a6)	# store dst exponent
   15890  1.1.6.2  bouyer 
   15891  1.1.6.2  bouyer 	cmp.w		%d0, %d1		# is src exp >= dst exp?
   15892  1.1.6.2  bouyer 	bge.l		src_exp_ge2
   15893  1.1.6.2  bouyer 
   15894  1.1.6.2  bouyer # dst exp is >  src exp; scale dst to exp = 0x3fff
   15895  1.1.6.2  bouyer dst_exp_gt2:
   15896  1.1.6.2  bouyer 	bsr.l		scale_to_zero_dst
   15897  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save scale factor
   15898  1.1.6.2  bouyer 
   15899  1.1.6.2  bouyer 	cmpi.b		STAG(%a6),&DENORM	# is dst denormalized?
   15900  1.1.6.2  bouyer 	bne.b		cmpexp12
   15901  1.1.6.2  bouyer 
   15902  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   15903  1.1.6.2  bouyer 	bsr.l		norm			# normalize the denorm; result is new exp
   15904  1.1.6.2  bouyer 	neg.w		%d0			# new exp = -(shft val)
   15905  1.1.6.2  bouyer 	mov.w		%d0,L_SCR1(%a6)		# inset new exp
   15906  1.1.6.2  bouyer 
   15907  1.1.6.2  bouyer cmpexp12:
   15908  1.1.6.2  bouyer 	mov.w		2+L_SCR1(%a6),%d0
   15909  1.1.6.2  bouyer 	subi.w		&mantissalen+2,%d0	# subtract mantissalen+2 from larger exp
   15910  1.1.6.2  bouyer 
   15911  1.1.6.2  bouyer 	cmp.w		%d0,L_SCR1(%a6)		# is difference >= len(mantissa)+2?
   15912  1.1.6.2  bouyer 	bge.b		quick_scale12
   15913  1.1.6.2  bouyer 
   15914  1.1.6.2  bouyer 	mov.w		L_SCR1(%a6),%d0
   15915  1.1.6.2  bouyer 	add.w		0x2(%sp),%d0		# scale src exponent by scale factor
   15916  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1
   15917  1.1.6.2  bouyer 	and.w		&0x8000,%d1
   15918  1.1.6.2  bouyer 	or.w		%d1,%d0			# concat {sgn,new exp}
   15919  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new dst exponent
   15920  1.1.6.2  bouyer 
   15921  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# return SCALE factor
   15922  1.1.6.2  bouyer 	rts
   15923  1.1.6.2  bouyer 
   15924  1.1.6.2  bouyer quick_scale12:
   15925  1.1.6.2  bouyer 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# zero src exponent
   15926  1.1.6.2  bouyer 	bset		&0x0,1+FP_SCR0_EX(%a6)	# set exp = 1
   15927  1.1.6.2  bouyer 
   15928  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# return SCALE factor
   15929  1.1.6.2  bouyer 	rts
   15930  1.1.6.2  bouyer 
   15931  1.1.6.2  bouyer # src exp is >= dst exp; scale src to exp = 0x3fff
   15932  1.1.6.2  bouyer src_exp_ge2:
   15933  1.1.6.2  bouyer 	bsr.l		scale_to_zero_src
   15934  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save scale factor
   15935  1.1.6.2  bouyer 
   15936  1.1.6.2  bouyer 	cmpi.b		DTAG(%a6),&DENORM	# is dst denormalized?
   15937  1.1.6.2  bouyer 	bne.b		cmpexp22
   15938  1.1.6.2  bouyer 	lea		FP_SCR1(%a6),%a0
   15939  1.1.6.2  bouyer 	bsr.l		norm			# normalize the denorm; result is new exp
   15940  1.1.6.2  bouyer 	neg.w		%d0			# new exp = -(shft val)
   15941  1.1.6.2  bouyer 	mov.w		%d0,2+L_SCR1(%a6)	# inset new exp
   15942  1.1.6.2  bouyer 
   15943  1.1.6.2  bouyer cmpexp22:
   15944  1.1.6.2  bouyer 	mov.w		L_SCR1(%a6),%d0
   15945  1.1.6.2  bouyer 	subi.w		&mantissalen+2,%d0	# subtract mantissalen+2 from larger exp
   15946  1.1.6.2  bouyer 
   15947  1.1.6.2  bouyer 	cmp.w		%d0,2+L_SCR1(%a6)	# is difference >= len(mantissa)+2?
   15948  1.1.6.2  bouyer 	bge.b		quick_scale22
   15949  1.1.6.2  bouyer 
   15950  1.1.6.2  bouyer 	mov.w		2+L_SCR1(%a6),%d0
   15951  1.1.6.2  bouyer 	add.w		0x2(%sp),%d0		# scale dst exponent by scale factor
   15952  1.1.6.2  bouyer 	mov.w		FP_SCR1_EX(%a6),%d1
   15953  1.1.6.2  bouyer 	andi.w		&0x8000,%d1
   15954  1.1.6.2  bouyer 	or.w		%d1,%d0			# concat {sgn,new exp}
   15955  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR1_EX(%a6)	# insert new dst exponent
   15956  1.1.6.2  bouyer 
   15957  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# return SCALE factor
   15958  1.1.6.2  bouyer 	rts
   15959  1.1.6.2  bouyer 
   15960  1.1.6.2  bouyer quick_scale22:
   15961  1.1.6.2  bouyer 	andi.w		&0x8000,FP_SCR1_EX(%a6)	# zero dst exponent
   15962  1.1.6.2  bouyer 	bset		&0x0,1+FP_SCR1_EX(%a6)	# set exp = 1
   15963  1.1.6.2  bouyer 
   15964  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# return SCALE factor
   15965  1.1.6.2  bouyer 	rts
   15966  1.1.6.2  bouyer 
   15967  1.1.6.2  bouyer ##########################################################################
   15968  1.1.6.2  bouyer 
   15969  1.1.6.2  bouyer #########################################################################
   15970  1.1.6.2  bouyer # XDEF ****************************************************************	#
   15971  1.1.6.2  bouyer #	scale_to_zero_src(): scale the exponent of extended precision	#
   15972  1.1.6.2  bouyer #			     value at FP_SCR0(a6).			#
   15973  1.1.6.2  bouyer #									#
   15974  1.1.6.2  bouyer # XREF ****************************************************************	#
   15975  1.1.6.2  bouyer #	norm() - normalize the mantissa if the operand was a DENORM	#
   15976  1.1.6.2  bouyer #									#
   15977  1.1.6.2  bouyer # INPUT ***************************************************************	#
   15978  1.1.6.2  bouyer #	FP_SCR0(a6) = extended precision operand to be scaled		#
   15979  1.1.6.2  bouyer # 									#
   15980  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   15981  1.1.6.2  bouyer #	FP_SCR0(a6) = scaled extended precision operand			#
   15982  1.1.6.2  bouyer #	d0	    = scale value					#
   15983  1.1.6.2  bouyer #									#
   15984  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   15985  1.1.6.2  bouyer # 	Set the exponent of the input operand to 0x3fff. Save the value	#
   15986  1.1.6.2  bouyer # of the difference between the original and new exponent. Then, 	#
   15987  1.1.6.2  bouyer # normalize the operand if it was a DENORM. Add this normalization	#
   15988  1.1.6.2  bouyer # value to the previous value. Return the result.			#
   15989  1.1.6.2  bouyer #									#
   15990  1.1.6.2  bouyer #########################################################################
   15991  1.1.6.2  bouyer 
   15992  1.1.6.2  bouyer 	global		scale_to_zero_src
   15993  1.1.6.2  bouyer scale_to_zero_src:
   15994  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# extract operand's {sgn,exp}
   15995  1.1.6.2  bouyer 	mov.w		%d1,%d0			# make a copy
   15996  1.1.6.2  bouyer 
   15997  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# extract operand's exponent
   15998  1.1.6.2  bouyer 
   15999  1.1.6.2  bouyer 	andi.w		&0x8000,%d0		# extract operand's sgn
   16000  1.1.6.2  bouyer 	or.w		&0x3fff,%d0		# insert new operand's exponent(=0)
   16001  1.1.6.2  bouyer 
   16002  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert biased exponent
   16003  1.1.6.2  bouyer 
   16004  1.1.6.2  bouyer 	cmpi.b		STAG(%a6),&DENORM	# is operand normalized?
   16005  1.1.6.2  bouyer 	beq.b		stzs_denorm		# normalize the DENORM
   16006  1.1.6.2  bouyer 
   16007  1.1.6.2  bouyer stzs_norm:
   16008  1.1.6.2  bouyer 	mov.l		&0x3fff,%d0
   16009  1.1.6.2  bouyer 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16010  1.1.6.2  bouyer 
   16011  1.1.6.2  bouyer 	rts
   16012  1.1.6.2  bouyer 
   16013  1.1.6.2  bouyer stzs_denorm:
   16014  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass ptr to src op
   16015  1.1.6.2  bouyer 	bsr.l		norm			# normalize denorm
   16016  1.1.6.2  bouyer 	neg.l		%d0			# new exponent = -(shft val)
   16017  1.1.6.2  bouyer 	mov.l		%d0,%d1			# prepare for op_norm call
   16018  1.1.6.2  bouyer 	bra.b		stzs_norm		# finish scaling
   16019  1.1.6.2  bouyer 
   16020  1.1.6.2  bouyer ###
   16021  1.1.6.2  bouyer 
   16022  1.1.6.2  bouyer #########################################################################
   16023  1.1.6.2  bouyer # XDEF ****************************************************************	#
   16024  1.1.6.2  bouyer #	scale_sqrt(): scale the input operand exponent so a subsequent	#
   16025  1.1.6.2  bouyer #		      fsqrt operation won't take an exception.		#
   16026  1.1.6.2  bouyer #									#
   16027  1.1.6.2  bouyer # XREF ****************************************************************	#
   16028  1.1.6.2  bouyer #	norm() - normalize the mantissa if the operand was a DENORM	#
   16029  1.1.6.2  bouyer #									#
   16030  1.1.6.2  bouyer # INPUT ***************************************************************	#
   16031  1.1.6.2  bouyer #	FP_SCR0(a6) = extended precision operand to be scaled		#
   16032  1.1.6.2  bouyer # 									#
   16033  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   16034  1.1.6.2  bouyer #	FP_SCR0(a6) = scaled extended precision operand			#
   16035  1.1.6.2  bouyer #	d0	    = scale value					#
   16036  1.1.6.2  bouyer #									#
   16037  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   16038  1.1.6.2  bouyer #	If the input operand is a DENORM, normalize it.			#
   16039  1.1.6.2  bouyer # 	If the exponent of the input operand is even, set the exponent	#
   16040  1.1.6.2  bouyer # to 0x3ffe and return a scale factor of "(exp-0x3ffe)/2". If the 	#
   16041  1.1.6.2  bouyer # exponent of the input operand is off, set the exponent to ox3fff and	#
   16042  1.1.6.2  bouyer # return a scale factor of "(exp-0x3fff)/2". 				#
   16043  1.1.6.2  bouyer #									#
   16044  1.1.6.2  bouyer #########################################################################
   16045  1.1.6.2  bouyer 
   16046  1.1.6.2  bouyer 	global		scale_sqrt
   16047  1.1.6.2  bouyer scale_sqrt:
   16048  1.1.6.2  bouyer 	cmpi.b		STAG(%a6),&DENORM	# is operand normalized?
   16049  1.1.6.2  bouyer 	beq.b		ss_denorm		# normalize the DENORM
   16050  1.1.6.2  bouyer 
   16051  1.1.6.2  bouyer 	mov.w		FP_SCR0_EX(%a6),%d1	# extract operand's {sgn,exp}
   16052  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# extract operand's exponent
   16053  1.1.6.2  bouyer 
   16054  1.1.6.2  bouyer 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# extract operand's sgn
   16055  1.1.6.2  bouyer 
   16056  1.1.6.2  bouyer 	btst		&0x0,%d1		# is exp even or odd?
   16057  1.1.6.2  bouyer 	beq.b		ss_norm_even
   16058  1.1.6.2  bouyer 
   16059  1.1.6.2  bouyer 	ori.w		&0x3fff,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16060  1.1.6.2  bouyer 
   16061  1.1.6.2  bouyer 	mov.l		&0x3fff,%d0
   16062  1.1.6.2  bouyer 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16063  1.1.6.2  bouyer 	asr.l		&0x1,%d0		# divide scale factor by 2
   16064  1.1.6.2  bouyer 	rts
   16065  1.1.6.2  bouyer 
   16066  1.1.6.2  bouyer ss_norm_even:
   16067  1.1.6.2  bouyer 	ori.w		&0x3ffe,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16068  1.1.6.2  bouyer 
   16069  1.1.6.2  bouyer 	mov.l		&0x3ffe,%d0
   16070  1.1.6.2  bouyer 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16071  1.1.6.2  bouyer 	asr.l		&0x1,%d0		# divide scale factor by 2
   16072  1.1.6.2  bouyer 	rts
   16073  1.1.6.2  bouyer 
   16074  1.1.6.2  bouyer ss_denorm:
   16075  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass ptr to src op
   16076  1.1.6.2  bouyer 	bsr.l		norm			# normalize denorm
   16077  1.1.6.2  bouyer 
   16078  1.1.6.2  bouyer 	btst		&0x0,%d0		# is exp even or odd?
   16079  1.1.6.2  bouyer 	beq.b		ss_denorm_even
   16080  1.1.6.2  bouyer 
   16081  1.1.6.2  bouyer 	ori.w		&0x3fff,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16082  1.1.6.2  bouyer 
   16083  1.1.6.2  bouyer 	add.l		&0x3fff,%d0
   16084  1.1.6.2  bouyer 	asr.l		&0x1,%d0		# divide scale factor by 2
   16085  1.1.6.2  bouyer 	rts
   16086  1.1.6.2  bouyer 
   16087  1.1.6.2  bouyer ss_denorm_even:
   16088  1.1.6.2  bouyer 	ori.w		&0x3ffe,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
   16089  1.1.6.2  bouyer 
   16090  1.1.6.2  bouyer 	add.l		&0x3ffe,%d0
   16091  1.1.6.2  bouyer 	asr.l		&0x1,%d0		# divide scale factor by 2
   16092  1.1.6.2  bouyer 	rts
   16093  1.1.6.2  bouyer 
   16094  1.1.6.2  bouyer ###
   16095  1.1.6.2  bouyer 
   16096  1.1.6.2  bouyer #########################################################################
   16097  1.1.6.2  bouyer # XDEF ****************************************************************	#
   16098  1.1.6.2  bouyer #	scale_to_zero_dst(): scale the exponent of extended precision	#
   16099  1.1.6.2  bouyer #			     value at FP_SCR1(a6).			#
   16100  1.1.6.2  bouyer #									#
   16101  1.1.6.2  bouyer # XREF ****************************************************************	#
   16102  1.1.6.2  bouyer #	norm() - normalize the mantissa if the operand was a DENORM	#
   16103  1.1.6.2  bouyer #									#
   16104  1.1.6.2  bouyer # INPUT ***************************************************************	#
   16105  1.1.6.2  bouyer #	FP_SCR1(a6) = extended precision operand to be scaled		#
   16106  1.1.6.2  bouyer # 									#
   16107  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   16108  1.1.6.2  bouyer #	FP_SCR1(a6) = scaled extended precision operand			#
   16109  1.1.6.2  bouyer #	d0	    = scale value					#
   16110  1.1.6.2  bouyer #									#
   16111  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   16112  1.1.6.2  bouyer # 	Set the exponent of the input operand to 0x3fff. Save the value	#
   16113  1.1.6.2  bouyer # of the difference between the original and new exponent. Then, 	#
   16114  1.1.6.2  bouyer # normalize the operand if it was a DENORM. Add this normalization	#
   16115  1.1.6.2  bouyer # value to the previous value. Return the result.			#
   16116  1.1.6.2  bouyer #									#
   16117  1.1.6.2  bouyer #########################################################################
   16118  1.1.6.2  bouyer 
   16119  1.1.6.2  bouyer 	global		scale_to_zero_dst
   16120  1.1.6.2  bouyer scale_to_zero_dst:
   16121  1.1.6.2  bouyer 	mov.w		FP_SCR1_EX(%a6),%d1	# extract operand's {sgn,exp}
   16122  1.1.6.2  bouyer 	mov.w		%d1,%d0			# make a copy
   16123  1.1.6.2  bouyer 
   16124  1.1.6.2  bouyer 	andi.l		&0x7fff,%d1		# extract operand's exponent
   16125  1.1.6.2  bouyer 
   16126  1.1.6.2  bouyer 	andi.w		&0x8000,%d0		# extract operand's sgn
   16127  1.1.6.2  bouyer 	or.w		&0x3fff,%d0		# insert new operand's exponent(=0)
   16128  1.1.6.2  bouyer 
   16129  1.1.6.2  bouyer 	mov.w		%d0,FP_SCR1_EX(%a6)	# insert biased exponent
   16130  1.1.6.2  bouyer 
   16131  1.1.6.2  bouyer 	cmpi.b		DTAG(%a6),&DENORM	# is operand normalized?
   16132  1.1.6.2  bouyer 	beq.b		stzd_denorm		# normalize the DENORM
   16133  1.1.6.2  bouyer 
   16134  1.1.6.2  bouyer stzd_norm:
   16135  1.1.6.2  bouyer 	mov.l		&0x3fff,%d0
   16136  1.1.6.2  bouyer 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
   16137  1.1.6.2  bouyer 	rts
   16138  1.1.6.2  bouyer 
   16139  1.1.6.2  bouyer stzd_denorm:
   16140  1.1.6.2  bouyer 	lea		FP_SCR1(%a6),%a0	# pass ptr to dst op
   16141  1.1.6.2  bouyer 	bsr.l		norm			# normalize denorm
   16142  1.1.6.2  bouyer 	neg.l		%d0			# new exponent = -(shft val)
   16143  1.1.6.2  bouyer 	mov.l		%d0,%d1			# prepare for op_norm call
   16144  1.1.6.2  bouyer 	bra.b		stzd_norm		# finish scaling
   16145  1.1.6.2  bouyer 
   16146  1.1.6.2  bouyer ##########################################################################
   16147  1.1.6.2  bouyer 
   16148  1.1.6.2  bouyer #########################################################################
   16149  1.1.6.2  bouyer # XDEF ****************************************************************	#
   16150  1.1.6.2  bouyer #	res_qnan(): return default result w/ QNAN operand for dyadic	#
   16151  1.1.6.2  bouyer #	res_snan(): return default result w/ SNAN operand for dyadic	#
   16152  1.1.6.2  bouyer #	res_qnan_1op(): return dflt result w/ QNAN operand for monadic	#
   16153  1.1.6.2  bouyer #	res_snan_1op(): return dflt result w/ SNAN operand for monadic	#
   16154  1.1.6.2  bouyer #									#
   16155  1.1.6.2  bouyer # XREF ****************************************************************	#
   16156  1.1.6.2  bouyer #	None								#
   16157  1.1.6.2  bouyer #									#
   16158  1.1.6.2  bouyer # INPUT ***************************************************************	#
   16159  1.1.6.2  bouyer #	FP_SRC(a6) = pointer to extended precision src operand		#
   16160  1.1.6.2  bouyer #	FP_DST(a6) = pointer to extended precision dst operand		#
   16161  1.1.6.2  bouyer # 									#
   16162  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   16163  1.1.6.2  bouyer #	fp0 = default result						#
   16164  1.1.6.2  bouyer #									#
   16165  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   16166  1.1.6.2  bouyer # 	If either operand (but not both operands) of an operation is a	#
   16167  1.1.6.2  bouyer # nonsignalling NAN, then that NAN is returned as the result. If both	#
   16168  1.1.6.2  bouyer # operands are nonsignalling NANs, then the destination operand 	#
   16169  1.1.6.2  bouyer # nonsignalling NAN is returned as the result.				#
   16170  1.1.6.2  bouyer # 	If either operand to an operation is a signalling NAN (SNAN),	#
   16171  1.1.6.2  bouyer # then, the SNAN bit is set in the FPSR EXC byte. If the SNAN trap	#
   16172  1.1.6.2  bouyer # enable bit is set in the FPCR, then the trap is taken and the 	#
   16173  1.1.6.2  bouyer # destination is not modified. If the SNAN trap enable bit is not set,	#
   16174  1.1.6.2  bouyer # then the SNAN is converted to a nonsignalling NAN (by setting the 	#
   16175  1.1.6.2  bouyer # SNAN bit in the operand to one), and the operation continues as 	#
   16176  1.1.6.2  bouyer # described in the preceding paragraph, for nonsignalling NANs.		#
   16177  1.1.6.2  bouyer #	Make sure the appropriate FPSR bits are set before exiting.	#
   16178  1.1.6.2  bouyer #									#
   16179  1.1.6.2  bouyer #########################################################################
   16180  1.1.6.2  bouyer 
   16181  1.1.6.2  bouyer 	global		res_qnan
   16182  1.1.6.2  bouyer 	global		res_snan
   16183  1.1.6.2  bouyer res_qnan:
   16184  1.1.6.2  bouyer res_snan:
   16185  1.1.6.2  bouyer 	cmp.b		DTAG(%a6), &SNAN	# is the dst an SNAN?
   16186  1.1.6.2  bouyer 	beq.b		dst_snan2
   16187  1.1.6.2  bouyer 	cmp.b		DTAG(%a6), &QNAN	# is the dst a  QNAN?
   16188  1.1.6.2  bouyer 	beq.b		dst_qnan2
   16189  1.1.6.2  bouyer src_nan:
   16190  1.1.6.2  bouyer 	cmp.b		STAG(%a6), &QNAN
   16191  1.1.6.2  bouyer 	beq.b		src_qnan2
   16192  1.1.6.2  bouyer 	global		res_snan_1op
   16193  1.1.6.2  bouyer res_snan_1op:
   16194  1.1.6.2  bouyer src_snan2:
   16195  1.1.6.2  bouyer 	bset		&0x6, FP_SRC_HI(%a6)	# set SNAN bit
   16196  1.1.6.2  bouyer 	or.l		&nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
   16197  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   16198  1.1.6.2  bouyer 	bra.b		nan_comp
   16199  1.1.6.2  bouyer 	global		res_qnan_1op
   16200  1.1.6.2  bouyer res_qnan_1op:
   16201  1.1.6.2  bouyer src_qnan2:
   16202  1.1.6.2  bouyer 	or.l		&nan_mask, USER_FPSR(%a6)
   16203  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   16204  1.1.6.2  bouyer 	bra.b		nan_comp
   16205  1.1.6.2  bouyer dst_snan2:
   16206  1.1.6.2  bouyer 	or.l		&nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
   16207  1.1.6.2  bouyer 	bset		&0x6, FP_DST_HI(%a6)	# set SNAN bit
   16208  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   16209  1.1.6.2  bouyer 	bra.b		nan_comp
   16210  1.1.6.2  bouyer dst_qnan2:
   16211  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   16212  1.1.6.2  bouyer 	cmp.b		STAG(%a6), &SNAN
   16213  1.1.6.2  bouyer 	bne		nan_done
   16214  1.1.6.2  bouyer 	or.l		&aiop_mask+snan_mask, USER_FPSR(%a6)
   16215  1.1.6.2  bouyer nan_done:
   16216  1.1.6.2  bouyer 	or.l		&nan_mask, USER_FPSR(%a6)
   16217  1.1.6.2  bouyer nan_comp:
   16218  1.1.6.2  bouyer 	btst		&0x7, FTEMP_EX(%a0)	# is NAN neg?
   16219  1.1.6.2  bouyer 	beq.b		nan_not_neg
   16220  1.1.6.2  bouyer 	or.l		&neg_mask, USER_FPSR(%a6)
   16221  1.1.6.2  bouyer nan_not_neg:
   16222  1.1.6.2  bouyer 	fmovm.x		(%a0), &0x80
   16223  1.1.6.2  bouyer 	rts
   16224  1.1.6.2  bouyer 
   16225  1.1.6.2  bouyer #########################################################################
   16226  1.1.6.2  bouyer # XDEF ****************************************************************	#
   16227  1.1.6.2  bouyer # 	res_operr(): return default result during operand error		#
   16228  1.1.6.2  bouyer #									#
   16229  1.1.6.2  bouyer # XREF ****************************************************************	#
   16230  1.1.6.2  bouyer #	None								#
   16231  1.1.6.2  bouyer #									#
   16232  1.1.6.2  bouyer # INPUT ***************************************************************	#
   16233  1.1.6.2  bouyer #	None								#
   16234  1.1.6.2  bouyer # 									#
   16235  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   16236  1.1.6.2  bouyer #	fp0 = default operand error result				#
   16237  1.1.6.2  bouyer #									#
   16238  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   16239  1.1.6.2  bouyer #	An nonsignalling NAN is returned as the default result when	#
   16240  1.1.6.2  bouyer # an operand error occurs for the following cases:			#
   16241  1.1.6.2  bouyer #									#
   16242  1.1.6.2  bouyer # 	Multiply: (Infinity x Zero)					#
   16243  1.1.6.2  bouyer # 	Divide  : (Zero / Zero) || (Infinity / Infinity)		#
   16244  1.1.6.2  bouyer #									#
   16245  1.1.6.2  bouyer #########################################################################
   16246  1.1.6.2  bouyer 
   16247  1.1.6.2  bouyer 	global		res_operr
   16248  1.1.6.2  bouyer res_operr:
   16249  1.1.6.2  bouyer 	or.l		&nan_mask+operr_mask+aiop_mask, USER_FPSR(%a6)
   16250  1.1.6.2  bouyer 	fmovm.x		nan_return(%pc), &0x80
   16251  1.1.6.2  bouyer 	rts
   16252  1.1.6.2  bouyer 
   16253  1.1.6.2  bouyer nan_return:
   16254  1.1.6.2  bouyer 	long		0x7fff0000, 0xffffffff, 0xffffffff
   16255  1.1.6.2  bouyer 
   16256  1.1.6.2  bouyer #########################################################################
   16257  1.1.6.2  bouyer # fdbcc(): routine to emulate the fdbcc instruction			#
   16258  1.1.6.2  bouyer #									#
   16259  1.1.6.2  bouyer # XDEF **************************************************************** #
   16260  1.1.6.2  bouyer #	_fdbcc()							#
   16261  1.1.6.2  bouyer #									#
   16262  1.1.6.2  bouyer # XREF **************************************************************** #
   16263  1.1.6.2  bouyer #	fetch_dreg() - fetch Dn value					#
   16264  1.1.6.2  bouyer #	store_dreg_l() - store updated Dn value				#
   16265  1.1.6.2  bouyer #									#
   16266  1.1.6.2  bouyer # INPUT ***************************************************************	#
   16267  1.1.6.2  bouyer #	d0 = displacement						#
   16268  1.1.6.2  bouyer #									#
   16269  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   16270  1.1.6.2  bouyer #	none								#
   16271  1.1.6.2  bouyer #									#
   16272  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   16273  1.1.6.2  bouyer #	This routine checks which conditional predicate is specified by	#
   16274  1.1.6.2  bouyer # the stacked fdbcc instruction opcode and then branches to a routine	#
   16275  1.1.6.2  bouyer # for that predicate. The corresponding fbcc instruction is then used	#
   16276  1.1.6.2  bouyer # to see whether the condition (specified by the stacked FPSR) is true	#
   16277  1.1.6.2  bouyer # or false.								#
   16278  1.1.6.2  bouyer #	If a BSUN exception should be indicated, the BSUN and ABSUN	#
   16279  1.1.6.2  bouyer # bits are set in the stacked FPSR. If the BSUN exception is enabled,	#
   16280  1.1.6.2  bouyer # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an 	#
   16281  1.1.6.2  bouyer # enabled BSUN should not be flagged and the predicate is true, then	#
   16282  1.1.6.2  bouyer # Dn is fetched and decremented by one. If Dn is not equal to -1, add	#
   16283  1.1.6.2  bouyer # the displacement value to the stacked PC so that when an "rte" is	#
   16284  1.1.6.2  bouyer # finally executed, the branch occurs.					#
   16285  1.1.6.2  bouyer #									#
   16286  1.1.6.2  bouyer #########################################################################
   16287  1.1.6.2  bouyer 	global		_fdbcc
   16288  1.1.6.2  bouyer _fdbcc:
   16289  1.1.6.2  bouyer 	mov.l		%d0,L_SCR1(%a6)		# save displacement
   16290  1.1.6.2  bouyer 
   16291  1.1.6.2  bouyer 	mov.w		EXC_CMDREG(%a6),%d0	# fetch predicate
   16292  1.1.6.2  bouyer 
   16293  1.1.6.2  bouyer 	clr.l		%d1			# clear scratch reg
   16294  1.1.6.2  bouyer 	mov.b		FPSR_CC(%a6),%d1	# fetch fp ccodes
   16295  1.1.6.2  bouyer 	ror.l		&0x8,%d1		# rotate to top byte
   16296  1.1.6.2  bouyer 	fmov.l		%d1,%fpsr		# insert into FPSR
   16297  1.1.6.2  bouyer 
   16298  1.1.6.2  bouyer 	mov.w		(tbl_fdbcc.b,%pc,%d0.w*2),%d1 # load table
   16299  1.1.6.2  bouyer 	jmp		(tbl_fdbcc.b,%pc,%d1.w) # jump to fdbcc routine
   16300  1.1.6.2  bouyer 
   16301  1.1.6.2  bouyer tbl_fdbcc:
   16302  1.1.6.2  bouyer 	short		fdbcc_f		-	tbl_fdbcc	# 00
   16303  1.1.6.2  bouyer 	short		fdbcc_eq	-	tbl_fdbcc	# 01
   16304  1.1.6.2  bouyer 	short		fdbcc_ogt	-	tbl_fdbcc	# 02
   16305  1.1.6.2  bouyer 	short		fdbcc_oge	-	tbl_fdbcc	# 03
   16306  1.1.6.2  bouyer 	short		fdbcc_olt	-	tbl_fdbcc	# 04
   16307  1.1.6.2  bouyer 	short		fdbcc_ole	-	tbl_fdbcc	# 05
   16308  1.1.6.2  bouyer 	short		fdbcc_ogl	-	tbl_fdbcc	# 06
   16309  1.1.6.2  bouyer 	short		fdbcc_or	-	tbl_fdbcc	# 07
   16310  1.1.6.2  bouyer 	short		fdbcc_un	-	tbl_fdbcc	# 08
   16311  1.1.6.2  bouyer 	short		fdbcc_ueq	-	tbl_fdbcc	# 09
   16312  1.1.6.2  bouyer 	short		fdbcc_ugt	-	tbl_fdbcc	# 10
   16313  1.1.6.2  bouyer 	short		fdbcc_uge	-	tbl_fdbcc	# 11
   16314  1.1.6.2  bouyer 	short		fdbcc_ult	-	tbl_fdbcc	# 12
   16315  1.1.6.2  bouyer 	short		fdbcc_ule	-	tbl_fdbcc	# 13
   16316  1.1.6.2  bouyer 	short		fdbcc_neq	-	tbl_fdbcc	# 14
   16317  1.1.6.2  bouyer 	short		fdbcc_t		-	tbl_fdbcc	# 15
   16318  1.1.6.2  bouyer 	short		fdbcc_sf	-	tbl_fdbcc	# 16
   16319  1.1.6.2  bouyer 	short		fdbcc_seq	-	tbl_fdbcc	# 17
   16320  1.1.6.2  bouyer 	short		fdbcc_gt	-	tbl_fdbcc	# 18
   16321  1.1.6.2  bouyer 	short		fdbcc_ge	-	tbl_fdbcc	# 19
   16322  1.1.6.2  bouyer 	short		fdbcc_lt	-	tbl_fdbcc	# 20
   16323  1.1.6.2  bouyer 	short		fdbcc_le	-	tbl_fdbcc	# 21
   16324  1.1.6.2  bouyer 	short		fdbcc_gl	-	tbl_fdbcc	# 22
   16325  1.1.6.2  bouyer 	short		fdbcc_gle	-	tbl_fdbcc	# 23
   16326  1.1.6.2  bouyer 	short		fdbcc_ngle	-	tbl_fdbcc	# 24
   16327  1.1.6.2  bouyer 	short		fdbcc_ngl	-	tbl_fdbcc	# 25
   16328  1.1.6.2  bouyer 	short		fdbcc_nle	-	tbl_fdbcc	# 26
   16329  1.1.6.2  bouyer 	short		fdbcc_nlt	-	tbl_fdbcc	# 27
   16330  1.1.6.2  bouyer 	short		fdbcc_nge	-	tbl_fdbcc	# 28
   16331  1.1.6.2  bouyer 	short		fdbcc_ngt	-	tbl_fdbcc	# 29
   16332  1.1.6.2  bouyer 	short		fdbcc_sneq	-	tbl_fdbcc	# 30
   16333  1.1.6.2  bouyer 	short		fdbcc_st	-	tbl_fdbcc	# 31
   16334  1.1.6.2  bouyer 
   16335  1.1.6.2  bouyer #########################################################################
   16336  1.1.6.2  bouyer #									#
   16337  1.1.6.2  bouyer # IEEE Nonaware tests							#
   16338  1.1.6.2  bouyer #									#
   16339  1.1.6.2  bouyer # For the IEEE nonaware tests, only the false branch changes the 	#
   16340  1.1.6.2  bouyer # counter. However, the true branch may set bsun so we check to see	#
   16341  1.1.6.2  bouyer # if the NAN bit is set, in which case BSUN and AIOP will be set.	#
   16342  1.1.6.2  bouyer #									#
   16343  1.1.6.2  bouyer # The cases EQ and NE are shared by the Aware and Nonaware groups	#
   16344  1.1.6.2  bouyer # and are incapable of setting the BSUN exception bit.			#
   16345  1.1.6.2  bouyer #									#
   16346  1.1.6.2  bouyer # Typically, only one of the two possible branch directions could	#
   16347  1.1.6.2  bouyer # have the NAN bit set.							#
   16348  1.1.6.2  bouyer # (This is assuming the mutual exclusiveness of FPSR cc bit groupings	#
   16349  1.1.6.2  bouyer #  is preserved.)							#
   16350  1.1.6.2  bouyer #									#
   16351  1.1.6.2  bouyer #########################################################################
   16352  1.1.6.2  bouyer 
   16353  1.1.6.2  bouyer #
   16354  1.1.6.2  bouyer # equal:
   16355  1.1.6.2  bouyer #
   16356  1.1.6.2  bouyer #	Z
   16357  1.1.6.2  bouyer #
   16358  1.1.6.2  bouyer fdbcc_eq:
   16359  1.1.6.2  bouyer 	fbeq.w		fdbcc_eq_yes		# equal?
   16360  1.1.6.2  bouyer fdbcc_eq_no:
   16361  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16362  1.1.6.2  bouyer fdbcc_eq_yes:
   16363  1.1.6.2  bouyer 	rts
   16364  1.1.6.2  bouyer 
   16365  1.1.6.2  bouyer #
   16366  1.1.6.2  bouyer # not equal:
   16367  1.1.6.2  bouyer #	_
   16368  1.1.6.2  bouyer #	Z
   16369  1.1.6.2  bouyer #
   16370  1.1.6.2  bouyer fdbcc_neq:
   16371  1.1.6.2  bouyer 	fbneq.w		fdbcc_neq_yes		# not equal?
   16372  1.1.6.2  bouyer fdbcc_neq_no:
   16373  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16374  1.1.6.2  bouyer fdbcc_neq_yes:
   16375  1.1.6.2  bouyer 	rts
   16376  1.1.6.2  bouyer 
   16377  1.1.6.2  bouyer #
   16378  1.1.6.2  bouyer # greater than:
   16379  1.1.6.2  bouyer #	_______
   16380  1.1.6.2  bouyer #	NANvZvN
   16381  1.1.6.2  bouyer #
   16382  1.1.6.2  bouyer fdbcc_gt:
   16383  1.1.6.2  bouyer 	fbgt.w		fdbcc_gt_yes		# greater than?
   16384  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16385  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no;go handle counter
   16386  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16387  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16388  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16389  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16390  1.1.6.2  bouyer fdbcc_gt_yes:
   16391  1.1.6.2  bouyer 	rts					# do nothing
   16392  1.1.6.2  bouyer 
   16393  1.1.6.2  bouyer #
   16394  1.1.6.2  bouyer # not greater than:
   16395  1.1.6.2  bouyer #
   16396  1.1.6.2  bouyer #	NANvZvN
   16397  1.1.6.2  bouyer #
   16398  1.1.6.2  bouyer fdbcc_ngt:
   16399  1.1.6.2  bouyer 	fbngt.w		fdbcc_ngt_yes		# not greater than?
   16400  1.1.6.2  bouyer fdbcc_ngt_no:
   16401  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16402  1.1.6.2  bouyer fdbcc_ngt_yes:
   16403  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16404  1.1.6.2  bouyer 	beq.b		fdbcc_ngt_done		# no;go finish
   16405  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16406  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16407  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16408  1.1.6.2  bouyer fdbcc_ngt_done:
   16409  1.1.6.2  bouyer 	rts					# no; do nothing
   16410  1.1.6.2  bouyer 
   16411  1.1.6.2  bouyer #
   16412  1.1.6.2  bouyer # greater than or equal:
   16413  1.1.6.2  bouyer #	   _____
   16414  1.1.6.2  bouyer #	Zv(NANvN)
   16415  1.1.6.2  bouyer #
   16416  1.1.6.2  bouyer fdbcc_ge:
   16417  1.1.6.2  bouyer 	fbge.w		fdbcc_ge_yes		# greater than or equal?
   16418  1.1.6.2  bouyer fdbcc_ge_no:
   16419  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16420  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no;go handle counter
   16421  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16422  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16423  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16424  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16425  1.1.6.2  bouyer fdbcc_ge_yes:
   16426  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16427  1.1.6.2  bouyer 	beq.b		fdbcc_ge_yes_done	# no;go do nothing
   16428  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16429  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16430  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16431  1.1.6.2  bouyer fdbcc_ge_yes_done:
   16432  1.1.6.2  bouyer 	rts					# do nothing
   16433  1.1.6.2  bouyer 
   16434  1.1.6.2  bouyer #
   16435  1.1.6.2  bouyer # not (greater than or equal):
   16436  1.1.6.2  bouyer #	       _
   16437  1.1.6.2  bouyer #	NANv(N^Z)
   16438  1.1.6.2  bouyer #
   16439  1.1.6.2  bouyer fdbcc_nge:
   16440  1.1.6.2  bouyer 	fbnge.w		fdbcc_nge_yes		# not (greater than or equal)?
   16441  1.1.6.2  bouyer fdbcc_nge_no:
   16442  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16443  1.1.6.2  bouyer fdbcc_nge_yes:
   16444  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16445  1.1.6.2  bouyer 	beq.b		fdbcc_nge_done		# no;go finish
   16446  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16447  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16448  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16449  1.1.6.2  bouyer fdbcc_nge_done:
   16450  1.1.6.2  bouyer 	rts					# no; do nothing
   16451  1.1.6.2  bouyer 
   16452  1.1.6.2  bouyer #
   16453  1.1.6.2  bouyer # less than:
   16454  1.1.6.2  bouyer #	   _____
   16455  1.1.6.2  bouyer #	N^(NANvZ)
   16456  1.1.6.2  bouyer #
   16457  1.1.6.2  bouyer fdbcc_lt:
   16458  1.1.6.2  bouyer 	fblt.w		fdbcc_lt_yes		# less than?
   16459  1.1.6.2  bouyer fdbcc_lt_no:
   16460  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16461  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no; go handle counter
   16462  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16463  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16464  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16465  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16466  1.1.6.2  bouyer fdbcc_lt_yes:
   16467  1.1.6.2  bouyer 	rts					# do nothing
   16468  1.1.6.2  bouyer 
   16469  1.1.6.2  bouyer #
   16470  1.1.6.2  bouyer # not less than:
   16471  1.1.6.2  bouyer #	       _
   16472  1.1.6.2  bouyer #	NANv(ZvN)
   16473  1.1.6.2  bouyer #
   16474  1.1.6.2  bouyer fdbcc_nlt:
   16475  1.1.6.2  bouyer 	fbnlt.w		fdbcc_nlt_yes		# not less than?
   16476  1.1.6.2  bouyer fdbcc_nlt_no:
   16477  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16478  1.1.6.2  bouyer fdbcc_nlt_yes:
   16479  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16480  1.1.6.2  bouyer 	beq.b		fdbcc_nlt_done		# no;go finish
   16481  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16482  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16483  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16484  1.1.6.2  bouyer fdbcc_nlt_done:
   16485  1.1.6.2  bouyer 	rts					# no; do nothing
   16486  1.1.6.2  bouyer 
   16487  1.1.6.2  bouyer #
   16488  1.1.6.2  bouyer # less than or equal:
   16489  1.1.6.2  bouyer #	     ___
   16490  1.1.6.2  bouyer #	Zv(N^NAN)
   16491  1.1.6.2  bouyer #
   16492  1.1.6.2  bouyer fdbcc_le:
   16493  1.1.6.2  bouyer 	fble.w		fdbcc_le_yes		# less than or equal?
   16494  1.1.6.2  bouyer fdbcc_le_no:
   16495  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16496  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no; go handle counter
   16497  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16498  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16499  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16500  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16501  1.1.6.2  bouyer fdbcc_le_yes:
   16502  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16503  1.1.6.2  bouyer 	beq.b		fdbcc_le_yes_done	# no; go do nothing
   16504  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16505  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16506  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16507  1.1.6.2  bouyer fdbcc_le_yes_done:
   16508  1.1.6.2  bouyer 	rts					# do nothing
   16509  1.1.6.2  bouyer 
   16510  1.1.6.2  bouyer #
   16511  1.1.6.2  bouyer # not (less than or equal):
   16512  1.1.6.2  bouyer #	     ___
   16513  1.1.6.2  bouyer #	NANv(NvZ)
   16514  1.1.6.2  bouyer #
   16515  1.1.6.2  bouyer fdbcc_nle:
   16516  1.1.6.2  bouyer 	fbnle.w		fdbcc_nle_yes		# not (less than or equal)?
   16517  1.1.6.2  bouyer fdbcc_nle_no:
   16518  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16519  1.1.6.2  bouyer fdbcc_nle_yes:
   16520  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16521  1.1.6.2  bouyer 	beq.w		fdbcc_nle_done		# no; go finish
   16522  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16523  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16524  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16525  1.1.6.2  bouyer fdbcc_nle_done:
   16526  1.1.6.2  bouyer 	rts					# no; do nothing
   16527  1.1.6.2  bouyer 
   16528  1.1.6.2  bouyer #
   16529  1.1.6.2  bouyer # greater or less than:
   16530  1.1.6.2  bouyer #	_____
   16531  1.1.6.2  bouyer #	NANvZ
   16532  1.1.6.2  bouyer #
   16533  1.1.6.2  bouyer fdbcc_gl:
   16534  1.1.6.2  bouyer 	fbgl.w		fdbcc_gl_yes		# greater or less than?
   16535  1.1.6.2  bouyer fdbcc_gl_no:
   16536  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16537  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no; handle counter
   16538  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16539  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16540  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16541  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16542  1.1.6.2  bouyer fdbcc_gl_yes:
   16543  1.1.6.2  bouyer 	rts					# do nothing
   16544  1.1.6.2  bouyer 
   16545  1.1.6.2  bouyer #
   16546  1.1.6.2  bouyer # not (greater or less than):
   16547  1.1.6.2  bouyer #
   16548  1.1.6.2  bouyer #	NANvZ
   16549  1.1.6.2  bouyer #
   16550  1.1.6.2  bouyer fdbcc_ngl:
   16551  1.1.6.2  bouyer 	fbngl.w		fdbcc_ngl_yes		# not (greater or less than)?
   16552  1.1.6.2  bouyer fdbcc_ngl_no:
   16553  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16554  1.1.6.2  bouyer fdbcc_ngl_yes:
   16555  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   16556  1.1.6.2  bouyer 	beq.b		fdbcc_ngl_done		# no; go finish
   16557  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16558  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16559  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16560  1.1.6.2  bouyer fdbcc_ngl_done:
   16561  1.1.6.2  bouyer 	rts					# no; do nothing
   16562  1.1.6.2  bouyer 
   16563  1.1.6.2  bouyer #
   16564  1.1.6.2  bouyer # greater, less, or equal:
   16565  1.1.6.2  bouyer #	___
   16566  1.1.6.2  bouyer #	NAN
   16567  1.1.6.2  bouyer #
   16568  1.1.6.2  bouyer fdbcc_gle:
   16569  1.1.6.2  bouyer 	fbgle.w		fdbcc_gle_yes		# greater, less, or equal?
   16570  1.1.6.2  bouyer fdbcc_gle_no:
   16571  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16572  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16573  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16574  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16575  1.1.6.2  bouyer fdbcc_gle_yes:
   16576  1.1.6.2  bouyer 	rts					# do nothing
   16577  1.1.6.2  bouyer 
   16578  1.1.6.2  bouyer #
   16579  1.1.6.2  bouyer # not (greater, less, or equal):
   16580  1.1.6.2  bouyer #
   16581  1.1.6.2  bouyer #	NAN
   16582  1.1.6.2  bouyer #
   16583  1.1.6.2  bouyer fdbcc_ngle:
   16584  1.1.6.2  bouyer 	fbngle.w	fdbcc_ngle_yes		# not (greater, less, or equal)?
   16585  1.1.6.2  bouyer fdbcc_ngle_no:
   16586  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16587  1.1.6.2  bouyer fdbcc_ngle_yes:
   16588  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16589  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16590  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16591  1.1.6.2  bouyer 	rts					# no; do nothing
   16592  1.1.6.2  bouyer 
   16593  1.1.6.2  bouyer #########################################################################
   16594  1.1.6.2  bouyer #									#
   16595  1.1.6.2  bouyer # Miscellaneous tests							#
   16596  1.1.6.2  bouyer #									#
   16597  1.1.6.2  bouyer # For the IEEE miscellaneous tests, all but fdbf and fdbt can set bsun. #
   16598  1.1.6.2  bouyer #									#
   16599  1.1.6.2  bouyer #########################################################################
   16600  1.1.6.2  bouyer 
   16601  1.1.6.2  bouyer #
   16602  1.1.6.2  bouyer # false:
   16603  1.1.6.2  bouyer #
   16604  1.1.6.2  bouyer #	False
   16605  1.1.6.2  bouyer #
   16606  1.1.6.2  bouyer fdbcc_f:					# no bsun possible
   16607  1.1.6.2  bouyer 	bra.w		fdbcc_false		# go handle counter
   16608  1.1.6.2  bouyer 
   16609  1.1.6.2  bouyer #
   16610  1.1.6.2  bouyer # true:
   16611  1.1.6.2  bouyer #
   16612  1.1.6.2  bouyer #	True
   16613  1.1.6.2  bouyer #
   16614  1.1.6.2  bouyer fdbcc_t:					# no bsun possible
   16615  1.1.6.2  bouyer 	rts					# do nothing
   16616  1.1.6.2  bouyer 
   16617  1.1.6.2  bouyer #
   16618  1.1.6.2  bouyer # signalling false:
   16619  1.1.6.2  bouyer #
   16620  1.1.6.2  bouyer #	False
   16621  1.1.6.2  bouyer #
   16622  1.1.6.2  bouyer fdbcc_sf:
   16623  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16624  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no;go handle counter
   16625  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16626  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16627  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16628  1.1.6.2  bouyer 	bra.w		fdbcc_false		# go handle counter
   16629  1.1.6.2  bouyer 
   16630  1.1.6.2  bouyer #
   16631  1.1.6.2  bouyer # signalling true:
   16632  1.1.6.2  bouyer #
   16633  1.1.6.2  bouyer #	True
   16634  1.1.6.2  bouyer #
   16635  1.1.6.2  bouyer fdbcc_st:
   16636  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16637  1.1.6.2  bouyer 	beq.b		fdbcc_st_done		# no;go finish
   16638  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16639  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16640  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16641  1.1.6.2  bouyer fdbcc_st_done:
   16642  1.1.6.2  bouyer 	rts
   16643  1.1.6.2  bouyer 
   16644  1.1.6.2  bouyer #
   16645  1.1.6.2  bouyer # signalling equal:
   16646  1.1.6.2  bouyer #
   16647  1.1.6.2  bouyer #	Z
   16648  1.1.6.2  bouyer #
   16649  1.1.6.2  bouyer fdbcc_seq:
   16650  1.1.6.2  bouyer 	fbseq.w		fdbcc_seq_yes		# signalling equal?
   16651  1.1.6.2  bouyer fdbcc_seq_no:
   16652  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16653  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no;go handle counter
   16654  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16655  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16656  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16657  1.1.6.2  bouyer 	bra.w		fdbcc_false		# go handle counter
   16658  1.1.6.2  bouyer fdbcc_seq_yes:
   16659  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16660  1.1.6.2  bouyer 	beq.b		fdbcc_seq_yes_done	# no;go do nothing
   16661  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16662  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16663  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16664  1.1.6.2  bouyer fdbcc_seq_yes_done:
   16665  1.1.6.2  bouyer 	rts					# yes; do nothing
   16666  1.1.6.2  bouyer 
   16667  1.1.6.2  bouyer #
   16668  1.1.6.2  bouyer # signalling not equal:
   16669  1.1.6.2  bouyer #	_
   16670  1.1.6.2  bouyer #	Z
   16671  1.1.6.2  bouyer #
   16672  1.1.6.2  bouyer fdbcc_sneq:
   16673  1.1.6.2  bouyer 	fbsneq.w	fdbcc_sneq_yes		# signalling not equal?
   16674  1.1.6.2  bouyer fdbcc_sneq_no:
   16675  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# is NAN set?
   16676  1.1.6.2  bouyer 	beq.w		fdbcc_false		# no;go handle counter
   16677  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16678  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16679  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16680  1.1.6.2  bouyer 	bra.w		fdbcc_false		# go handle counter
   16681  1.1.6.2  bouyer fdbcc_sneq_yes:
   16682  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   16683  1.1.6.2  bouyer 	beq.w		fdbcc_sneq_done		# no;go finish
   16684  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   16685  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
   16686  1.1.6.2  bouyer 	bne.w		fdbcc_bsun		# yes; we have an exception
   16687  1.1.6.2  bouyer fdbcc_sneq_done:
   16688  1.1.6.2  bouyer 	rts
   16689  1.1.6.2  bouyer 
   16690  1.1.6.2  bouyer #########################################################################
   16691  1.1.6.2  bouyer #									#
   16692  1.1.6.2  bouyer # IEEE Aware tests							#
   16693  1.1.6.2  bouyer #									#
   16694  1.1.6.2  bouyer # For the IEEE aware tests, action is only taken if the result is false.#
   16695  1.1.6.2  bouyer # Therefore, the opposite branch type is used to jump to the decrement	#
   16696  1.1.6.2  bouyer # routine. 								#
   16697  1.1.6.2  bouyer # The BSUN exception will not be set for any of these tests.		#
   16698  1.1.6.2  bouyer #									#
   16699  1.1.6.2  bouyer #########################################################################
   16700  1.1.6.2  bouyer 
   16701  1.1.6.2  bouyer #
   16702  1.1.6.2  bouyer # ordered greater than:
   16703  1.1.6.2  bouyer #	_______
   16704  1.1.6.2  bouyer #	NANvZvN
   16705  1.1.6.2  bouyer #
   16706  1.1.6.2  bouyer fdbcc_ogt:
   16707  1.1.6.2  bouyer 	fbogt.w		fdbcc_ogt_yes		# ordered greater than?
   16708  1.1.6.2  bouyer fdbcc_ogt_no:
   16709  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16710  1.1.6.2  bouyer fdbcc_ogt_yes:
   16711  1.1.6.2  bouyer 	rts					# yes; do nothing
   16712  1.1.6.2  bouyer 
   16713  1.1.6.2  bouyer #
   16714  1.1.6.2  bouyer # unordered or less or equal:
   16715  1.1.6.2  bouyer #	_______
   16716  1.1.6.2  bouyer #	NANvZvN
   16717  1.1.6.2  bouyer #
   16718  1.1.6.2  bouyer fdbcc_ule:
   16719  1.1.6.2  bouyer 	fbule.w		fdbcc_ule_yes		# unordered or less or equal?
   16720  1.1.6.2  bouyer fdbcc_ule_no:
   16721  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16722  1.1.6.2  bouyer fdbcc_ule_yes:
   16723  1.1.6.2  bouyer 	rts					# yes; do nothing
   16724  1.1.6.2  bouyer 
   16725  1.1.6.2  bouyer #
   16726  1.1.6.2  bouyer # ordered greater than or equal:
   16727  1.1.6.2  bouyer #	   _____
   16728  1.1.6.2  bouyer #	Zv(NANvN)
   16729  1.1.6.2  bouyer #
   16730  1.1.6.2  bouyer fdbcc_oge:
   16731  1.1.6.2  bouyer 	fboge.w		fdbcc_oge_yes		# ordered greater than or equal?
   16732  1.1.6.2  bouyer fdbcc_oge_no:
   16733  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16734  1.1.6.2  bouyer fdbcc_oge_yes:
   16735  1.1.6.2  bouyer 	rts					# yes; do nothing
   16736  1.1.6.2  bouyer 
   16737  1.1.6.2  bouyer #
   16738  1.1.6.2  bouyer # unordered or less than:
   16739  1.1.6.2  bouyer #	       _
   16740  1.1.6.2  bouyer #	NANv(N^Z)
   16741  1.1.6.2  bouyer #
   16742  1.1.6.2  bouyer fdbcc_ult:
   16743  1.1.6.2  bouyer 	fbult.w		fdbcc_ult_yes		# unordered or less than?
   16744  1.1.6.2  bouyer fdbcc_ult_no:
   16745  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16746  1.1.6.2  bouyer fdbcc_ult_yes:
   16747  1.1.6.2  bouyer 	rts					# yes; do nothing
   16748  1.1.6.2  bouyer 
   16749  1.1.6.2  bouyer #
   16750  1.1.6.2  bouyer # ordered less than:
   16751  1.1.6.2  bouyer #	   _____
   16752  1.1.6.2  bouyer #	N^(NANvZ)
   16753  1.1.6.2  bouyer #
   16754  1.1.6.2  bouyer fdbcc_olt:
   16755  1.1.6.2  bouyer 	fbolt.w		fdbcc_olt_yes		# ordered less than?
   16756  1.1.6.2  bouyer fdbcc_olt_no:
   16757  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16758  1.1.6.2  bouyer fdbcc_olt_yes:
   16759  1.1.6.2  bouyer 	rts					# yes; do nothing
   16760  1.1.6.2  bouyer 
   16761  1.1.6.2  bouyer #
   16762  1.1.6.2  bouyer # unordered or greater or equal:
   16763  1.1.6.2  bouyer #
   16764  1.1.6.2  bouyer #	NANvZvN
   16765  1.1.6.2  bouyer #
   16766  1.1.6.2  bouyer fdbcc_uge:
   16767  1.1.6.2  bouyer 	fbuge.w		fdbcc_uge_yes		# unordered or greater than?
   16768  1.1.6.2  bouyer fdbcc_uge_no:
   16769  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16770  1.1.6.2  bouyer fdbcc_uge_yes:
   16771  1.1.6.2  bouyer 	rts					# yes; do nothing
   16772  1.1.6.2  bouyer 
   16773  1.1.6.2  bouyer #
   16774  1.1.6.2  bouyer # ordered less than or equal:
   16775  1.1.6.2  bouyer #	     ___
   16776  1.1.6.2  bouyer #	Zv(N^NAN)
   16777  1.1.6.2  bouyer #
   16778  1.1.6.2  bouyer fdbcc_ole:
   16779  1.1.6.2  bouyer 	fbole.w		fdbcc_ole_yes		# ordered greater or less than?
   16780  1.1.6.2  bouyer fdbcc_ole_no:
   16781  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16782  1.1.6.2  bouyer fdbcc_ole_yes:
   16783  1.1.6.2  bouyer 	rts					# yes; do nothing
   16784  1.1.6.2  bouyer 
   16785  1.1.6.2  bouyer #
   16786  1.1.6.2  bouyer # unordered or greater than:
   16787  1.1.6.2  bouyer #	     ___
   16788  1.1.6.2  bouyer #	NANv(NvZ)
   16789  1.1.6.2  bouyer #
   16790  1.1.6.2  bouyer fdbcc_ugt:
   16791  1.1.6.2  bouyer 	fbugt.w		fdbcc_ugt_yes		# unordered or greater than?
   16792  1.1.6.2  bouyer fdbcc_ugt_no:
   16793  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16794  1.1.6.2  bouyer fdbcc_ugt_yes:
   16795  1.1.6.2  bouyer 	rts					# yes; do nothing
   16796  1.1.6.2  bouyer 
   16797  1.1.6.2  bouyer #
   16798  1.1.6.2  bouyer # ordered greater or less than:
   16799  1.1.6.2  bouyer #	_____
   16800  1.1.6.2  bouyer #	NANvZ
   16801  1.1.6.2  bouyer #
   16802  1.1.6.2  bouyer fdbcc_ogl:
   16803  1.1.6.2  bouyer 	fbogl.w		fdbcc_ogl_yes		# ordered greater or less than?
   16804  1.1.6.2  bouyer fdbcc_ogl_no:
   16805  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16806  1.1.6.2  bouyer fdbcc_ogl_yes:
   16807  1.1.6.2  bouyer 	rts					# yes; do nothing
   16808  1.1.6.2  bouyer 
   16809  1.1.6.2  bouyer #
   16810  1.1.6.2  bouyer # unordered or equal:
   16811  1.1.6.2  bouyer #
   16812  1.1.6.2  bouyer #	NANvZ
   16813  1.1.6.2  bouyer #
   16814  1.1.6.2  bouyer fdbcc_ueq:
   16815  1.1.6.2  bouyer 	fbueq.w		fdbcc_ueq_yes		# unordered or equal?
   16816  1.1.6.2  bouyer fdbcc_ueq_no:
   16817  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16818  1.1.6.2  bouyer fdbcc_ueq_yes:
   16819  1.1.6.2  bouyer 	rts					# yes; do nothing
   16820  1.1.6.2  bouyer 
   16821  1.1.6.2  bouyer #
   16822  1.1.6.2  bouyer # ordered:
   16823  1.1.6.2  bouyer #	___
   16824  1.1.6.2  bouyer #	NAN
   16825  1.1.6.2  bouyer #
   16826  1.1.6.2  bouyer fdbcc_or:
   16827  1.1.6.2  bouyer 	fbor.w		fdbcc_or_yes		# ordered?
   16828  1.1.6.2  bouyer fdbcc_or_no:
   16829  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16830  1.1.6.2  bouyer fdbcc_or_yes:
   16831  1.1.6.2  bouyer 	rts					# yes; do nothing
   16832  1.1.6.2  bouyer 
   16833  1.1.6.2  bouyer #
   16834  1.1.6.2  bouyer # unordered:
   16835  1.1.6.2  bouyer #
   16836  1.1.6.2  bouyer #	NAN
   16837  1.1.6.2  bouyer #
   16838  1.1.6.2  bouyer fdbcc_un:
   16839  1.1.6.2  bouyer 	fbun.w		fdbcc_un_yes		# unordered?
   16840  1.1.6.2  bouyer fdbcc_un_no:
   16841  1.1.6.2  bouyer 	bra.w		fdbcc_false		# no; go handle counter
   16842  1.1.6.2  bouyer fdbcc_un_yes:
   16843  1.1.6.2  bouyer 	rts					# yes; do nothing
   16844  1.1.6.2  bouyer 
   16845  1.1.6.2  bouyer #######################################################################
   16846  1.1.6.2  bouyer 
   16847  1.1.6.2  bouyer #
   16848  1.1.6.2  bouyer # the bsun exception bit was not set.
   16849  1.1.6.2  bouyer #
   16850  1.1.6.2  bouyer # (1) subtract 1 from the count register
   16851  1.1.6.2  bouyer # (2) if (cr == -1) then
   16852  1.1.6.2  bouyer #	pc = pc of next instruction
   16853  1.1.6.2  bouyer #     else
   16854  1.1.6.2  bouyer #	pc += sign_ext(16-bit displacement)
   16855  1.1.6.2  bouyer #
   16856  1.1.6.2  bouyer fdbcc_false:
   16857  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6), %d1	# fetch lo opword
   16858  1.1.6.2  bouyer 	andi.w		&0x7, %d1		# extract count register
   16859  1.1.6.2  bouyer 
   16860  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch count value
   16861  1.1.6.2  bouyer # make sure that d0 isn't corrupted between calls...
   16862  1.1.6.2  bouyer 
   16863  1.1.6.2  bouyer 	subq.w		&0x1, %d0		# Dn - 1 -> Dn
   16864  1.1.6.2  bouyer 
   16865  1.1.6.2  bouyer 	bsr.l		store_dreg_l		# store new count value
   16866  1.1.6.2  bouyer 
   16867  1.1.6.2  bouyer 	cmpi.w		%d0, &-0x1		# is (Dn == -1)?
   16868  1.1.6.2  bouyer 	bne.b		fdbcc_false_cont	# no;
   16869  1.1.6.2  bouyer 	rts
   16870  1.1.6.2  bouyer 
   16871  1.1.6.2  bouyer fdbcc_false_cont:
   16872  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d0		# fetch displacement
   16873  1.1.6.2  bouyer 	add.l		USER_FPIAR(%a6),%d0	# add instruction PC
   16874  1.1.6.2  bouyer 	addq.l		&0x4,%d0		# add instruction length
   16875  1.1.6.2  bouyer 	mov.l		%d0,EXC_PC(%a6)		# set new PC
   16876  1.1.6.2  bouyer 	rts
   16877  1.1.6.2  bouyer 
   16878  1.1.6.2  bouyer # the emulation routine set bsun and BSUN was enabled. have to
   16879  1.1.6.2  bouyer # fix stack and jump to the bsun handler.
   16880  1.1.6.2  bouyer # let the caller of this routine shift the stack frame up to
   16881  1.1.6.2  bouyer # eliminate the effective address field.
   16882  1.1.6.2  bouyer fdbcc_bsun:
   16883  1.1.6.2  bouyer 	mov.b		&fbsun_flg,SPCOND_FLG(%a6)
   16884  1.1.6.2  bouyer 	rts
   16885  1.1.6.2  bouyer 
   16886  1.1.6.2  bouyer #########################################################################
   16887  1.1.6.2  bouyer # ftrapcc(): routine to emulate the ftrapcc instruction			#
   16888  1.1.6.2  bouyer #									#
   16889  1.1.6.2  bouyer # XDEF ****************************************************************	#
   16890  1.1.6.2  bouyer #	_ftrapcc()							#
   16891  1.1.6.2  bouyer #									#
   16892  1.1.6.2  bouyer # XREF ****************************************************************	#
   16893  1.1.6.2  bouyer #	none								#
   16894  1.1.6.2  bouyer #									#
   16895  1.1.6.2  bouyer # INPUT *************************************************************** #
   16896  1.1.6.2  bouyer #	none								#
   16897  1.1.6.2  bouyer #									#
   16898  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   16899  1.1.6.2  bouyer #	none								#
   16900  1.1.6.2  bouyer #									#
   16901  1.1.6.2  bouyer # ALGORITHM *********************************************************** #
   16902  1.1.6.2  bouyer #	This routine checks which conditional predicate is specified by	#
   16903  1.1.6.2  bouyer # the stacked ftrapcc instruction opcode and then branches to a routine	#
   16904  1.1.6.2  bouyer # for that predicate. The corresponding fbcc instruction is then used	#
   16905  1.1.6.2  bouyer # to see whether the condition (specified by the stacked FPSR) is true	#
   16906  1.1.6.2  bouyer # or false.								#
   16907  1.1.6.2  bouyer #	If a BSUN exception should be indicated, the BSUN and ABSUN	#
   16908  1.1.6.2  bouyer # bits are set in the stacked FPSR. If the BSUN exception is enabled,	#
   16909  1.1.6.2  bouyer # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an 	#
   16910  1.1.6.2  bouyer # enabled BSUN should not be flagged and the predicate is true, then	#
   16911  1.1.6.2  bouyer # the ftrapcc_flg is set in the SPCOND_FLG location. These special	#
   16912  1.1.6.2  bouyer # flags indicate to the calling routine to emulate the exceptional	#
   16913  1.1.6.2  bouyer # condition.								#
   16914  1.1.6.2  bouyer #									#
   16915  1.1.6.2  bouyer #########################################################################
   16916  1.1.6.2  bouyer 
   16917  1.1.6.2  bouyer 	global		_ftrapcc
   16918  1.1.6.2  bouyer _ftrapcc:
   16919  1.1.6.2  bouyer 	mov.w		EXC_CMDREG(%a6),%d0	# fetch predicate
   16920  1.1.6.2  bouyer 
   16921  1.1.6.2  bouyer 	clr.l		%d1			# clear scratch reg
   16922  1.1.6.2  bouyer 	mov.b		FPSR_CC(%a6),%d1	# fetch fp ccodes
   16923  1.1.6.2  bouyer 	ror.l		&0x8,%d1		# rotate to top byte
   16924  1.1.6.2  bouyer 	fmov.l		%d1,%fpsr		# insert into FPSR
   16925  1.1.6.2  bouyer 
   16926  1.1.6.2  bouyer 	mov.w		(tbl_ftrapcc.b,%pc,%d0.w*2), %d1 # load table
   16927  1.1.6.2  bouyer 	jmp		(tbl_ftrapcc.b,%pc,%d1.w) # jump to ftrapcc routine
   16928  1.1.6.2  bouyer 
   16929  1.1.6.2  bouyer tbl_ftrapcc:
   16930  1.1.6.2  bouyer 	short		ftrapcc_f	-	tbl_ftrapcc	# 00
   16931  1.1.6.2  bouyer 	short		ftrapcc_eq	-	tbl_ftrapcc	# 01
   16932  1.1.6.2  bouyer 	short		ftrapcc_ogt	-	tbl_ftrapcc	# 02
   16933  1.1.6.2  bouyer 	short		ftrapcc_oge	-	tbl_ftrapcc	# 03
   16934  1.1.6.2  bouyer 	short		ftrapcc_olt	-	tbl_ftrapcc	# 04
   16935  1.1.6.2  bouyer 	short		ftrapcc_ole	-	tbl_ftrapcc	# 05
   16936  1.1.6.2  bouyer 	short		ftrapcc_ogl	-	tbl_ftrapcc	# 06
   16937  1.1.6.2  bouyer 	short		ftrapcc_or	-	tbl_ftrapcc	# 07
   16938  1.1.6.2  bouyer 	short		ftrapcc_un	-	tbl_ftrapcc	# 08
   16939  1.1.6.2  bouyer 	short		ftrapcc_ueq	-	tbl_ftrapcc	# 09
   16940  1.1.6.2  bouyer 	short		ftrapcc_ugt	-	tbl_ftrapcc	# 10
   16941  1.1.6.2  bouyer 	short		ftrapcc_uge	-	tbl_ftrapcc	# 11
   16942  1.1.6.2  bouyer 	short		ftrapcc_ult	-	tbl_ftrapcc	# 12
   16943  1.1.6.2  bouyer 	short		ftrapcc_ule	-	tbl_ftrapcc	# 13
   16944  1.1.6.2  bouyer 	short		ftrapcc_neq	-	tbl_ftrapcc	# 14
   16945  1.1.6.2  bouyer 	short		ftrapcc_t	-	tbl_ftrapcc	# 15
   16946  1.1.6.2  bouyer 	short		ftrapcc_sf	-	tbl_ftrapcc	# 16
   16947  1.1.6.2  bouyer 	short		ftrapcc_seq	-	tbl_ftrapcc	# 17
   16948  1.1.6.2  bouyer 	short		ftrapcc_gt	-	tbl_ftrapcc	# 18
   16949  1.1.6.2  bouyer 	short		ftrapcc_ge	-	tbl_ftrapcc	# 19
   16950  1.1.6.2  bouyer 	short		ftrapcc_lt	-	tbl_ftrapcc	# 20
   16951  1.1.6.2  bouyer 	short		ftrapcc_le	-	tbl_ftrapcc	# 21
   16952  1.1.6.2  bouyer 	short		ftrapcc_gl	-	tbl_ftrapcc	# 22
   16953  1.1.6.2  bouyer 	short		ftrapcc_gle	-	tbl_ftrapcc	# 23
   16954  1.1.6.2  bouyer 	short		ftrapcc_ngle	-	tbl_ftrapcc	# 24
   16955  1.1.6.2  bouyer 	short		ftrapcc_ngl	-	tbl_ftrapcc	# 25
   16956  1.1.6.2  bouyer 	short		ftrapcc_nle	-	tbl_ftrapcc	# 26
   16957  1.1.6.2  bouyer 	short		ftrapcc_nlt	-	tbl_ftrapcc	# 27
   16958  1.1.6.2  bouyer 	short		ftrapcc_nge	-	tbl_ftrapcc	# 28
   16959  1.1.6.2  bouyer 	short		ftrapcc_ngt	-	tbl_ftrapcc	# 29
   16960  1.1.6.2  bouyer 	short		ftrapcc_sneq	-	tbl_ftrapcc	# 30
   16961  1.1.6.2  bouyer 	short		ftrapcc_st	-	tbl_ftrapcc	# 31
   16962  1.1.6.2  bouyer 
   16963  1.1.6.2  bouyer #########################################################################
   16964  1.1.6.2  bouyer #									#
   16965  1.1.6.2  bouyer # IEEE Nonaware tests							#
   16966  1.1.6.2  bouyer #									#
   16967  1.1.6.2  bouyer # For the IEEE nonaware tests, we set the result based on the		#
   16968  1.1.6.2  bouyer # floating point condition codes. In addition, we check to see		#
   16969  1.1.6.2  bouyer # if the NAN bit is set, in which case BSUN and AIOP will be set.	#
   16970  1.1.6.2  bouyer #									#
   16971  1.1.6.2  bouyer # The cases EQ and NE are shared by the Aware and Nonaware groups	#
   16972  1.1.6.2  bouyer # and are incapable of setting the BSUN exception bit.			#
   16973  1.1.6.2  bouyer #									#
   16974  1.1.6.2  bouyer # Typically, only one of the two possible branch directions could	#
   16975  1.1.6.2  bouyer # have the NAN bit set.							#
   16976  1.1.6.2  bouyer #									#
   16977  1.1.6.2  bouyer #########################################################################
   16978  1.1.6.2  bouyer 
   16979  1.1.6.2  bouyer #
   16980  1.1.6.2  bouyer # equal:
   16981  1.1.6.2  bouyer #
   16982  1.1.6.2  bouyer #	Z
   16983  1.1.6.2  bouyer #
   16984  1.1.6.2  bouyer ftrapcc_eq:
   16985  1.1.6.2  bouyer 	fbeq.w		ftrapcc_trap		# equal?
   16986  1.1.6.2  bouyer ftrapcc_eq_no:
   16987  1.1.6.2  bouyer 	rts					# do nothing
   16988  1.1.6.2  bouyer 
   16989  1.1.6.2  bouyer #
   16990  1.1.6.2  bouyer # not equal:
   16991  1.1.6.2  bouyer #	_
   16992  1.1.6.2  bouyer #	Z
   16993  1.1.6.2  bouyer #
   16994  1.1.6.2  bouyer ftrapcc_neq:
   16995  1.1.6.2  bouyer 	fbneq.w		ftrapcc_trap		# not equal?
   16996  1.1.6.2  bouyer ftrapcc_neq_no:
   16997  1.1.6.2  bouyer 	rts					# do nothing
   16998  1.1.6.2  bouyer 
   16999  1.1.6.2  bouyer #
   17000  1.1.6.2  bouyer # greater than:
   17001  1.1.6.2  bouyer #	_______
   17002  1.1.6.2  bouyer #	NANvZvN
   17003  1.1.6.2  bouyer #
   17004  1.1.6.2  bouyer ftrapcc_gt:
   17005  1.1.6.2  bouyer 	fbgt.w		ftrapcc_trap		# greater than?
   17006  1.1.6.2  bouyer ftrapcc_gt_no:
   17007  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17008  1.1.6.2  bouyer 	beq.b		ftrapcc_gt_done		# no
   17009  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17010  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17011  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17012  1.1.6.2  bouyer ftrapcc_gt_done:
   17013  1.1.6.2  bouyer 	rts					# no; do nothing
   17014  1.1.6.2  bouyer 
   17015  1.1.6.2  bouyer #
   17016  1.1.6.2  bouyer # not greater than:
   17017  1.1.6.2  bouyer #
   17018  1.1.6.2  bouyer #	NANvZvN
   17019  1.1.6.2  bouyer #
   17020  1.1.6.2  bouyer ftrapcc_ngt:
   17021  1.1.6.2  bouyer 	fbngt.w		ftrapcc_ngt_yes		# not greater than?
   17022  1.1.6.2  bouyer ftrapcc_ngt_no:
   17023  1.1.6.2  bouyer 	rts					# do nothing
   17024  1.1.6.2  bouyer ftrapcc_ngt_yes:
   17025  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17026  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17027  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17028  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17029  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17030  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17031  1.1.6.2  bouyer 
   17032  1.1.6.2  bouyer #
   17033  1.1.6.2  bouyer # greater than or equal:
   17034  1.1.6.2  bouyer #	   _____
   17035  1.1.6.2  bouyer #	Zv(NANvN)
   17036  1.1.6.2  bouyer #
   17037  1.1.6.2  bouyer ftrapcc_ge:
   17038  1.1.6.2  bouyer 	fbge.w		ftrapcc_ge_yes		# greater than or equal?
   17039  1.1.6.2  bouyer ftrapcc_ge_no:
   17040  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17041  1.1.6.2  bouyer 	beq.b		ftrapcc_ge_done		# no; go finish
   17042  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17043  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17044  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17045  1.1.6.2  bouyer ftrapcc_ge_done:
   17046  1.1.6.2  bouyer 	rts					# no; do nothing
   17047  1.1.6.2  bouyer ftrapcc_ge_yes:
   17048  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17049  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17050  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17051  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17052  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17053  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17054  1.1.6.2  bouyer 
   17055  1.1.6.2  bouyer #
   17056  1.1.6.2  bouyer # not (greater than or equal):
   17057  1.1.6.2  bouyer #	       _
   17058  1.1.6.2  bouyer #	NANv(N^Z)
   17059  1.1.6.2  bouyer #
   17060  1.1.6.2  bouyer ftrapcc_nge:
   17061  1.1.6.2  bouyer 	fbnge.w		ftrapcc_nge_yes		# not (greater than or equal)?
   17062  1.1.6.2  bouyer ftrapcc_nge_no:
   17063  1.1.6.2  bouyer 	rts					# do nothing
   17064  1.1.6.2  bouyer ftrapcc_nge_yes:
   17065  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17066  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17067  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17068  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17069  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17070  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17071  1.1.6.2  bouyer 
   17072  1.1.6.2  bouyer #
   17073  1.1.6.2  bouyer # less than:
   17074  1.1.6.2  bouyer #	   _____
   17075  1.1.6.2  bouyer #	N^(NANvZ)
   17076  1.1.6.2  bouyer #
   17077  1.1.6.2  bouyer ftrapcc_lt:
   17078  1.1.6.2  bouyer 	fblt.w		ftrapcc_trap		# less than?
   17079  1.1.6.2  bouyer ftrapcc_lt_no:
   17080  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17081  1.1.6.2  bouyer 	beq.b		ftrapcc_lt_done		# no; go finish
   17082  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17083  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17084  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17085  1.1.6.2  bouyer ftrapcc_lt_done:
   17086  1.1.6.2  bouyer 	rts					# no; do nothing
   17087  1.1.6.2  bouyer 
   17088  1.1.6.2  bouyer #
   17089  1.1.6.2  bouyer # not less than:
   17090  1.1.6.2  bouyer #	       _
   17091  1.1.6.2  bouyer #	NANv(ZvN)
   17092  1.1.6.2  bouyer #
   17093  1.1.6.2  bouyer ftrapcc_nlt:
   17094  1.1.6.2  bouyer 	fbnlt.w		ftrapcc_nlt_yes		# not less than?
   17095  1.1.6.2  bouyer ftrapcc_nlt_no:
   17096  1.1.6.2  bouyer 	rts					# do nothing
   17097  1.1.6.2  bouyer ftrapcc_nlt_yes:
   17098  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17099  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17100  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17101  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17102  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17103  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17104  1.1.6.2  bouyer 
   17105  1.1.6.2  bouyer #
   17106  1.1.6.2  bouyer # less than or equal:
   17107  1.1.6.2  bouyer #	     ___
   17108  1.1.6.2  bouyer #	Zv(N^NAN)
   17109  1.1.6.2  bouyer #
   17110  1.1.6.2  bouyer ftrapcc_le:
   17111  1.1.6.2  bouyer 	fble.w		ftrapcc_le_yes		# less than or equal?
   17112  1.1.6.2  bouyer ftrapcc_le_no:
   17113  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17114  1.1.6.2  bouyer 	beq.b		ftrapcc_le_done		# no; go finish
   17115  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17116  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17117  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17118  1.1.6.2  bouyer ftrapcc_le_done:
   17119  1.1.6.2  bouyer 	rts					# no; do nothing
   17120  1.1.6.2  bouyer ftrapcc_le_yes:
   17121  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17122  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17123  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17124  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17125  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17126  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17127  1.1.6.2  bouyer 
   17128  1.1.6.2  bouyer #
   17129  1.1.6.2  bouyer # not (less than or equal):
   17130  1.1.6.2  bouyer #	     ___
   17131  1.1.6.2  bouyer #	NANv(NvZ)
   17132  1.1.6.2  bouyer #
   17133  1.1.6.2  bouyer ftrapcc_nle:
   17134  1.1.6.2  bouyer 	fbnle.w		ftrapcc_nle_yes		# not (less than or equal)?
   17135  1.1.6.2  bouyer ftrapcc_nle_no:
   17136  1.1.6.2  bouyer 	rts					# do nothing
   17137  1.1.6.2  bouyer ftrapcc_nle_yes:
   17138  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17139  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17140  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17141  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17142  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17143  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17144  1.1.6.2  bouyer 
   17145  1.1.6.2  bouyer #
   17146  1.1.6.2  bouyer # greater or less than:
   17147  1.1.6.2  bouyer #	_____
   17148  1.1.6.2  bouyer #	NANvZ
   17149  1.1.6.2  bouyer #
   17150  1.1.6.2  bouyer ftrapcc_gl:
   17151  1.1.6.2  bouyer 	fbgl.w		ftrapcc_trap		# greater or less than?
   17152  1.1.6.2  bouyer ftrapcc_gl_no:
   17153  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17154  1.1.6.2  bouyer 	beq.b		ftrapcc_gl_done		# no; go finish
   17155  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17156  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17157  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17158  1.1.6.2  bouyer ftrapcc_gl_done:
   17159  1.1.6.2  bouyer 	rts					# no; do nothing
   17160  1.1.6.2  bouyer 
   17161  1.1.6.2  bouyer #
   17162  1.1.6.2  bouyer # not (greater or less than):
   17163  1.1.6.2  bouyer #
   17164  1.1.6.2  bouyer #	NANvZ
   17165  1.1.6.2  bouyer #
   17166  1.1.6.2  bouyer ftrapcc_ngl:
   17167  1.1.6.2  bouyer 	fbngl.w		ftrapcc_ngl_yes		# not (greater or less than)?
   17168  1.1.6.2  bouyer ftrapcc_ngl_no:
   17169  1.1.6.2  bouyer 	rts					# do nothing
   17170  1.1.6.2  bouyer ftrapcc_ngl_yes:
   17171  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17172  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17173  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17174  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17175  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17176  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17177  1.1.6.2  bouyer 
   17178  1.1.6.2  bouyer #
   17179  1.1.6.2  bouyer # greater, less, or equal:
   17180  1.1.6.2  bouyer #	___
   17181  1.1.6.2  bouyer #	NAN
   17182  1.1.6.2  bouyer #
   17183  1.1.6.2  bouyer ftrapcc_gle:
   17184  1.1.6.2  bouyer 	fbgle.w		ftrapcc_trap		# greater, less, or equal?
   17185  1.1.6.2  bouyer ftrapcc_gle_no:
   17186  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17187  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17188  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17189  1.1.6.2  bouyer 	rts					# no; do nothing
   17190  1.1.6.2  bouyer 
   17191  1.1.6.2  bouyer #
   17192  1.1.6.2  bouyer # not (greater, less, or equal):
   17193  1.1.6.2  bouyer #
   17194  1.1.6.2  bouyer #	NAN
   17195  1.1.6.2  bouyer #
   17196  1.1.6.2  bouyer ftrapcc_ngle:
   17197  1.1.6.2  bouyer 	fbngle.w	ftrapcc_ngle_yes	# not (greater, less, or equal)?
   17198  1.1.6.2  bouyer ftrapcc_ngle_no:
   17199  1.1.6.2  bouyer 	rts					# do nothing
   17200  1.1.6.2  bouyer ftrapcc_ngle_yes:
   17201  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17202  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17203  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17204  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17205  1.1.6.2  bouyer 
   17206  1.1.6.2  bouyer #########################################################################
   17207  1.1.6.2  bouyer #									#
   17208  1.1.6.2  bouyer # Miscellaneous tests							#
   17209  1.1.6.2  bouyer #									#
   17210  1.1.6.2  bouyer # For the IEEE aware tests, we only have to set the result based on the	#
   17211  1.1.6.2  bouyer # floating point condition codes. The BSUN exception will not be	#
   17212  1.1.6.2  bouyer # set for any of these tests.						#
   17213  1.1.6.2  bouyer #									#
   17214  1.1.6.2  bouyer #########################################################################
   17215  1.1.6.2  bouyer 
   17216  1.1.6.2  bouyer #
   17217  1.1.6.2  bouyer # false:
   17218  1.1.6.2  bouyer #
   17219  1.1.6.2  bouyer #	False
   17220  1.1.6.2  bouyer #
   17221  1.1.6.2  bouyer ftrapcc_f:
   17222  1.1.6.2  bouyer 	rts					# do nothing
   17223  1.1.6.2  bouyer 
   17224  1.1.6.2  bouyer #
   17225  1.1.6.2  bouyer # true:
   17226  1.1.6.2  bouyer #
   17227  1.1.6.2  bouyer #	True
   17228  1.1.6.2  bouyer #
   17229  1.1.6.2  bouyer ftrapcc_t:
   17230  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# go take trap
   17231  1.1.6.2  bouyer 
   17232  1.1.6.2  bouyer #
   17233  1.1.6.2  bouyer # signalling false:
   17234  1.1.6.2  bouyer #
   17235  1.1.6.2  bouyer #	False
   17236  1.1.6.2  bouyer #
   17237  1.1.6.2  bouyer ftrapcc_sf:
   17238  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17239  1.1.6.2  bouyer 	beq.b		ftrapcc_sf_done		# no; go finish
   17240  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17241  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17242  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17243  1.1.6.2  bouyer ftrapcc_sf_done:
   17244  1.1.6.2  bouyer 	rts					# no; do nothing
   17245  1.1.6.2  bouyer 
   17246  1.1.6.2  bouyer #
   17247  1.1.6.2  bouyer # signalling true:
   17248  1.1.6.2  bouyer #
   17249  1.1.6.2  bouyer #	True
   17250  1.1.6.2  bouyer #
   17251  1.1.6.2  bouyer ftrapcc_st:
   17252  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17253  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17254  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17255  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17256  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17257  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17258  1.1.6.2  bouyer 
   17259  1.1.6.2  bouyer #
   17260  1.1.6.2  bouyer # signalling equal:
   17261  1.1.6.2  bouyer #
   17262  1.1.6.2  bouyer #	Z
   17263  1.1.6.2  bouyer #
   17264  1.1.6.2  bouyer ftrapcc_seq:
   17265  1.1.6.2  bouyer 	fbseq.w		ftrapcc_seq_yes		# signalling equal?
   17266  1.1.6.2  bouyer ftrapcc_seq_no:
   17267  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17268  1.1.6.2  bouyer 	beq.w		ftrapcc_seq_done	# no; go finish
   17269  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17270  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17271  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17272  1.1.6.2  bouyer ftrapcc_seq_done:
   17273  1.1.6.2  bouyer 	rts					# no; do nothing
   17274  1.1.6.2  bouyer ftrapcc_seq_yes:
   17275  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17276  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17277  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17278  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17279  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17280  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17281  1.1.6.2  bouyer 
   17282  1.1.6.2  bouyer #
   17283  1.1.6.2  bouyer # signalling not equal:
   17284  1.1.6.2  bouyer #	_
   17285  1.1.6.2  bouyer #	Z
   17286  1.1.6.2  bouyer #
   17287  1.1.6.2  bouyer ftrapcc_sneq:
   17288  1.1.6.2  bouyer 	fbsneq.w	ftrapcc_sneq_yes	# signalling equal?
   17289  1.1.6.2  bouyer ftrapcc_sneq_no:
   17290  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17291  1.1.6.2  bouyer 	beq.w		ftrapcc_sneq_no_done	# no; go finish
   17292  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17293  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17294  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17295  1.1.6.2  bouyer ftrapcc_sneq_no_done:
   17296  1.1.6.2  bouyer 	rts					# do nothing
   17297  1.1.6.2  bouyer ftrapcc_sneq_yes:
   17298  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17299  1.1.6.2  bouyer 	beq.w		ftrapcc_trap		# no; go take trap
   17300  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17301  1.1.6.2  bouyer 	btst		&bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
   17302  1.1.6.2  bouyer 	bne.w		ftrapcc_bsun		# yes
   17303  1.1.6.2  bouyer 	bra.w		ftrapcc_trap		# no; go take trap
   17304  1.1.6.2  bouyer 
   17305  1.1.6.2  bouyer #########################################################################
   17306  1.1.6.2  bouyer #									#
   17307  1.1.6.2  bouyer # IEEE Aware tests							#
   17308  1.1.6.2  bouyer #									#
   17309  1.1.6.2  bouyer # For the IEEE aware tests, we only have to set the result based on the	#
   17310  1.1.6.2  bouyer # floating point condition codes. The BSUN exception will not be	#
   17311  1.1.6.2  bouyer # set for any of these tests.						#
   17312  1.1.6.2  bouyer #									#
   17313  1.1.6.2  bouyer #########################################################################
   17314  1.1.6.2  bouyer 
   17315  1.1.6.2  bouyer #
   17316  1.1.6.2  bouyer # ordered greater than:
   17317  1.1.6.2  bouyer #	_______
   17318  1.1.6.2  bouyer #	NANvZvN
   17319  1.1.6.2  bouyer #
   17320  1.1.6.2  bouyer ftrapcc_ogt:
   17321  1.1.6.2  bouyer 	fbogt.w		ftrapcc_trap		# ordered greater than?
   17322  1.1.6.2  bouyer ftrapcc_ogt_no:
   17323  1.1.6.2  bouyer 	rts					# do nothing
   17324  1.1.6.2  bouyer 
   17325  1.1.6.2  bouyer #
   17326  1.1.6.2  bouyer # unordered or less or equal:
   17327  1.1.6.2  bouyer #	_______
   17328  1.1.6.2  bouyer #	NANvZvN
   17329  1.1.6.2  bouyer #
   17330  1.1.6.2  bouyer ftrapcc_ule:
   17331  1.1.6.2  bouyer 	fbule.w		ftrapcc_trap		# unordered or less or equal?
   17332  1.1.6.2  bouyer ftrapcc_ule_no:
   17333  1.1.6.2  bouyer 	rts					# do nothing
   17334  1.1.6.2  bouyer 
   17335  1.1.6.2  bouyer #
   17336  1.1.6.2  bouyer # ordered greater than or equal:
   17337  1.1.6.2  bouyer #	   _____
   17338  1.1.6.2  bouyer #	Zv(NANvN)
   17339  1.1.6.2  bouyer #
   17340  1.1.6.2  bouyer ftrapcc_oge:
   17341  1.1.6.2  bouyer 	fboge.w		ftrapcc_trap		# ordered greater than or equal?
   17342  1.1.6.2  bouyer ftrapcc_oge_no:
   17343  1.1.6.2  bouyer 	rts					# do nothing
   17344  1.1.6.2  bouyer 
   17345  1.1.6.2  bouyer #
   17346  1.1.6.2  bouyer # unordered or less than:
   17347  1.1.6.2  bouyer #	       _
   17348  1.1.6.2  bouyer #	NANv(N^Z)
   17349  1.1.6.2  bouyer #
   17350  1.1.6.2  bouyer ftrapcc_ult:
   17351  1.1.6.2  bouyer 	fbult.w		ftrapcc_trap		# unordered or less than?
   17352  1.1.6.2  bouyer ftrapcc_ult_no:
   17353  1.1.6.2  bouyer 	rts					# do nothing
   17354  1.1.6.2  bouyer 
   17355  1.1.6.2  bouyer #
   17356  1.1.6.2  bouyer # ordered less than:
   17357  1.1.6.2  bouyer #	   _____
   17358  1.1.6.2  bouyer #	N^(NANvZ)
   17359  1.1.6.2  bouyer #
   17360  1.1.6.2  bouyer ftrapcc_olt:
   17361  1.1.6.2  bouyer 	fbolt.w		ftrapcc_trap		# ordered less than?
   17362  1.1.6.2  bouyer ftrapcc_olt_no:
   17363  1.1.6.2  bouyer 	rts					# do nothing
   17364  1.1.6.2  bouyer 
   17365  1.1.6.2  bouyer #
   17366  1.1.6.2  bouyer # unordered or greater or equal:
   17367  1.1.6.2  bouyer #
   17368  1.1.6.2  bouyer #	NANvZvN
   17369  1.1.6.2  bouyer #
   17370  1.1.6.2  bouyer ftrapcc_uge:
   17371  1.1.6.2  bouyer 	fbuge.w		ftrapcc_trap		# unordered or greater than?
   17372  1.1.6.2  bouyer ftrapcc_uge_no:
   17373  1.1.6.2  bouyer 	rts					# do nothing
   17374  1.1.6.2  bouyer 
   17375  1.1.6.2  bouyer #
   17376  1.1.6.2  bouyer # ordered less than or equal:
   17377  1.1.6.2  bouyer #	     ___
   17378  1.1.6.2  bouyer #	Zv(N^NAN)
   17379  1.1.6.2  bouyer #
   17380  1.1.6.2  bouyer ftrapcc_ole:
   17381  1.1.6.2  bouyer 	fbole.w		ftrapcc_trap		# ordered greater or less than?
   17382  1.1.6.2  bouyer ftrapcc_ole_no:
   17383  1.1.6.2  bouyer 	rts					# do nothing
   17384  1.1.6.2  bouyer 
   17385  1.1.6.2  bouyer #
   17386  1.1.6.2  bouyer # unordered or greater than:
   17387  1.1.6.2  bouyer #	     ___
   17388  1.1.6.2  bouyer #	NANv(NvZ)
   17389  1.1.6.2  bouyer #
   17390  1.1.6.2  bouyer ftrapcc_ugt:
   17391  1.1.6.2  bouyer 	fbugt.w		ftrapcc_trap		# unordered or greater than?
   17392  1.1.6.2  bouyer ftrapcc_ugt_no:
   17393  1.1.6.2  bouyer 	rts					# do nothing
   17394  1.1.6.2  bouyer 
   17395  1.1.6.2  bouyer #
   17396  1.1.6.2  bouyer # ordered greater or less than:
   17397  1.1.6.2  bouyer #	_____
   17398  1.1.6.2  bouyer #	NANvZ
   17399  1.1.6.2  bouyer #
   17400  1.1.6.2  bouyer ftrapcc_ogl:
   17401  1.1.6.2  bouyer 	fbogl.w		ftrapcc_trap		# ordered greater or less than?
   17402  1.1.6.2  bouyer ftrapcc_ogl_no:
   17403  1.1.6.2  bouyer 	rts					# do nothing
   17404  1.1.6.2  bouyer 
   17405  1.1.6.2  bouyer #
   17406  1.1.6.2  bouyer # unordered or equal:
   17407  1.1.6.2  bouyer #
   17408  1.1.6.2  bouyer #	NANvZ
   17409  1.1.6.2  bouyer #
   17410  1.1.6.2  bouyer ftrapcc_ueq:
   17411  1.1.6.2  bouyer 	fbueq.w		ftrapcc_trap		# unordered or equal?
   17412  1.1.6.2  bouyer ftrapcc_ueq_no:
   17413  1.1.6.2  bouyer 	rts					# do nothing
   17414  1.1.6.2  bouyer 
   17415  1.1.6.2  bouyer #
   17416  1.1.6.2  bouyer # ordered:
   17417  1.1.6.2  bouyer #	___
   17418  1.1.6.2  bouyer #	NAN
   17419  1.1.6.2  bouyer #
   17420  1.1.6.2  bouyer ftrapcc_or:
   17421  1.1.6.2  bouyer 	fbor.w		ftrapcc_trap		# ordered?
   17422  1.1.6.2  bouyer ftrapcc_or_no:
   17423  1.1.6.2  bouyer 	rts					# do nothing
   17424  1.1.6.2  bouyer 
   17425  1.1.6.2  bouyer #
   17426  1.1.6.2  bouyer # unordered:
   17427  1.1.6.2  bouyer #
   17428  1.1.6.2  bouyer #	NAN
   17429  1.1.6.2  bouyer #
   17430  1.1.6.2  bouyer ftrapcc_un:
   17431  1.1.6.2  bouyer 	fbun.w		ftrapcc_trap		# unordered?
   17432  1.1.6.2  bouyer ftrapcc_un_no:
   17433  1.1.6.2  bouyer 	rts					# do nothing
   17434  1.1.6.2  bouyer 
   17435  1.1.6.2  bouyer #######################################################################
   17436  1.1.6.2  bouyer 
   17437  1.1.6.2  bouyer # the bsun exception bit was not set.
   17438  1.1.6.2  bouyer # we will need to jump to the ftrapcc vector. the stack frame
   17439  1.1.6.2  bouyer # is the same size as that of the fp unimp instruction. the
   17440  1.1.6.2  bouyer # only difference is that the <ea> field should hold the PC
   17441  1.1.6.2  bouyer # of the ftrapcc instruction and the vector offset field
   17442  1.1.6.2  bouyer # should denote the ftrapcc trap.
   17443  1.1.6.2  bouyer ftrapcc_trap:
   17444  1.1.6.2  bouyer 	mov.b		&ftrapcc_flg,SPCOND_FLG(%a6)
   17445  1.1.6.2  bouyer 	rts
   17446  1.1.6.2  bouyer 
   17447  1.1.6.2  bouyer # the emulation routine set bsun and BSUN was enabled. have to
   17448  1.1.6.2  bouyer # fix stack and jump to the bsun handler.
   17449  1.1.6.2  bouyer # let the caller of this routine shift the stack frame up to
   17450  1.1.6.2  bouyer # eliminate the effective address field.
   17451  1.1.6.2  bouyer ftrapcc_bsun:
   17452  1.1.6.2  bouyer 	mov.b		&fbsun_flg,SPCOND_FLG(%a6)
   17453  1.1.6.2  bouyer 	rts
   17454  1.1.6.2  bouyer 
   17455  1.1.6.2  bouyer #########################################################################
   17456  1.1.6.2  bouyer # fscc(): routine to emulate the fscc instruction			#
   17457  1.1.6.2  bouyer #									#
   17458  1.1.6.2  bouyer # XDEF **************************************************************** #
   17459  1.1.6.2  bouyer #	_fscc()								#
   17460  1.1.6.2  bouyer #									#
   17461  1.1.6.2  bouyer # XREF **************************************************************** #
   17462  1.1.6.2  bouyer #	store_dreg_b() - store result to data register file		#
   17463  1.1.6.2  bouyer #	dec_areg() - decrement an areg for -(an) mode			#
   17464  1.1.6.2  bouyer #	inc_areg() - increment an areg for (an)+ mode			#
   17465  1.1.6.2  bouyer #	_dmem_write_byte() - store result to memory			#
   17466  1.1.6.2  bouyer #									#
   17467  1.1.6.2  bouyer # INPUT ***************************************************************	#
   17468  1.1.6.2  bouyer #	none								#
   17469  1.1.6.2  bouyer #									#
   17470  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   17471  1.1.6.2  bouyer #	none								#
   17472  1.1.6.2  bouyer #									#
   17473  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   17474  1.1.6.2  bouyer #	This routine checks which conditional predicate is specified by	#
   17475  1.1.6.2  bouyer # the stacked fscc instruction opcode and then branches to a routine	#
   17476  1.1.6.2  bouyer # for that predicate. The corresponding fbcc instruction is then used	#
   17477  1.1.6.2  bouyer # to see whether the condition (specified by the stacked FPSR) is true	#
   17478  1.1.6.2  bouyer # or false.								#
   17479  1.1.6.2  bouyer #	If a BSUN exception should be indicated, the BSUN and ABSUN	#
   17480  1.1.6.2  bouyer # bits are set in the stacked FPSR. If the BSUN exception is enabled,	#
   17481  1.1.6.2  bouyer # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an 	#
   17482  1.1.6.2  bouyer # enabled BSUN should not be flagged and the predicate is true, then	#
   17483  1.1.6.2  bouyer # the result is stored to the data register file or memory		#
   17484  1.1.6.2  bouyer #									#
   17485  1.1.6.2  bouyer #########################################################################
   17486  1.1.6.2  bouyer 
   17487  1.1.6.2  bouyer 	global		_fscc
   17488  1.1.6.2  bouyer _fscc:
   17489  1.1.6.2  bouyer 	mov.w		EXC_CMDREG(%a6),%d0	# fetch predicate
   17490  1.1.6.2  bouyer 
   17491  1.1.6.2  bouyer 	clr.l		%d1			# clear scratch reg
   17492  1.1.6.2  bouyer 	mov.b		FPSR_CC(%a6),%d1	# fetch fp ccodes
   17493  1.1.6.2  bouyer 	ror.l		&0x8,%d1		# rotate to top byte
   17494  1.1.6.2  bouyer 	fmov.l		%d1,%fpsr		# insert into FPSR
   17495  1.1.6.2  bouyer 
   17496  1.1.6.2  bouyer 	mov.w		(tbl_fscc.b,%pc,%d0.w*2),%d1 # load table
   17497  1.1.6.2  bouyer 	jmp		(tbl_fscc.b,%pc,%d1.w) 	# jump to fscc routine
   17498  1.1.6.2  bouyer 
   17499  1.1.6.2  bouyer tbl_fscc:
   17500  1.1.6.2  bouyer 	short		fscc_f		-	tbl_fscc	# 00
   17501  1.1.6.2  bouyer 	short		fscc_eq		-	tbl_fscc	# 01
   17502  1.1.6.2  bouyer 	short		fscc_ogt	-	tbl_fscc	# 02
   17503  1.1.6.2  bouyer 	short		fscc_oge	-	tbl_fscc	# 03
   17504  1.1.6.2  bouyer 	short		fscc_olt	-	tbl_fscc	# 04
   17505  1.1.6.2  bouyer 	short		fscc_ole	-	tbl_fscc	# 05
   17506  1.1.6.2  bouyer 	short		fscc_ogl	-	tbl_fscc	# 06
   17507  1.1.6.2  bouyer 	short		fscc_or		-	tbl_fscc	# 07
   17508  1.1.6.2  bouyer 	short		fscc_un		-	tbl_fscc	# 08
   17509  1.1.6.2  bouyer 	short		fscc_ueq	-	tbl_fscc	# 09
   17510  1.1.6.2  bouyer 	short		fscc_ugt	-	tbl_fscc	# 10
   17511  1.1.6.2  bouyer 	short		fscc_uge	-	tbl_fscc	# 11
   17512  1.1.6.2  bouyer 	short		fscc_ult	-	tbl_fscc	# 12
   17513  1.1.6.2  bouyer 	short		fscc_ule	-	tbl_fscc	# 13
   17514  1.1.6.2  bouyer 	short		fscc_neq	-	tbl_fscc	# 14
   17515  1.1.6.2  bouyer 	short		fscc_t		-	tbl_fscc	# 15
   17516  1.1.6.2  bouyer 	short		fscc_sf		-	tbl_fscc	# 16
   17517  1.1.6.2  bouyer 	short		fscc_seq	-	tbl_fscc	# 17
   17518  1.1.6.2  bouyer 	short		fscc_gt		-	tbl_fscc	# 18
   17519  1.1.6.2  bouyer 	short		fscc_ge		-	tbl_fscc	# 19
   17520  1.1.6.2  bouyer 	short		fscc_lt		-	tbl_fscc	# 20
   17521  1.1.6.2  bouyer 	short		fscc_le		-	tbl_fscc	# 21
   17522  1.1.6.2  bouyer 	short		fscc_gl		-	tbl_fscc	# 22
   17523  1.1.6.2  bouyer 	short		fscc_gle	-	tbl_fscc	# 23
   17524  1.1.6.2  bouyer 	short		fscc_ngle	-	tbl_fscc	# 24
   17525  1.1.6.2  bouyer 	short		fscc_ngl	-	tbl_fscc	# 25
   17526  1.1.6.2  bouyer 	short		fscc_nle	-	tbl_fscc	# 26
   17527  1.1.6.2  bouyer 	short		fscc_nlt	-	tbl_fscc	# 27
   17528  1.1.6.2  bouyer 	short		fscc_nge	-	tbl_fscc	# 28
   17529  1.1.6.2  bouyer 	short		fscc_ngt	-	tbl_fscc	# 29
   17530  1.1.6.2  bouyer 	short		fscc_sneq	-	tbl_fscc	# 30
   17531  1.1.6.2  bouyer 	short		fscc_st		-	tbl_fscc	# 31
   17532  1.1.6.2  bouyer 
   17533  1.1.6.2  bouyer #########################################################################
   17534  1.1.6.2  bouyer #									#
   17535  1.1.6.2  bouyer # IEEE Nonaware tests							#
   17536  1.1.6.2  bouyer #									#
   17537  1.1.6.2  bouyer # For the IEEE nonaware tests, we set the result based on the		#
   17538  1.1.6.2  bouyer # floating point condition codes. In addition, we check to see		#
   17539  1.1.6.2  bouyer # if the NAN bit is set, in which case BSUN and AIOP will be set.	#
   17540  1.1.6.2  bouyer #									#
   17541  1.1.6.2  bouyer # The cases EQ and NE are shared by the Aware and Nonaware groups	#
   17542  1.1.6.2  bouyer # and are incapable of setting the BSUN exception bit.			#
   17543  1.1.6.2  bouyer #									#
   17544  1.1.6.2  bouyer # Typically, only one of the two possible branch directions could	#
   17545  1.1.6.2  bouyer # have the NAN bit set.							#
   17546  1.1.6.2  bouyer #									#
   17547  1.1.6.2  bouyer #########################################################################
   17548  1.1.6.2  bouyer 
   17549  1.1.6.2  bouyer #
   17550  1.1.6.2  bouyer # equal:
   17551  1.1.6.2  bouyer #
   17552  1.1.6.2  bouyer #	Z
   17553  1.1.6.2  bouyer #
   17554  1.1.6.2  bouyer fscc_eq:
   17555  1.1.6.2  bouyer 	fbeq.w		fscc_eq_yes		# equal?
   17556  1.1.6.2  bouyer fscc_eq_no:
   17557  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17558  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17559  1.1.6.2  bouyer fscc_eq_yes:
   17560  1.1.6.2  bouyer 	st		%d0			# set true
   17561  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17562  1.1.6.2  bouyer 
   17563  1.1.6.2  bouyer #
   17564  1.1.6.2  bouyer # not equal:
   17565  1.1.6.2  bouyer #	_
   17566  1.1.6.2  bouyer #	Z
   17567  1.1.6.2  bouyer #
   17568  1.1.6.2  bouyer fscc_neq:
   17569  1.1.6.2  bouyer 	fbneq.w		fscc_neq_yes		# not equal?
   17570  1.1.6.2  bouyer fscc_neq_no:
   17571  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17572  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17573  1.1.6.2  bouyer fscc_neq_yes:
   17574  1.1.6.2  bouyer 	st		%d0			# set true
   17575  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17576  1.1.6.2  bouyer 
   17577  1.1.6.2  bouyer #
   17578  1.1.6.2  bouyer # greater than:
   17579  1.1.6.2  bouyer #	_______
   17580  1.1.6.2  bouyer #	NANvZvN
   17581  1.1.6.2  bouyer #
   17582  1.1.6.2  bouyer fscc_gt:
   17583  1.1.6.2  bouyer 	fbgt.w		fscc_gt_yes		# greater than?
   17584  1.1.6.2  bouyer fscc_gt_no:
   17585  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17586  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17587  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17588  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17589  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17590  1.1.6.2  bouyer fscc_gt_yes:
   17591  1.1.6.2  bouyer 	st		%d0			# set true
   17592  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17593  1.1.6.2  bouyer 
   17594  1.1.6.2  bouyer #
   17595  1.1.6.2  bouyer # not greater than:
   17596  1.1.6.2  bouyer #
   17597  1.1.6.2  bouyer #	NANvZvN
   17598  1.1.6.2  bouyer #
   17599  1.1.6.2  bouyer fscc_ngt:
   17600  1.1.6.2  bouyer 	fbngt.w		fscc_ngt_yes		# not greater than?
   17601  1.1.6.2  bouyer fscc_ngt_no:
   17602  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17603  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17604  1.1.6.2  bouyer fscc_ngt_yes:
   17605  1.1.6.2  bouyer 	st		%d0			# set true
   17606  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17607  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17608  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17609  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17610  1.1.6.2  bouyer 
   17611  1.1.6.2  bouyer #
   17612  1.1.6.2  bouyer # greater than or equal:
   17613  1.1.6.2  bouyer #	   _____
   17614  1.1.6.2  bouyer #	Zv(NANvN)
   17615  1.1.6.2  bouyer #
   17616  1.1.6.2  bouyer fscc_ge:
   17617  1.1.6.2  bouyer 	fbge.w		fscc_ge_yes		# greater than or equal?
   17618  1.1.6.2  bouyer fscc_ge_no:
   17619  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17620  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17621  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17622  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17623  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17624  1.1.6.2  bouyer fscc_ge_yes:
   17625  1.1.6.2  bouyer 	st		%d0			# set true
   17626  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17627  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17628  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17629  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17630  1.1.6.2  bouyer 
   17631  1.1.6.2  bouyer #
   17632  1.1.6.2  bouyer # not (greater than or equal):
   17633  1.1.6.2  bouyer #	       _
   17634  1.1.6.2  bouyer #	NANv(N^Z)
   17635  1.1.6.2  bouyer #
   17636  1.1.6.2  bouyer fscc_nge:
   17637  1.1.6.2  bouyer 	fbnge.w		fscc_nge_yes		# not (greater than or equal)?
   17638  1.1.6.2  bouyer fscc_nge_no:
   17639  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17640  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17641  1.1.6.2  bouyer fscc_nge_yes:
   17642  1.1.6.2  bouyer 	st		%d0			# set true
   17643  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17644  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17645  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17646  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17647  1.1.6.2  bouyer 
   17648  1.1.6.2  bouyer #
   17649  1.1.6.2  bouyer # less than:
   17650  1.1.6.2  bouyer #	   _____
   17651  1.1.6.2  bouyer #	N^(NANvZ)
   17652  1.1.6.2  bouyer #
   17653  1.1.6.2  bouyer fscc_lt:
   17654  1.1.6.2  bouyer 	fblt.w		fscc_lt_yes		# less than?
   17655  1.1.6.2  bouyer fscc_lt_no:
   17656  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17657  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17658  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17659  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17660  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17661  1.1.6.2  bouyer fscc_lt_yes:
   17662  1.1.6.2  bouyer 	st		%d0			# set true
   17663  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17664  1.1.6.2  bouyer 
   17665  1.1.6.2  bouyer #
   17666  1.1.6.2  bouyer # not less than:
   17667  1.1.6.2  bouyer #	       _
   17668  1.1.6.2  bouyer #	NANv(ZvN)
   17669  1.1.6.2  bouyer #
   17670  1.1.6.2  bouyer fscc_nlt:
   17671  1.1.6.2  bouyer 	fbnlt.w		fscc_nlt_yes		# not less than?
   17672  1.1.6.2  bouyer fscc_nlt_no:
   17673  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17674  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17675  1.1.6.2  bouyer fscc_nlt_yes:
   17676  1.1.6.2  bouyer 	st		%d0			# set true
   17677  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17678  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17679  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17680  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17681  1.1.6.2  bouyer 
   17682  1.1.6.2  bouyer #
   17683  1.1.6.2  bouyer # less than or equal:
   17684  1.1.6.2  bouyer #	     ___
   17685  1.1.6.2  bouyer #	Zv(N^NAN)
   17686  1.1.6.2  bouyer #
   17687  1.1.6.2  bouyer fscc_le:
   17688  1.1.6.2  bouyer 	fble.w		fscc_le_yes		# less than or equal?
   17689  1.1.6.2  bouyer fscc_le_no:
   17690  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17691  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17692  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17693  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17694  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17695  1.1.6.2  bouyer fscc_le_yes:
   17696  1.1.6.2  bouyer 	st		%d0			# set true
   17697  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17698  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17699  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17700  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17701  1.1.6.2  bouyer 
   17702  1.1.6.2  bouyer #
   17703  1.1.6.2  bouyer # not (less than or equal):
   17704  1.1.6.2  bouyer #	     ___
   17705  1.1.6.2  bouyer #	NANv(NvZ)
   17706  1.1.6.2  bouyer #
   17707  1.1.6.2  bouyer fscc_nle:
   17708  1.1.6.2  bouyer 	fbnle.w		fscc_nle_yes		# not (less than or equal)?
   17709  1.1.6.2  bouyer fscc_nle_no:
   17710  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17711  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17712  1.1.6.2  bouyer fscc_nle_yes:
   17713  1.1.6.2  bouyer 	st		%d0			# set true
   17714  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17715  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17716  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17717  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17718  1.1.6.2  bouyer 
   17719  1.1.6.2  bouyer #
   17720  1.1.6.2  bouyer # greater or less than:
   17721  1.1.6.2  bouyer #	_____
   17722  1.1.6.2  bouyer #	NANvZ
   17723  1.1.6.2  bouyer #
   17724  1.1.6.2  bouyer fscc_gl:
   17725  1.1.6.2  bouyer 	fbgl.w		fscc_gl_yes		# greater or less than?
   17726  1.1.6.2  bouyer fscc_gl_no:
   17727  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17728  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17729  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17730  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17731  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17732  1.1.6.2  bouyer fscc_gl_yes:
   17733  1.1.6.2  bouyer 	st		%d0			# set true
   17734  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17735  1.1.6.2  bouyer 
   17736  1.1.6.2  bouyer #
   17737  1.1.6.2  bouyer # not (greater or less than):
   17738  1.1.6.2  bouyer #
   17739  1.1.6.2  bouyer #	NANvZ
   17740  1.1.6.2  bouyer #
   17741  1.1.6.2  bouyer fscc_ngl:
   17742  1.1.6.2  bouyer 	fbngl.w		fscc_ngl_yes		# not (greater or less than)?
   17743  1.1.6.2  bouyer fscc_ngl_no:
   17744  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17745  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17746  1.1.6.2  bouyer fscc_ngl_yes:
   17747  1.1.6.2  bouyer 	st		%d0			# set true
   17748  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6)	# is NAN set in cc?
   17749  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17750  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17751  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17752  1.1.6.2  bouyer 
   17753  1.1.6.2  bouyer #
   17754  1.1.6.2  bouyer # greater, less, or equal:
   17755  1.1.6.2  bouyer #	___
   17756  1.1.6.2  bouyer #	NAN
   17757  1.1.6.2  bouyer #
   17758  1.1.6.2  bouyer fscc_gle:
   17759  1.1.6.2  bouyer 	fbgle.w		fscc_gle_yes		# greater, less, or equal?
   17760  1.1.6.2  bouyer fscc_gle_no:
   17761  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17762  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17763  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17764  1.1.6.2  bouyer fscc_gle_yes:
   17765  1.1.6.2  bouyer 	st		%d0			# set true
   17766  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17767  1.1.6.2  bouyer 
   17768  1.1.6.2  bouyer #
   17769  1.1.6.2  bouyer # not (greater, less, or equal):
   17770  1.1.6.2  bouyer #
   17771  1.1.6.2  bouyer #	NAN
   17772  1.1.6.2  bouyer #
   17773  1.1.6.2  bouyer fscc_ngle:
   17774  1.1.6.2  bouyer 	fbngle.w		fscc_ngle_yes	# not (greater, less, or equal)?
   17775  1.1.6.2  bouyer fscc_ngle_no:
   17776  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17777  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17778  1.1.6.2  bouyer fscc_ngle_yes:
   17779  1.1.6.2  bouyer 	st		%d0			# set true
   17780  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17781  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17782  1.1.6.2  bouyer 
   17783  1.1.6.2  bouyer #########################################################################
   17784  1.1.6.2  bouyer #									#
   17785  1.1.6.2  bouyer # Miscellaneous tests							#
   17786  1.1.6.2  bouyer #									#
   17787  1.1.6.2  bouyer # For the IEEE aware tests, we only have to set the result based on the	#
   17788  1.1.6.2  bouyer # floating point condition codes. The BSUN exception will not be	#
   17789  1.1.6.2  bouyer # set for any of these tests.						#
   17790  1.1.6.2  bouyer #									#
   17791  1.1.6.2  bouyer #########################################################################
   17792  1.1.6.2  bouyer 
   17793  1.1.6.2  bouyer #
   17794  1.1.6.2  bouyer # false:
   17795  1.1.6.2  bouyer #
   17796  1.1.6.2  bouyer #	False
   17797  1.1.6.2  bouyer #
   17798  1.1.6.2  bouyer fscc_f:
   17799  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17800  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17801  1.1.6.2  bouyer 
   17802  1.1.6.2  bouyer #
   17803  1.1.6.2  bouyer # true:
   17804  1.1.6.2  bouyer #
   17805  1.1.6.2  bouyer #	True
   17806  1.1.6.2  bouyer #
   17807  1.1.6.2  bouyer fscc_t:
   17808  1.1.6.2  bouyer 	st		%d0			# set true
   17809  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17810  1.1.6.2  bouyer 
   17811  1.1.6.2  bouyer #
   17812  1.1.6.2  bouyer # signalling false:
   17813  1.1.6.2  bouyer #
   17814  1.1.6.2  bouyer #	False
   17815  1.1.6.2  bouyer #
   17816  1.1.6.2  bouyer fscc_sf:
   17817  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17818  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17819  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17820  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17821  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17822  1.1.6.2  bouyer 
   17823  1.1.6.2  bouyer #
   17824  1.1.6.2  bouyer # signalling true:
   17825  1.1.6.2  bouyer #
   17826  1.1.6.2  bouyer #	True
   17827  1.1.6.2  bouyer #
   17828  1.1.6.2  bouyer fscc_st:
   17829  1.1.6.2  bouyer 	st		%d0			# set false
   17830  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17831  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17832  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17833  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17834  1.1.6.2  bouyer 
   17835  1.1.6.2  bouyer #
   17836  1.1.6.2  bouyer # signalling equal:
   17837  1.1.6.2  bouyer #
   17838  1.1.6.2  bouyer #	Z
   17839  1.1.6.2  bouyer #
   17840  1.1.6.2  bouyer fscc_seq:
   17841  1.1.6.2  bouyer 	fbseq.w		fscc_seq_yes		# signalling equal?
   17842  1.1.6.2  bouyer fscc_seq_no:
   17843  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17844  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17845  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17846  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17847  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17848  1.1.6.2  bouyer fscc_seq_yes:
   17849  1.1.6.2  bouyer 	st		%d0			# set true
   17850  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17851  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17852  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17853  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17854  1.1.6.2  bouyer 
   17855  1.1.6.2  bouyer #
   17856  1.1.6.2  bouyer # signalling not equal:
   17857  1.1.6.2  bouyer #	_
   17858  1.1.6.2  bouyer #	Z
   17859  1.1.6.2  bouyer #
   17860  1.1.6.2  bouyer fscc_sneq:
   17861  1.1.6.2  bouyer 	fbsneq.w	fscc_sneq_yes		# signalling equal?
   17862  1.1.6.2  bouyer fscc_sneq_no:
   17863  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17864  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17865  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17866  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17867  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17868  1.1.6.2  bouyer fscc_sneq_yes:
   17869  1.1.6.2  bouyer 	st		%d0			# set true
   17870  1.1.6.2  bouyer 	btst		&nan_bit, FPSR_CC(%a6) 	# set BSUN exc bit
   17871  1.1.6.2  bouyer 	beq.w		fscc_done		# no;go finish
   17872  1.1.6.2  bouyer 	ori.l		&bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
   17873  1.1.6.2  bouyer 	bra.w		fscc_chk_bsun		# go finish
   17874  1.1.6.2  bouyer 
   17875  1.1.6.2  bouyer #########################################################################
   17876  1.1.6.2  bouyer #									#
   17877  1.1.6.2  bouyer # IEEE Aware tests							#
   17878  1.1.6.2  bouyer #									#
   17879  1.1.6.2  bouyer # For the IEEE aware tests, we only have to set the result based on the	#
   17880  1.1.6.2  bouyer # floating point condition codes. The BSUN exception will not be	#
   17881  1.1.6.2  bouyer # set for any of these tests.						#
   17882  1.1.6.2  bouyer #									#
   17883  1.1.6.2  bouyer #########################################################################
   17884  1.1.6.2  bouyer 
   17885  1.1.6.2  bouyer #
   17886  1.1.6.2  bouyer # ordered greater than:
   17887  1.1.6.2  bouyer #	_______
   17888  1.1.6.2  bouyer #	NANvZvN
   17889  1.1.6.2  bouyer #
   17890  1.1.6.2  bouyer fscc_ogt:
   17891  1.1.6.2  bouyer 	fbogt.w		fscc_ogt_yes		# ordered greater than?
   17892  1.1.6.2  bouyer fscc_ogt_no:
   17893  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17894  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17895  1.1.6.2  bouyer fscc_ogt_yes:
   17896  1.1.6.2  bouyer 	st		%d0			# set true
   17897  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17898  1.1.6.2  bouyer 
   17899  1.1.6.2  bouyer #
   17900  1.1.6.2  bouyer # unordered or less or equal:
   17901  1.1.6.2  bouyer #	_______
   17902  1.1.6.2  bouyer #	NANvZvN
   17903  1.1.6.2  bouyer #
   17904  1.1.6.2  bouyer fscc_ule:
   17905  1.1.6.2  bouyer 	fbule.w		fscc_ule_yes		# unordered or less or equal?
   17906  1.1.6.2  bouyer fscc_ule_no:
   17907  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17908  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17909  1.1.6.2  bouyer fscc_ule_yes:
   17910  1.1.6.2  bouyer 	st		%d0			# set true
   17911  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17912  1.1.6.2  bouyer 
   17913  1.1.6.2  bouyer #
   17914  1.1.6.2  bouyer # ordered greater than or equal:
   17915  1.1.6.2  bouyer #	   _____
   17916  1.1.6.2  bouyer #	Zv(NANvN)
   17917  1.1.6.2  bouyer #
   17918  1.1.6.2  bouyer fscc_oge:
   17919  1.1.6.2  bouyer 	fboge.w		fscc_oge_yes		# ordered greater than or equal?
   17920  1.1.6.2  bouyer fscc_oge_no:
   17921  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17922  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17923  1.1.6.2  bouyer fscc_oge_yes:
   17924  1.1.6.2  bouyer 	st		%d0			# set true
   17925  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17926  1.1.6.2  bouyer 
   17927  1.1.6.2  bouyer #
   17928  1.1.6.2  bouyer # unordered or less than:
   17929  1.1.6.2  bouyer #	       _
   17930  1.1.6.2  bouyer #	NANv(N^Z)
   17931  1.1.6.2  bouyer #
   17932  1.1.6.2  bouyer fscc_ult:
   17933  1.1.6.2  bouyer 	fbult.w		fscc_ult_yes		# unordered or less than?
   17934  1.1.6.2  bouyer fscc_ult_no:
   17935  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17936  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17937  1.1.6.2  bouyer fscc_ult_yes:
   17938  1.1.6.2  bouyer 	st		%d0			# set true
   17939  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17940  1.1.6.2  bouyer 
   17941  1.1.6.2  bouyer #
   17942  1.1.6.2  bouyer # ordered less than:
   17943  1.1.6.2  bouyer #	   _____
   17944  1.1.6.2  bouyer #	N^(NANvZ)
   17945  1.1.6.2  bouyer #
   17946  1.1.6.2  bouyer fscc_olt:
   17947  1.1.6.2  bouyer 	fbolt.w		fscc_olt_yes		# ordered less than?
   17948  1.1.6.2  bouyer fscc_olt_no:
   17949  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17950  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17951  1.1.6.2  bouyer fscc_olt_yes:
   17952  1.1.6.2  bouyer 	st		%d0			# set true
   17953  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17954  1.1.6.2  bouyer 
   17955  1.1.6.2  bouyer #
   17956  1.1.6.2  bouyer # unordered or greater or equal:
   17957  1.1.6.2  bouyer #
   17958  1.1.6.2  bouyer #	NANvZvN
   17959  1.1.6.2  bouyer #
   17960  1.1.6.2  bouyer fscc_uge:
   17961  1.1.6.2  bouyer 	fbuge.w		fscc_uge_yes		# unordered or greater than?
   17962  1.1.6.2  bouyer fscc_uge_no:
   17963  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17964  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17965  1.1.6.2  bouyer fscc_uge_yes:
   17966  1.1.6.2  bouyer 	st		%d0			# set true
   17967  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17968  1.1.6.2  bouyer 
   17969  1.1.6.2  bouyer #
   17970  1.1.6.2  bouyer # ordered less than or equal:
   17971  1.1.6.2  bouyer #	     ___
   17972  1.1.6.2  bouyer #	Zv(N^NAN)
   17973  1.1.6.2  bouyer #
   17974  1.1.6.2  bouyer fscc_ole:
   17975  1.1.6.2  bouyer 	fbole.w		fscc_ole_yes		# ordered greater or less than?
   17976  1.1.6.2  bouyer fscc_ole_no:
   17977  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17978  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17979  1.1.6.2  bouyer fscc_ole_yes:
   17980  1.1.6.2  bouyer 	st		%d0			# set true
   17981  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17982  1.1.6.2  bouyer 
   17983  1.1.6.2  bouyer #
   17984  1.1.6.2  bouyer # unordered or greater than:
   17985  1.1.6.2  bouyer #	     ___
   17986  1.1.6.2  bouyer #	NANv(NvZ)
   17987  1.1.6.2  bouyer #
   17988  1.1.6.2  bouyer fscc_ugt:
   17989  1.1.6.2  bouyer 	fbugt.w		fscc_ugt_yes		# unordered or greater than?
   17990  1.1.6.2  bouyer fscc_ugt_no:
   17991  1.1.6.2  bouyer 	clr.b		%d0			# set false
   17992  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17993  1.1.6.2  bouyer fscc_ugt_yes:
   17994  1.1.6.2  bouyer 	st		%d0			# set true
   17995  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   17996  1.1.6.2  bouyer 
   17997  1.1.6.2  bouyer #
   17998  1.1.6.2  bouyer # ordered greater or less than:
   17999  1.1.6.2  bouyer #	_____
   18000  1.1.6.2  bouyer #	NANvZ
   18001  1.1.6.2  bouyer #
   18002  1.1.6.2  bouyer fscc_ogl:
   18003  1.1.6.2  bouyer 	fbogl.w		fscc_ogl_yes		# ordered greater or less than?
   18004  1.1.6.2  bouyer fscc_ogl_no:
   18005  1.1.6.2  bouyer 	clr.b		%d0			# set false
   18006  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18007  1.1.6.2  bouyer fscc_ogl_yes:
   18008  1.1.6.2  bouyer 	st		%d0			# set true
   18009  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18010  1.1.6.2  bouyer 
   18011  1.1.6.2  bouyer #
   18012  1.1.6.2  bouyer # unordered or equal:
   18013  1.1.6.2  bouyer #
   18014  1.1.6.2  bouyer #	NANvZ
   18015  1.1.6.2  bouyer #
   18016  1.1.6.2  bouyer fscc_ueq:
   18017  1.1.6.2  bouyer 	fbueq.w		fscc_ueq_yes		# unordered or equal?
   18018  1.1.6.2  bouyer fscc_ueq_no:
   18019  1.1.6.2  bouyer 	clr.b		%d0			# set false
   18020  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18021  1.1.6.2  bouyer fscc_ueq_yes:
   18022  1.1.6.2  bouyer 	st		%d0			# set true
   18023  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18024  1.1.6.2  bouyer 
   18025  1.1.6.2  bouyer #
   18026  1.1.6.2  bouyer # ordered:
   18027  1.1.6.2  bouyer #	___
   18028  1.1.6.2  bouyer #	NAN
   18029  1.1.6.2  bouyer #
   18030  1.1.6.2  bouyer fscc_or:
   18031  1.1.6.2  bouyer 	fbor.w		fscc_or_yes		# ordered?
   18032  1.1.6.2  bouyer fscc_or_no:
   18033  1.1.6.2  bouyer 	clr.b		%d0			# set false
   18034  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18035  1.1.6.2  bouyer fscc_or_yes:
   18036  1.1.6.2  bouyer 	st		%d0			# set true
   18037  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18038  1.1.6.2  bouyer 
   18039  1.1.6.2  bouyer #
   18040  1.1.6.2  bouyer # unordered:
   18041  1.1.6.2  bouyer #
   18042  1.1.6.2  bouyer #	NAN
   18043  1.1.6.2  bouyer #
   18044  1.1.6.2  bouyer fscc_un:
   18045  1.1.6.2  bouyer 	fbun.w		fscc_un_yes		# unordered?
   18046  1.1.6.2  bouyer fscc_un_no:
   18047  1.1.6.2  bouyer 	clr.b		%d0			# set false
   18048  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18049  1.1.6.2  bouyer fscc_un_yes:
   18050  1.1.6.2  bouyer 	st		%d0			# set true
   18051  1.1.6.2  bouyer 	bra.w		fscc_done		# go finish
   18052  1.1.6.2  bouyer 
   18053  1.1.6.2  bouyer #######################################################################
   18054  1.1.6.2  bouyer 
   18055  1.1.6.2  bouyer #
   18056  1.1.6.2  bouyer # the bsun exception bit was set. now, check to see is BSUN
   18057  1.1.6.2  bouyer # is enabled. if so, don't store result and correct stack frame
   18058  1.1.6.2  bouyer # for a bsun exception.
   18059  1.1.6.2  bouyer #
   18060  1.1.6.2  bouyer fscc_chk_bsun:
   18061  1.1.6.2  bouyer 	btst		&bsun_bit,FPCR_ENABLE(%a6) # was BSUN set?
   18062  1.1.6.2  bouyer 	bne.w		fscc_bsun
   18063  1.1.6.2  bouyer 
   18064  1.1.6.2  bouyer #
   18065  1.1.6.2  bouyer # the bsun exception bit was not set.
   18066  1.1.6.2  bouyer # the result has been selected.
   18067  1.1.6.2  bouyer # now, check to see if the result is to be stored in the data register
   18068  1.1.6.2  bouyer # file or in memory.
   18069  1.1.6.2  bouyer #
   18070  1.1.6.2  bouyer fscc_done:
   18071  1.1.6.2  bouyer 	mov.l		%d0,%a0			# save result for a moment
   18072  1.1.6.2  bouyer 
   18073  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# fetch lo opword
   18074  1.1.6.2  bouyer 	mov.l		%d1,%d0			# make a copy
   18075  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# extract src mode
   18076  1.1.6.2  bouyer 
   18077  1.1.6.2  bouyer 	bne.b		fscc_mem_op		# it's a memory operation
   18078  1.1.6.2  bouyer 
   18079  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18080  1.1.6.2  bouyer 	andi.w		&0x7,%d1		# pass index in d1
   18081  1.1.6.2  bouyer 	mov.l		%a0,%d0			# pass result in d0
   18082  1.1.6.2  bouyer 	bsr.l		store_dreg_b		# save result in regfile
   18083  1.1.6.2  bouyer 	rts
   18084  1.1.6.2  bouyer 
   18085  1.1.6.2  bouyer #
   18086  1.1.6.2  bouyer # the stacked <ea> is correct with the exception of:
   18087  1.1.6.2  bouyer # 	-> Dn : <ea> is garbage
   18088  1.1.6.2  bouyer #
   18089  1.1.6.2  bouyer # if the addressing mode is post-increment or pre-decrement,
   18090  1.1.6.2  bouyer # then the address registers have not been updated.
   18091  1.1.6.2  bouyer #
   18092  1.1.6.2  bouyer fscc_mem_op:
   18093  1.1.6.2  bouyer 	cmpi.b		%d1,&0x18		# is <ea> (An)+ ?
   18094  1.1.6.2  bouyer 	beq.b		fscc_mem_inc		# yes
   18095  1.1.6.2  bouyer 	cmpi.b		%d1,&0x20		# is <ea> -(An) ?
   18096  1.1.6.2  bouyer 	beq.b		fscc_mem_dec		# yes
   18097  1.1.6.2  bouyer 
   18098  1.1.6.2  bouyer 	mov.l		%a0,%d0			# pass result in d0
   18099  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# fetch <ea>
   18100  1.1.6.2  bouyer 	bsr.l		_dmem_write_byte	# write result byte
   18101  1.1.6.2  bouyer 
   18102  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   18103  1.1.6.2  bouyer 	bne.w		fscc_err		# yes
   18104  1.1.6.2  bouyer 
   18105  1.1.6.2  bouyer 	rts
   18106  1.1.6.2  bouyer 
   18107  1.1.6.2  bouyer # addresing mode is post-increment. write the result byte. if the write
   18108  1.1.6.2  bouyer # fails then don't update the address register. if write passes then
   18109  1.1.6.2  bouyer # call inc_areg() to update the address register.
   18110  1.1.6.2  bouyer fscc_mem_inc:
   18111  1.1.6.2  bouyer 	mov.l		%a0,%d0			# pass result in d0
   18112  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# fetch <ea>
   18113  1.1.6.2  bouyer 	bsr.l		_dmem_write_byte	# write result byte
   18114  1.1.6.2  bouyer 
   18115  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   18116  1.1.6.2  bouyer 	bne.w		fscc_err		# yes
   18117  1.1.6.2  bouyer 
   18118  1.1.6.2  bouyer 	mov.b		0x1+EXC_OPWORD(%a6),%d1	# fetch opword
   18119  1.1.6.2  bouyer 	andi.w		&0x7,%d1		# pass index in d1
   18120  1.1.6.2  bouyer 	movq.l		&0x1,%d0		# pass amt to inc by
   18121  1.1.6.2  bouyer 	bsr.l		inc_areg		# increment address register
   18122  1.1.6.2  bouyer 
   18123  1.1.6.2  bouyer 	rts
   18124  1.1.6.2  bouyer 
   18125  1.1.6.2  bouyer # addressing mode is pre-decrement. write the result byte. if the write
   18126  1.1.6.2  bouyer # fails then don't update the address register. if the write passes then
   18127  1.1.6.2  bouyer # call dec_areg() to update the address register.
   18128  1.1.6.2  bouyer fscc_mem_dec:
   18129  1.1.6.2  bouyer 	mov.l		%a0,%d0			# pass result in d0
   18130  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# fetch <ea>
   18131  1.1.6.2  bouyer 	bsr.l		_dmem_write_byte	# write result byte
   18132  1.1.6.2  bouyer 
   18133  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   18134  1.1.6.2  bouyer 	bne.w		fscc_err		# yes
   18135  1.1.6.2  bouyer 
   18136  1.1.6.2  bouyer 	mov.b		0x1+EXC_OPWORD(%a6),%d1	# fetch opword
   18137  1.1.6.2  bouyer 	andi.w		&0x7,%d1		# pass index in d1
   18138  1.1.6.2  bouyer 	movq.l		&0x1,%d0		# pass amt to dec by
   18139  1.1.6.2  bouyer 	bsr.l		dec_areg		# decrement address register
   18140  1.1.6.2  bouyer 
   18141  1.1.6.2  bouyer 	rts
   18142  1.1.6.2  bouyer 
   18143  1.1.6.2  bouyer # the emulation routine set bsun and BSUN was enabled. have to
   18144  1.1.6.2  bouyer # fix stack and jump to the bsun handler.
   18145  1.1.6.2  bouyer # let the caller of this routine shift the stack frame up to
   18146  1.1.6.2  bouyer # eliminate the effective address field.
   18147  1.1.6.2  bouyer fscc_bsun:
   18148  1.1.6.2  bouyer 	mov.b		&fbsun_flg,SPCOND_FLG(%a6)
   18149  1.1.6.2  bouyer 	rts
   18150  1.1.6.2  bouyer 
   18151  1.1.6.2  bouyer # the byte write to memory has failed. pass the failing effective address
   18152  1.1.6.2  bouyer # and a FSLW to funimp_dacc().
   18153  1.1.6.2  bouyer fscc_err:
   18154  1.1.6.2  bouyer 	mov.w		&0x00a1,EXC_VOFF(%a6)
   18155  1.1.6.2  bouyer 	bra.l		facc_finish
   18156  1.1.6.2  bouyer 
   18157  1.1.6.2  bouyer #########################################################################
   18158  1.1.6.2  bouyer # XDEF ****************************************************************	#
   18159  1.1.6.2  bouyer #	fmovm_dynamic(): emulate "fmovm" dynamic instruction		#
   18160  1.1.6.2  bouyer #									#
   18161  1.1.6.2  bouyer # XREF ****************************************************************	#
   18162  1.1.6.2  bouyer #	fetch_dreg() - fetch data register				#
   18163  1.1.6.2  bouyer #	{i,d,}mem_read() - fetch data from memory			#
   18164  1.1.6.2  bouyer #	_mem_write() - write data to memory				#
   18165  1.1.6.2  bouyer #	iea_iacc() - instruction memory access error occurred		#
   18166  1.1.6.2  bouyer #	iea_dacc() - data memory access error occurred			#
   18167  1.1.6.2  bouyer #	restore() - restore An index regs if access error occurred	#
   18168  1.1.6.2  bouyer #									#
   18169  1.1.6.2  bouyer # INPUT ***************************************************************	#
   18170  1.1.6.2  bouyer #	None								#
   18171  1.1.6.2  bouyer # 									#
   18172  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   18173  1.1.6.2  bouyer #	If instr is "fmovm Dn,-(A7)" from supervisor mode,		#
   18174  1.1.6.2  bouyer #		d0 = size of dump					#
   18175  1.1.6.2  bouyer #		d1 = Dn							#
   18176  1.1.6.2  bouyer #	Else if instruction access error,				#
   18177  1.1.6.2  bouyer #		d0 = FSLW						#
   18178  1.1.6.2  bouyer #	Else if data access error,					#
   18179  1.1.6.2  bouyer #		d0 = FSLW						#
   18180  1.1.6.2  bouyer #		a0 = address of fault					#
   18181  1.1.6.2  bouyer #	Else								#
   18182  1.1.6.2  bouyer #		none.							#
   18183  1.1.6.2  bouyer #									#
   18184  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   18185  1.1.6.2  bouyer #	The effective address must be calculated since this is entered	#
   18186  1.1.6.2  bouyer # from an "Unimplemented Effective Address" exception handler. So, we	#
   18187  1.1.6.2  bouyer # have our own fcalc_ea() routine here. If an access error is flagged	#
   18188  1.1.6.2  bouyer # by a _{i,d,}mem_read() call, we must exit through the special		#
   18189  1.1.6.2  bouyer # handler.								#
   18190  1.1.6.2  bouyer #	The data register is determined and its value loaded to get the	#
   18191  1.1.6.2  bouyer # string of FP registers affected. This value is used as an index into	#
   18192  1.1.6.2  bouyer # a lookup table such that we can determine the number of bytes		#
   18193  1.1.6.2  bouyer # involved. 								#
   18194  1.1.6.2  bouyer #	If the instruction is "fmovm.x <ea>,Dn", a _mem_read() is used	#
   18195  1.1.6.2  bouyer # to read in all FP values. Again, _mem_read() may fail and require a	#
   18196  1.1.6.2  bouyer # special exit. 							#
   18197  1.1.6.2  bouyer #	If the instruction is "fmovm.x DN,<ea>", a _mem_write() is used	#
   18198  1.1.6.2  bouyer # to write all FP values. _mem_write() may also fail.			#
   18199  1.1.6.2  bouyer # 	If the instruction is "fmovm.x DN,-(a7)" from supervisor mode,	#
   18200  1.1.6.2  bouyer # then we return the size of the dump and the string to the caller	#
   18201  1.1.6.2  bouyer # so that the move can occur outside of this routine. This special	#
   18202  1.1.6.2  bouyer # case is required so that moves to the system stack are handled	#
   18203  1.1.6.2  bouyer # correctly.								#
   18204  1.1.6.2  bouyer #									#
   18205  1.1.6.2  bouyer # DYNAMIC:								#
   18206  1.1.6.2  bouyer # 	fmovm.x	dn, <ea>						#
   18207  1.1.6.2  bouyer # 	fmovm.x	<ea>, dn						#
   18208  1.1.6.2  bouyer #									#
   18209  1.1.6.2  bouyer #	      <WORD 1>		      <WORD2>				#
   18210  1.1.6.2  bouyer #	1111 0010 00 |<ea>|	11@& 1000 0$$$ 0000			#
   18211  1.1.6.2  bouyer #					  				#
   18212  1.1.6.2  bouyer #	& = (0): predecrement addressing mode				#
   18213  1.1.6.2  bouyer #	    (1): postincrement or control addressing mode		#
   18214  1.1.6.2  bouyer #	@ = (0): move listed regs from memory to the FPU		#
   18215  1.1.6.2  bouyer #	    (1): move listed regs from the FPU to memory		#
   18216  1.1.6.2  bouyer #	$$$    : index of data register holding reg select mask		#
   18217  1.1.6.2  bouyer #									#
   18218  1.1.6.2  bouyer # NOTES:								#
   18219  1.1.6.2  bouyer #	If the data register holds a zero, then the			#
   18220  1.1.6.2  bouyer #	instruction is a nop.						#
   18221  1.1.6.2  bouyer #									#
   18222  1.1.6.2  bouyer #########################################################################
   18223  1.1.6.2  bouyer 
   18224  1.1.6.2  bouyer 	global		fmovm_dynamic
   18225  1.1.6.2  bouyer fmovm_dynamic:
   18226  1.1.6.2  bouyer 
   18227  1.1.6.2  bouyer # extract the data register in which the bit string resides...
   18228  1.1.6.2  bouyer 	mov.b		1+EXC_EXTWORD(%a6),%d1	# fetch extword
   18229  1.1.6.2  bouyer 	andi.w		&0x70,%d1		# extract reg bits
   18230  1.1.6.2  bouyer 	lsr.b		&0x4,%d1		# shift into lo bits
   18231  1.1.6.2  bouyer 
   18232  1.1.6.2  bouyer # fetch the bit string into d0...
   18233  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch reg string
   18234  1.1.6.2  bouyer 
   18235  1.1.6.2  bouyer 	andi.l		&0x000000ff,%d0		# keep only lo byte
   18236  1.1.6.2  bouyer 
   18237  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save strg
   18238  1.1.6.2  bouyer 	mov.b		(tbl_fmovm_size.w,%pc,%d0),%d0
   18239  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save size
   18240  1.1.6.2  bouyer 	bsr.l		fmovm_calc_ea		# calculate <ea>
   18241  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# restore size
   18242  1.1.6.2  bouyer 	mov.l		(%sp)+,%d1		# restore strg
   18243  1.1.6.2  bouyer 
   18244  1.1.6.2  bouyer # if the bit string is a zero, then the operation is a no-op
   18245  1.1.6.2  bouyer # but, make sure that we've calculated ea and advanced the opword pointer
   18246  1.1.6.2  bouyer 	beq.w		fmovm_data_done
   18247  1.1.6.2  bouyer 
   18248  1.1.6.2  bouyer # separate move ins from move outs...
   18249  1.1.6.2  bouyer 	btst		&0x5,EXC_EXTWORD(%a6)	# is it a move in or out?
   18250  1.1.6.2  bouyer 	beq.w		fmovm_data_in		# it's a move out
   18251  1.1.6.2  bouyer 
   18252  1.1.6.2  bouyer #############
   18253  1.1.6.2  bouyer # MOVE OUT: #
   18254  1.1.6.2  bouyer #############
   18255  1.1.6.2  bouyer fmovm_data_out:
   18256  1.1.6.2  bouyer 	btst		&0x4,EXC_EXTWORD(%a6)	# control or predecrement?
   18257  1.1.6.2  bouyer 	bne.w		fmovm_out_ctrl		# control
   18258  1.1.6.2  bouyer 
   18259  1.1.6.2  bouyer ############################
   18260  1.1.6.2  bouyer fmovm_out_predec:
   18261  1.1.6.2  bouyer # for predecrement mode, the bit string is the opposite of both control
   18262  1.1.6.2  bouyer # operations and postincrement mode. (bit7 = FP7 ... bit0 = FP0)
   18263  1.1.6.2  bouyer # here, we convert it to be just like the others...
   18264  1.1.6.2  bouyer 	mov.b		(tbl_fmovm_convert.w,%pc,%d1.w*1),%d1
   18265  1.1.6.2  bouyer 
   18266  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode?
   18267  1.1.6.2  bouyer 	beq.b		fmovm_out_ctrl		# user
   18268  1.1.6.2  bouyer 
   18269  1.1.6.2  bouyer fmovm_out_predec_s:
   18270  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
   18271  1.1.6.2  bouyer 	bne.b		fmovm_out_ctrl
   18272  1.1.6.2  bouyer 
   18273  1.1.6.2  bouyer # the operation was unfortunately an: fmovm.x dn,-(sp)
   18274  1.1.6.2  bouyer # called from supervisor mode.
   18275  1.1.6.2  bouyer # we're also passing "size" and "strg" back to the calling routine
   18276  1.1.6.2  bouyer 	rts
   18277  1.1.6.2  bouyer 
   18278  1.1.6.2  bouyer ############################
   18279  1.1.6.2  bouyer fmovm_out_ctrl:
   18280  1.1.6.2  bouyer 	mov.l		%a0,%a1			# move <ea> to a1
   18281  1.1.6.2  bouyer 
   18282  1.1.6.2  bouyer 	sub.l		%d0,%sp			# subtract size of dump
   18283  1.1.6.2  bouyer 	lea		(%sp),%a0
   18284  1.1.6.2  bouyer 
   18285  1.1.6.2  bouyer 	tst.b		%d1			# should FP0 be moved?
   18286  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_fp1	# no
   18287  1.1.6.2  bouyer 
   18288  1.1.6.2  bouyer 	mov.l		0x0+EXC_FP0(%a6),(%a0)+	# yes
   18289  1.1.6.2  bouyer 	mov.l		0x4+EXC_FP0(%a6),(%a0)+
   18290  1.1.6.2  bouyer 	mov.l		0x8+EXC_FP0(%a6),(%a0)+
   18291  1.1.6.2  bouyer 
   18292  1.1.6.2  bouyer fmovm_out_ctrl_fp1:
   18293  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP1 be moved?
   18294  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_fp2	# no
   18295  1.1.6.2  bouyer 
   18296  1.1.6.2  bouyer 	mov.l		0x0+EXC_FP1(%a6),(%a0)+	# yes
   18297  1.1.6.2  bouyer 	mov.l		0x4+EXC_FP1(%a6),(%a0)+
   18298  1.1.6.2  bouyer 	mov.l		0x8+EXC_FP1(%a6),(%a0)+
   18299  1.1.6.2  bouyer 
   18300  1.1.6.2  bouyer fmovm_out_ctrl_fp2:
   18301  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP2 be moved?
   18302  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_fp3	# no
   18303  1.1.6.2  bouyer 
   18304  1.1.6.2  bouyer 	fmovm.x		&0x20,(%a0)		# yes
   18305  1.1.6.2  bouyer 	add.l		&0xc,%a0
   18306  1.1.6.2  bouyer 
   18307  1.1.6.2  bouyer fmovm_out_ctrl_fp3:
   18308  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP3 be moved?
   18309  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_fp4	# no
   18310  1.1.6.2  bouyer 
   18311  1.1.6.2  bouyer 	fmovm.x		&0x10,(%a0)		# yes
   18312  1.1.6.2  bouyer 	add.l		&0xc,%a0
   18313  1.1.6.2  bouyer 
   18314  1.1.6.2  bouyer fmovm_out_ctrl_fp4:
   18315  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP4 be moved?
   18316  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_fp5	# no
   18317  1.1.6.2  bouyer 
   18318  1.1.6.2  bouyer 	fmovm.x		&0x08,(%a0)		# yes
   18319  1.1.6.2  bouyer 	add.l		&0xc,%a0
   18320  1.1.6.2  bouyer 
   18321  1.1.6.2  bouyer fmovm_out_ctrl_fp5:
   18322  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP5 be moved?
   18323  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_fp6	# no
   18324  1.1.6.2  bouyer 
   18325  1.1.6.2  bouyer 	fmovm.x		&0x04,(%a0)		# yes
   18326  1.1.6.2  bouyer 	add.l		&0xc,%a0
   18327  1.1.6.2  bouyer 
   18328  1.1.6.2  bouyer fmovm_out_ctrl_fp6:
   18329  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP6 be moved?
   18330  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_fp7	# no
   18331  1.1.6.2  bouyer 
   18332  1.1.6.2  bouyer 	fmovm.x		&0x02,(%a0)		# yes
   18333  1.1.6.2  bouyer 	add.l		&0xc,%a0
   18334  1.1.6.2  bouyer 
   18335  1.1.6.2  bouyer fmovm_out_ctrl_fp7:
   18336  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP7 be moved?
   18337  1.1.6.2  bouyer 	bpl.b		fmovm_out_ctrl_done	# no
   18338  1.1.6.2  bouyer 
   18339  1.1.6.2  bouyer 	fmovm.x		&0x01,(%a0)		# yes
   18340  1.1.6.2  bouyer 	add.l		&0xc,%a0
   18341  1.1.6.2  bouyer 
   18342  1.1.6.2  bouyer fmovm_out_ctrl_done:
   18343  1.1.6.2  bouyer 	mov.l		%a1,L_SCR1(%a6)
   18344  1.1.6.2  bouyer 
   18345  1.1.6.2  bouyer 	lea		(%sp),%a0		# pass: supervisor src
   18346  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save size
   18347  1.1.6.2  bouyer 	bsr.l		_dmem_write		# copy data to user mem
   18348  1.1.6.2  bouyer 
   18349  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0
   18350  1.1.6.2  bouyer 	add.l		%d0,%sp			# clear fpreg data from stack
   18351  1.1.6.2  bouyer 
   18352  1.1.6.2  bouyer 	tst.l		%d1			# did dstore err?
   18353  1.1.6.2  bouyer 	bne.w		fmovm_out_err		# yes
   18354  1.1.6.2  bouyer 
   18355  1.1.6.2  bouyer 	rts
   18356  1.1.6.2  bouyer 
   18357  1.1.6.2  bouyer ############
   18358  1.1.6.2  bouyer # MOVE IN: #
   18359  1.1.6.2  bouyer ############
   18360  1.1.6.2  bouyer fmovm_data_in:
   18361  1.1.6.2  bouyer 	mov.l		%a0,L_SCR1(%a6)
   18362  1.1.6.2  bouyer 
   18363  1.1.6.2  bouyer 	sub.l		%d0,%sp			# make room for fpregs
   18364  1.1.6.2  bouyer 	lea		(%sp),%a1
   18365  1.1.6.2  bouyer 
   18366  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# save bit string for later
   18367  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)		# save # of bytes
   18368  1.1.6.2  bouyer 
   18369  1.1.6.2  bouyer 	bsr.l		_dmem_read		# copy data from user mem
   18370  1.1.6.2  bouyer 
   18371  1.1.6.2  bouyer 	mov.l		(%sp)+,%d0		# retrieve # of bytes
   18372  1.1.6.2  bouyer 
   18373  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   18374  1.1.6.2  bouyer 	bne.w		fmovm_in_err		# yes
   18375  1.1.6.2  bouyer 
   18376  1.1.6.2  bouyer 	mov.l		(%sp)+,%d1		# load bit string
   18377  1.1.6.2  bouyer 
   18378  1.1.6.2  bouyer 	lea		(%sp),%a0		# addr of stack
   18379  1.1.6.2  bouyer 
   18380  1.1.6.2  bouyer 	tst.b		%d1			# should FP0 be moved?
   18381  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_fp1	# no
   18382  1.1.6.2  bouyer 
   18383  1.1.6.2  bouyer 	mov.l		(%a0)+,0x0+EXC_FP0(%a6)	# yes
   18384  1.1.6.2  bouyer 	mov.l		(%a0)+,0x4+EXC_FP0(%a6)
   18385  1.1.6.2  bouyer 	mov.l		(%a0)+,0x8+EXC_FP0(%a6)
   18386  1.1.6.2  bouyer 
   18387  1.1.6.2  bouyer fmovm_data_in_fp1:
   18388  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP1 be moved?
   18389  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_fp2	# no
   18390  1.1.6.2  bouyer 
   18391  1.1.6.2  bouyer 	mov.l		(%a0)+,0x0+EXC_FP1(%a6)	# yes
   18392  1.1.6.2  bouyer 	mov.l		(%a0)+,0x4+EXC_FP1(%a6)
   18393  1.1.6.2  bouyer 	mov.l		(%a0)+,0x8+EXC_FP1(%a6)
   18394  1.1.6.2  bouyer 
   18395  1.1.6.2  bouyer fmovm_data_in_fp2:
   18396  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP2 be moved?
   18397  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_fp3	# no
   18398  1.1.6.2  bouyer 
   18399  1.1.6.2  bouyer 	fmovm.x		(%a0)+,&0x20		# yes
   18400  1.1.6.2  bouyer 
   18401  1.1.6.2  bouyer fmovm_data_in_fp3:
   18402  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP3 be moved?
   18403  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_fp4	# no
   18404  1.1.6.2  bouyer 
   18405  1.1.6.2  bouyer 	fmovm.x		(%a0)+,&0x10		# yes
   18406  1.1.6.2  bouyer 
   18407  1.1.6.2  bouyer fmovm_data_in_fp4:
   18408  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP4 be moved?
   18409  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_fp5	# no
   18410  1.1.6.2  bouyer 
   18411  1.1.6.2  bouyer 	fmovm.x		(%a0)+,&0x08		# yes
   18412  1.1.6.2  bouyer 
   18413  1.1.6.2  bouyer fmovm_data_in_fp5:
   18414  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP5 be moved?
   18415  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_fp6	# no
   18416  1.1.6.2  bouyer 
   18417  1.1.6.2  bouyer 	fmovm.x		(%a0)+,&0x04		# yes
   18418  1.1.6.2  bouyer 
   18419  1.1.6.2  bouyer fmovm_data_in_fp6:
   18420  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP6 be moved?
   18421  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_fp7	# no
   18422  1.1.6.2  bouyer 
   18423  1.1.6.2  bouyer 	fmovm.x		(%a0)+,&0x02		# yes
   18424  1.1.6.2  bouyer 
   18425  1.1.6.2  bouyer fmovm_data_in_fp7:
   18426  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# should FP7 be moved?
   18427  1.1.6.2  bouyer 	bpl.b		fmovm_data_in_done	# no
   18428  1.1.6.2  bouyer 
   18429  1.1.6.2  bouyer 	fmovm.x		(%a0)+,&0x01		# yes
   18430  1.1.6.2  bouyer 
   18431  1.1.6.2  bouyer fmovm_data_in_done:
   18432  1.1.6.2  bouyer 	add.l		%d0,%sp			# remove fpregs from stack
   18433  1.1.6.2  bouyer 	rts
   18434  1.1.6.2  bouyer 
   18435  1.1.6.2  bouyer #####################################
   18436  1.1.6.2  bouyer 
   18437  1.1.6.2  bouyer fmovm_data_done:
   18438  1.1.6.2  bouyer 	rts
   18439  1.1.6.2  bouyer 
   18440  1.1.6.2  bouyer ##############################################################################
   18441  1.1.6.2  bouyer 
   18442  1.1.6.2  bouyer #
   18443  1.1.6.2  bouyer # table indexed by the operation's bit string that gives the number
   18444  1.1.6.2  bouyer # of bytes that will be moved.
   18445  1.1.6.2  bouyer #
   18446  1.1.6.2  bouyer # number of bytes = (# of 1's in bit string) * 12(bytes/fpreg)
   18447  1.1.6.2  bouyer #
   18448  1.1.6.2  bouyer tbl_fmovm_size:
   18449  1.1.6.2  bouyer 	byte	0x00,0x0c,0x0c,0x18,0x0c,0x18,0x18,0x24
   18450  1.1.6.2  bouyer 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18451  1.1.6.2  bouyer 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18452  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18453  1.1.6.2  bouyer 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18454  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18455  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18456  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18457  1.1.6.2  bouyer 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18458  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18459  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18460  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18461  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18462  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18463  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18464  1.1.6.2  bouyer 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18465  1.1.6.2  bouyer 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
   18466  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18467  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18468  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18469  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18470  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18471  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18472  1.1.6.2  bouyer 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18473  1.1.6.2  bouyer 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
   18474  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18475  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18476  1.1.6.2  bouyer 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18477  1.1.6.2  bouyer 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
   18478  1.1.6.2  bouyer 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18479  1.1.6.2  bouyer 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
   18480  1.1.6.2  bouyer 	byte	0x3c,0x48,0x48,0x54,0x48,0x54,0x54,0x60
   18481  1.1.6.2  bouyer 
   18482  1.1.6.2  bouyer #
   18483  1.1.6.2  bouyer # table to convert a pre-decrement bit string into a post-increment
   18484  1.1.6.2  bouyer # or control bit string.
   18485  1.1.6.2  bouyer # ex: 	0x00	==>	0x00
   18486  1.1.6.2  bouyer #	0x01	==>	0x80
   18487  1.1.6.2  bouyer #	0x02	==>	0x40
   18488  1.1.6.2  bouyer #		.
   18489  1.1.6.2  bouyer #		.
   18490  1.1.6.2  bouyer #	0xfd	==>	0xbf
   18491  1.1.6.2  bouyer #	0xfe	==>	0x7f
   18492  1.1.6.2  bouyer #	0xff	==>	0xff
   18493  1.1.6.2  bouyer #
   18494  1.1.6.2  bouyer tbl_fmovm_convert:
   18495  1.1.6.2  bouyer 	byte	0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0
   18496  1.1.6.2  bouyer 	byte	0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0
   18497  1.1.6.2  bouyer 	byte	0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8
   18498  1.1.6.2  bouyer 	byte	0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8
   18499  1.1.6.2  bouyer 	byte	0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4
   18500  1.1.6.2  bouyer 	byte	0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4
   18501  1.1.6.2  bouyer 	byte	0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec
   18502  1.1.6.2  bouyer 	byte	0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc
   18503  1.1.6.2  bouyer 	byte	0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2
   18504  1.1.6.2  bouyer 	byte	0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2
   18505  1.1.6.2  bouyer 	byte	0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea
   18506  1.1.6.2  bouyer 	byte	0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa
   18507  1.1.6.2  bouyer 	byte	0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6
   18508  1.1.6.2  bouyer 	byte	0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6
   18509  1.1.6.2  bouyer 	byte	0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee
   18510  1.1.6.2  bouyer 	byte	0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe
   18511  1.1.6.2  bouyer 	byte	0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1
   18512  1.1.6.2  bouyer 	byte	0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1
   18513  1.1.6.2  bouyer 	byte	0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9
   18514  1.1.6.2  bouyer 	byte	0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9
   18515  1.1.6.2  bouyer 	byte	0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5
   18516  1.1.6.2  bouyer 	byte	0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5
   18517  1.1.6.2  bouyer 	byte	0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed
   18518  1.1.6.2  bouyer 	byte	0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd
   18519  1.1.6.2  bouyer 	byte	0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3
   18520  1.1.6.2  bouyer 	byte	0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3
   18521  1.1.6.2  bouyer 	byte	0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb
   18522  1.1.6.2  bouyer 	byte	0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb
   18523  1.1.6.2  bouyer 	byte	0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7
   18524  1.1.6.2  bouyer 	byte	0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7
   18525  1.1.6.2  bouyer 	byte	0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef
   18526  1.1.6.2  bouyer 	byte	0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
   18527  1.1.6.2  bouyer 
   18528  1.1.6.2  bouyer 	global		fmovm_calc_ea
   18529  1.1.6.2  bouyer ###############################################
   18530  1.1.6.2  bouyer # _fmovm_calc_ea: calculate effective address #
   18531  1.1.6.2  bouyer ###############################################
   18532  1.1.6.2  bouyer fmovm_calc_ea:
   18533  1.1.6.2  bouyer 	mov.l		%d0,%a0			# move # bytes to a0
   18534  1.1.6.2  bouyer 
   18535  1.1.6.2  bouyer # currently, MODE and REG are taken from the EXC_OPWORD. this could be
   18536  1.1.6.2  bouyer # easily changed if they were inputs passed in registers.
   18537  1.1.6.2  bouyer 	mov.w		EXC_OPWORD(%a6),%d0	# fetch opcode word
   18538  1.1.6.2  bouyer 	mov.w		%d0,%d1			# make a copy
   18539  1.1.6.2  bouyer 
   18540  1.1.6.2  bouyer 	andi.w		&0x3f,%d0		# extract mode field
   18541  1.1.6.2  bouyer 	andi.l		&0x7,%d1		# extract reg  field
   18542  1.1.6.2  bouyer 
   18543  1.1.6.2  bouyer # jump to the corresponding function for each {MODE,REG} pair.
   18544  1.1.6.2  bouyer 	mov.w		(tbl_fea_mode.b,%pc,%d0.w*2),%d0 # fetch jmp distance
   18545  1.1.6.2  bouyer 	jmp		(tbl_fea_mode.b,%pc,%d0.w*1) # jmp to correct ea mode
   18546  1.1.6.2  bouyer 
   18547  1.1.6.2  bouyer 	swbeg		&64
   18548  1.1.6.2  bouyer tbl_fea_mode:
   18549  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18550  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18551  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18552  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18553  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18554  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18555  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18556  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18557  1.1.6.2  bouyer 
   18558  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18559  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18560  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18561  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18562  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18563  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18564  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18565  1.1.6.2  bouyer 	short		tbl_fea_mode	-	tbl_fea_mode
   18566  1.1.6.2  bouyer 
   18567  1.1.6.2  bouyer 	short		faddr_ind_a0	- 	tbl_fea_mode
   18568  1.1.6.2  bouyer 	short		faddr_ind_a1	- 	tbl_fea_mode
   18569  1.1.6.2  bouyer 	short		faddr_ind_a2	- 	tbl_fea_mode
   18570  1.1.6.2  bouyer 	short		faddr_ind_a3 	- 	tbl_fea_mode
   18571  1.1.6.2  bouyer 	short		faddr_ind_a4 	- 	tbl_fea_mode
   18572  1.1.6.2  bouyer 	short		faddr_ind_a5 	- 	tbl_fea_mode
   18573  1.1.6.2  bouyer 	short		faddr_ind_a6 	- 	tbl_fea_mode
   18574  1.1.6.2  bouyer 	short		faddr_ind_a7 	- 	tbl_fea_mode
   18575  1.1.6.2  bouyer 
   18576  1.1.6.2  bouyer 	short		faddr_ind_p_a0	- 	tbl_fea_mode
   18577  1.1.6.2  bouyer 	short		faddr_ind_p_a1 	- 	tbl_fea_mode
   18578  1.1.6.2  bouyer 	short		faddr_ind_p_a2 	- 	tbl_fea_mode
   18579  1.1.6.2  bouyer 	short		faddr_ind_p_a3 	- 	tbl_fea_mode
   18580  1.1.6.2  bouyer 	short		faddr_ind_p_a4 	- 	tbl_fea_mode
   18581  1.1.6.2  bouyer 	short		faddr_ind_p_a5 	- 	tbl_fea_mode
   18582  1.1.6.2  bouyer 	short		faddr_ind_p_a6 	- 	tbl_fea_mode
   18583  1.1.6.2  bouyer 	short		faddr_ind_p_a7 	- 	tbl_fea_mode
   18584  1.1.6.2  bouyer 
   18585  1.1.6.2  bouyer 	short		faddr_ind_m_a0 	- 	tbl_fea_mode
   18586  1.1.6.2  bouyer 	short		faddr_ind_m_a1 	- 	tbl_fea_mode
   18587  1.1.6.2  bouyer 	short		faddr_ind_m_a2 	- 	tbl_fea_mode
   18588  1.1.6.2  bouyer 	short		faddr_ind_m_a3 	- 	tbl_fea_mode
   18589  1.1.6.2  bouyer 	short		faddr_ind_m_a4 	- 	tbl_fea_mode
   18590  1.1.6.2  bouyer 	short		faddr_ind_m_a5 	- 	tbl_fea_mode
   18591  1.1.6.2  bouyer 	short		faddr_ind_m_a6 	- 	tbl_fea_mode
   18592  1.1.6.2  bouyer 	short		faddr_ind_m_a7 	- 	tbl_fea_mode
   18593  1.1.6.2  bouyer 
   18594  1.1.6.2  bouyer 	short		faddr_ind_disp_a0	- 	tbl_fea_mode
   18595  1.1.6.2  bouyer 	short		faddr_ind_disp_a1 	- 	tbl_fea_mode
   18596  1.1.6.2  bouyer 	short		faddr_ind_disp_a2 	- 	tbl_fea_mode
   18597  1.1.6.2  bouyer 	short		faddr_ind_disp_a3 	- 	tbl_fea_mode
   18598  1.1.6.2  bouyer 	short		faddr_ind_disp_a4 	- 	tbl_fea_mode
   18599  1.1.6.2  bouyer 	short		faddr_ind_disp_a5 	- 	tbl_fea_mode
   18600  1.1.6.2  bouyer 	short		faddr_ind_disp_a6 	- 	tbl_fea_mode
   18601  1.1.6.2  bouyer 	short		faddr_ind_disp_a7	-	tbl_fea_mode
   18602  1.1.6.2  bouyer 
   18603  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18604  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18605  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18606  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18607  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18608  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18609  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18610  1.1.6.2  bouyer 	short		faddr_ind_ext 	- 	tbl_fea_mode
   18611  1.1.6.2  bouyer 
   18612  1.1.6.2  bouyer 	short		fabs_short	- 	tbl_fea_mode
   18613  1.1.6.2  bouyer 	short		fabs_long	- 	tbl_fea_mode
   18614  1.1.6.2  bouyer 	short		fpc_ind		- 	tbl_fea_mode
   18615  1.1.6.2  bouyer 	short		fpc_ind_ext	- 	tbl_fea_mode
   18616  1.1.6.2  bouyer 	short		tbl_fea_mode	- 	tbl_fea_mode
   18617  1.1.6.2  bouyer 	short		tbl_fea_mode	- 	tbl_fea_mode
   18618  1.1.6.2  bouyer 	short		tbl_fea_mode	- 	tbl_fea_mode
   18619  1.1.6.2  bouyer 	short		tbl_fea_mode	- 	tbl_fea_mode
   18620  1.1.6.2  bouyer 
   18621  1.1.6.2  bouyer ###################################
   18622  1.1.6.2  bouyer # Address register indirect: (An) #
   18623  1.1.6.2  bouyer ###################################
   18624  1.1.6.2  bouyer faddr_ind_a0:
   18625  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0x8(%a6),%a0	# Get current a0
   18626  1.1.6.2  bouyer 	rts
   18627  1.1.6.2  bouyer 
   18628  1.1.6.2  bouyer faddr_ind_a1:
   18629  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0xc(%a6),%a0	# Get current a1
   18630  1.1.6.2  bouyer 	rts
   18631  1.1.6.2  bouyer 
   18632  1.1.6.2  bouyer faddr_ind_a2:
   18633  1.1.6.2  bouyer 	mov.l		%a2,%a0			# Get current a2
   18634  1.1.6.2  bouyer 	rts
   18635  1.1.6.2  bouyer 
   18636  1.1.6.2  bouyer faddr_ind_a3:
   18637  1.1.6.2  bouyer 	mov.l		%a3,%a0			# Get current a3
   18638  1.1.6.2  bouyer 	rts
   18639  1.1.6.2  bouyer 
   18640  1.1.6.2  bouyer faddr_ind_a4:
   18641  1.1.6.2  bouyer 	mov.l		%a4,%a0			# Get current a4
   18642  1.1.6.2  bouyer 	rts
   18643  1.1.6.2  bouyer 
   18644  1.1.6.2  bouyer faddr_ind_a5:
   18645  1.1.6.2  bouyer 	mov.l		%a5,%a0			# Get current a5
   18646  1.1.6.2  bouyer 	rts
   18647  1.1.6.2  bouyer 
   18648  1.1.6.2  bouyer faddr_ind_a6:
   18649  1.1.6.2  bouyer 	mov.l		(%a6),%a0		# Get current a6
   18650  1.1.6.2  bouyer 	rts
   18651  1.1.6.2  bouyer 
   18652  1.1.6.2  bouyer faddr_ind_a7:
   18653  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%a0		# Get current a7
   18654  1.1.6.2  bouyer 	rts
   18655  1.1.6.2  bouyer 
   18656  1.1.6.2  bouyer #####################################################
   18657  1.1.6.2  bouyer # Address register indirect w/ postincrement: (An)+ #
   18658  1.1.6.2  bouyer #####################################################
   18659  1.1.6.2  bouyer faddr_ind_p_a0:
   18660  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0x8(%a6),%d0	# Get current a0
   18661  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18662  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18663  1.1.6.2  bouyer 	mov.l		%d1,EXC_DREGS+0x8(%a6)	# Save incr value
   18664  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18665  1.1.6.2  bouyer 	rts
   18666  1.1.6.2  bouyer 
   18667  1.1.6.2  bouyer faddr_ind_p_a1:
   18668  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0xc(%a6),%d0	# Get current a1
   18669  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18670  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18671  1.1.6.2  bouyer 	mov.l		%d1,EXC_DREGS+0xc(%a6)	# Save incr value
   18672  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18673  1.1.6.2  bouyer 	rts
   18674  1.1.6.2  bouyer 
   18675  1.1.6.2  bouyer faddr_ind_p_a2:
   18676  1.1.6.2  bouyer 	mov.l		%a2,%d0			# Get current a2
   18677  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18678  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18679  1.1.6.2  bouyer 	mov.l		%d1,%a2			# Save incr value
   18680  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18681  1.1.6.2  bouyer 	rts
   18682  1.1.6.2  bouyer 
   18683  1.1.6.2  bouyer faddr_ind_p_a3:
   18684  1.1.6.2  bouyer 	mov.l		%a3,%d0			# Get current a3
   18685  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18686  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18687  1.1.6.2  bouyer 	mov.l		%d1,%a3			# Save incr value
   18688  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18689  1.1.6.2  bouyer 	rts
   18690  1.1.6.2  bouyer 
   18691  1.1.6.2  bouyer faddr_ind_p_a4:
   18692  1.1.6.2  bouyer 	mov.l		%a4,%d0			# Get current a4
   18693  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18694  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18695  1.1.6.2  bouyer 	mov.l		%d1,%a4			# Save incr value
   18696  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18697  1.1.6.2  bouyer 	rts
   18698  1.1.6.2  bouyer 
   18699  1.1.6.2  bouyer faddr_ind_p_a5:
   18700  1.1.6.2  bouyer 	mov.l		%a5,%d0			# Get current a5
   18701  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18702  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18703  1.1.6.2  bouyer 	mov.l		%d1,%a5			# Save incr value
   18704  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18705  1.1.6.2  bouyer 	rts
   18706  1.1.6.2  bouyer 
   18707  1.1.6.2  bouyer faddr_ind_p_a6:
   18708  1.1.6.2  bouyer 	mov.l		(%a6),%d0		# Get current a6
   18709  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18710  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18711  1.1.6.2  bouyer 	mov.l		%d1,(%a6)		# Save incr value
   18712  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18713  1.1.6.2  bouyer 	rts
   18714  1.1.6.2  bouyer 
   18715  1.1.6.2  bouyer faddr_ind_p_a7:
   18716  1.1.6.2  bouyer 	mov.b		&mia7_flg,SPCOND_FLG(%a6) # set "special case" flag
   18717  1.1.6.2  bouyer 
   18718  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%d0		# Get current a7
   18719  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18720  1.1.6.2  bouyer 	add.l		%a0,%d1			# Increment
   18721  1.1.6.2  bouyer 	mov.l		%d1,EXC_A7(%a6)		# Save incr value
   18722  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18723  1.1.6.2  bouyer 	rts
   18724  1.1.6.2  bouyer 
   18725  1.1.6.2  bouyer ####################################################
   18726  1.1.6.2  bouyer # Address register indirect w/ predecrement: -(An) #
   18727  1.1.6.2  bouyer ####################################################
   18728  1.1.6.2  bouyer faddr_ind_m_a0:
   18729  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0x8(%a6),%d0	# Get current a0
   18730  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18731  1.1.6.2  bouyer 	mov.l		%d0,EXC_DREGS+0x8(%a6)	# Save decr value
   18732  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18733  1.1.6.2  bouyer 	rts
   18734  1.1.6.2  bouyer 
   18735  1.1.6.2  bouyer faddr_ind_m_a1:
   18736  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0xc(%a6),%d0	# Get current a1
   18737  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18738  1.1.6.2  bouyer 	mov.l		%d0,EXC_DREGS+0xc(%a6)	# Save decr value
   18739  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18740  1.1.6.2  bouyer 	rts
   18741  1.1.6.2  bouyer 
   18742  1.1.6.2  bouyer faddr_ind_m_a2:
   18743  1.1.6.2  bouyer 	mov.l		%a2,%d0			# Get current a2
   18744  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18745  1.1.6.2  bouyer 	mov.l		%d0,%a2			# Save decr value
   18746  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18747  1.1.6.2  bouyer 	rts
   18748  1.1.6.2  bouyer 
   18749  1.1.6.2  bouyer faddr_ind_m_a3:
   18750  1.1.6.2  bouyer 	mov.l		%a3,%d0			# Get current a3
   18751  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18752  1.1.6.2  bouyer 	mov.l		%d0,%a3			# Save decr value
   18753  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18754  1.1.6.2  bouyer 	rts
   18755  1.1.6.2  bouyer 
   18756  1.1.6.2  bouyer faddr_ind_m_a4:
   18757  1.1.6.2  bouyer 	mov.l		%a4,%d0			# Get current a4
   18758  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18759  1.1.6.2  bouyer 	mov.l		%d0,%a4			# Save decr value
   18760  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18761  1.1.6.2  bouyer 	rts
   18762  1.1.6.2  bouyer 
   18763  1.1.6.2  bouyer faddr_ind_m_a5:
   18764  1.1.6.2  bouyer 	mov.l		%a5,%d0			# Get current a5
   18765  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18766  1.1.6.2  bouyer 	mov.l		%d0,%a5			# Save decr value
   18767  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18768  1.1.6.2  bouyer 	rts
   18769  1.1.6.2  bouyer 
   18770  1.1.6.2  bouyer faddr_ind_m_a6:
   18771  1.1.6.2  bouyer 	mov.l		(%a6),%d0		# Get current a6
   18772  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18773  1.1.6.2  bouyer 	mov.l		%d0,(%a6)		# Save decr value
   18774  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18775  1.1.6.2  bouyer 	rts
   18776  1.1.6.2  bouyer 
   18777  1.1.6.2  bouyer faddr_ind_m_a7:
   18778  1.1.6.2  bouyer 	mov.b		&mda7_flg,SPCOND_FLG(%a6) # set "special case" flag
   18779  1.1.6.2  bouyer 
   18780  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%d0		# Get current a7
   18781  1.1.6.2  bouyer 	sub.l		%a0,%d0			# Decrement
   18782  1.1.6.2  bouyer 	mov.l		%d0,EXC_A7(%a6)		# Save decr value
   18783  1.1.6.2  bouyer 	mov.l		%d0,%a0
   18784  1.1.6.2  bouyer 	rts
   18785  1.1.6.2  bouyer 
   18786  1.1.6.2  bouyer ########################################################
   18787  1.1.6.2  bouyer # Address register indirect w/ displacement: (d16, An) #
   18788  1.1.6.2  bouyer ########################################################
   18789  1.1.6.2  bouyer faddr_ind_disp_a0:
   18790  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18791  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18792  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18793  1.1.6.2  bouyer 
   18794  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18795  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18796  1.1.6.2  bouyer 
   18797  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18798  1.1.6.2  bouyer 
   18799  1.1.6.2  bouyer 	add.l		EXC_DREGS+0x8(%a6),%a0	# a0 + d16
   18800  1.1.6.2  bouyer 	rts
   18801  1.1.6.2  bouyer 
   18802  1.1.6.2  bouyer faddr_ind_disp_a1:
   18803  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18804  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18805  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18806  1.1.6.2  bouyer 
   18807  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18808  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18809  1.1.6.2  bouyer 
   18810  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18811  1.1.6.2  bouyer 
   18812  1.1.6.2  bouyer 	add.l		EXC_DREGS+0xc(%a6),%a0	# a1 + d16
   18813  1.1.6.2  bouyer 	rts
   18814  1.1.6.2  bouyer 
   18815  1.1.6.2  bouyer faddr_ind_disp_a2:
   18816  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18817  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18818  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18819  1.1.6.2  bouyer 
   18820  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18821  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18822  1.1.6.2  bouyer 
   18823  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18824  1.1.6.2  bouyer 
   18825  1.1.6.2  bouyer 	add.l		%a2,%a0			# a2 + d16
   18826  1.1.6.2  bouyer 	rts
   18827  1.1.6.2  bouyer 
   18828  1.1.6.2  bouyer faddr_ind_disp_a3:
   18829  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18830  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18831  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18832  1.1.6.2  bouyer 
   18833  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18834  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18835  1.1.6.2  bouyer 
   18836  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18837  1.1.6.2  bouyer 
   18838  1.1.6.2  bouyer 	add.l		%a3,%a0			# a3 + d16
   18839  1.1.6.2  bouyer 	rts
   18840  1.1.6.2  bouyer 
   18841  1.1.6.2  bouyer faddr_ind_disp_a4:
   18842  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18843  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18844  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18845  1.1.6.2  bouyer 
   18846  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18847  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18848  1.1.6.2  bouyer 
   18849  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18850  1.1.6.2  bouyer 
   18851  1.1.6.2  bouyer 	add.l		%a4,%a0			# a4 + d16
   18852  1.1.6.2  bouyer 	rts
   18853  1.1.6.2  bouyer 
   18854  1.1.6.2  bouyer faddr_ind_disp_a5:
   18855  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18856  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18857  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18858  1.1.6.2  bouyer 
   18859  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18860  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18861  1.1.6.2  bouyer 
   18862  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18863  1.1.6.2  bouyer 
   18864  1.1.6.2  bouyer 	add.l		%a5,%a0			# a5 + d16
   18865  1.1.6.2  bouyer 	rts
   18866  1.1.6.2  bouyer 
   18867  1.1.6.2  bouyer faddr_ind_disp_a6:
   18868  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18869  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18870  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18871  1.1.6.2  bouyer 
   18872  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18873  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18874  1.1.6.2  bouyer 
   18875  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18876  1.1.6.2  bouyer 
   18877  1.1.6.2  bouyer 	add.l		(%a6),%a0		# a6 + d16
   18878  1.1.6.2  bouyer 	rts
   18879  1.1.6.2  bouyer 
   18880  1.1.6.2  bouyer faddr_ind_disp_a7:
   18881  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18882  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18883  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   18884  1.1.6.2  bouyer 
   18885  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18886  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18887  1.1.6.2  bouyer 
   18888  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18889  1.1.6.2  bouyer 
   18890  1.1.6.2  bouyer 	add.l		EXC_A7(%a6),%a0		# a7 + d16
   18891  1.1.6.2  bouyer 	rts
   18892  1.1.6.2  bouyer 
   18893  1.1.6.2  bouyer ########################################################################
   18894  1.1.6.2  bouyer # Address register indirect w/ index(8-bit displacement): (d8, An, Xn) #
   18895  1.1.6.2  bouyer #    "       "         "    w/   "  (base displacement): (bd, An, Xn)  #
   18896  1.1.6.2  bouyer # Memory indirect postindexed: ([bd, An], Xn, od)		       #
   18897  1.1.6.2  bouyer # Memory indirect preindexed: ([bd, An, Xn], od)		       #
   18898  1.1.6.2  bouyer ########################################################################
   18899  1.1.6.2  bouyer faddr_ind_ext:
   18900  1.1.6.2  bouyer 	addq.l		&0x8,%d1
   18901  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch base areg
   18902  1.1.6.2  bouyer 	mov.l		%d0,-(%sp)
   18903  1.1.6.2  bouyer 
   18904  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18905  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18906  1.1.6.2  bouyer 	bsr.l		_imem_read_word		# fetch extword in d0
   18907  1.1.6.2  bouyer 
   18908  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18909  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18910  1.1.6.2  bouyer 
   18911  1.1.6.2  bouyer 	mov.l		(%sp)+,%a0
   18912  1.1.6.2  bouyer 
   18913  1.1.6.2  bouyer 	btst		&0x8,%d0
   18914  1.1.6.2  bouyer 	bne.w		fcalc_mem_ind
   18915  1.1.6.2  bouyer 
   18916  1.1.6.2  bouyer 	mov.l		%d0,L_SCR1(%a6)		# hold opword
   18917  1.1.6.2  bouyer 
   18918  1.1.6.2  bouyer 	mov.l		%d0,%d1
   18919  1.1.6.2  bouyer 	rol.w		&0x4,%d1
   18920  1.1.6.2  bouyer 	andi.w		&0xf,%d1		# extract index regno
   18921  1.1.6.2  bouyer 
   18922  1.1.6.2  bouyer # count on fetch_dreg() not to alter a0...
   18923  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch index
   18924  1.1.6.2  bouyer 
   18925  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   18926  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d2		# fetch opword
   18927  1.1.6.2  bouyer 
   18928  1.1.6.2  bouyer 	btst		&0xb,%d2		# is it word or long?
   18929  1.1.6.2  bouyer 	bne.b		faii8_long
   18930  1.1.6.2  bouyer 	ext.l		%d0			# sign extend word index
   18931  1.1.6.2  bouyer faii8_long:
   18932  1.1.6.2  bouyer 	mov.l		%d2,%d1
   18933  1.1.6.2  bouyer 	rol.w		&0x7,%d1
   18934  1.1.6.2  bouyer 	andi.l		&0x3,%d1		# extract scale value
   18935  1.1.6.2  bouyer 
   18936  1.1.6.2  bouyer 	lsl.l		%d1,%d0			# shift index by scale
   18937  1.1.6.2  bouyer 
   18938  1.1.6.2  bouyer 	extb.l		%d2			# sign extend displacement
   18939  1.1.6.2  bouyer 	add.l		%d2,%d0			# index + disp
   18940  1.1.6.2  bouyer 	add.l		%d0,%a0			# An + (index + disp)
   18941  1.1.6.2  bouyer 
   18942  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore old d2
   18943  1.1.6.2  bouyer 	rts
   18944  1.1.6.2  bouyer 
   18945  1.1.6.2  bouyer ###########################
   18946  1.1.6.2  bouyer # Absolute short: (XXX).W #
   18947  1.1.6.2  bouyer ###########################
   18948  1.1.6.2  bouyer fabs_short:
   18949  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18950  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18951  1.1.6.2  bouyer 	bsr.l		_imem_read_word		# fetch short address
   18952  1.1.6.2  bouyer 
   18953  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18954  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18955  1.1.6.2  bouyer 
   18956  1.1.6.2  bouyer 	mov.w		%d0,%a0			# return <ea> in a0
   18957  1.1.6.2  bouyer 	rts
   18958  1.1.6.2  bouyer 
   18959  1.1.6.2  bouyer ##########################
   18960  1.1.6.2  bouyer # Absolute long: (XXX).L #
   18961  1.1.6.2  bouyer ##########################
   18962  1.1.6.2  bouyer fabs_long:
   18963  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18964  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18965  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch long address
   18966  1.1.6.2  bouyer 
   18967  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18968  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18969  1.1.6.2  bouyer 
   18970  1.1.6.2  bouyer 	mov.l		%d0,%a0			# return <ea> in a0
   18971  1.1.6.2  bouyer 	rts
   18972  1.1.6.2  bouyer 
   18973  1.1.6.2  bouyer #######################################################
   18974  1.1.6.2  bouyer # Program counter indirect w/ displacement: (d16, PC) #
   18975  1.1.6.2  bouyer #######################################################
   18976  1.1.6.2  bouyer fpc_ind:
   18977  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   18978  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   18979  1.1.6.2  bouyer 	bsr.l		_imem_read_word		# fetch word displacement
   18980  1.1.6.2  bouyer 
   18981  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   18982  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   18983  1.1.6.2  bouyer 
   18984  1.1.6.2  bouyer 	mov.w		%d0,%a0			# sign extend displacement
   18985  1.1.6.2  bouyer 
   18986  1.1.6.2  bouyer 	add.l		EXC_EXTWPTR(%a6),%a0	# pc + d16
   18987  1.1.6.2  bouyer 
   18988  1.1.6.2  bouyer # _imem_read_word() increased the extwptr by 2. need to adjust here.
   18989  1.1.6.2  bouyer 	subq.l		&0x2,%a0		# adjust <ea>
   18990  1.1.6.2  bouyer 	rts
   18991  1.1.6.2  bouyer 
   18992  1.1.6.2  bouyer ##########################################################
   18993  1.1.6.2  bouyer # PC indirect w/ index(8-bit displacement): (d8, PC, An) #
   18994  1.1.6.2  bouyer # "     "     w/   "  (base displacement): (bd, PC, An)  #
   18995  1.1.6.2  bouyer # PC memory indirect postindexed: ([bd, PC], Xn, od)     #
   18996  1.1.6.2  bouyer # PC memory indirect preindexed: ([bd, PC, Xn], od)      #
   18997  1.1.6.2  bouyer ##########################################################
   18998  1.1.6.2  bouyer fpc_ind_ext:
   18999  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19000  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19001  1.1.6.2  bouyer 	bsr.l		_imem_read_word		# fetch ext word
   19002  1.1.6.2  bouyer 
   19003  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19004  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19005  1.1.6.2  bouyer 
   19006  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# put base in a0
   19007  1.1.6.2  bouyer 	subq.l		&0x2,%a0		# adjust base
   19008  1.1.6.2  bouyer 
   19009  1.1.6.2  bouyer 	btst		&0x8,%d0		# is disp only 8 bits?
   19010  1.1.6.2  bouyer 	bne.w		fcalc_mem_ind		# calc memory indirect
   19011  1.1.6.2  bouyer 
   19012  1.1.6.2  bouyer 	mov.l		%d0,L_SCR1(%a6)		# store opword
   19013  1.1.6.2  bouyer 
   19014  1.1.6.2  bouyer 	mov.l		%d0,%d1			# make extword copy
   19015  1.1.6.2  bouyer 	rol.w		&0x4,%d1		# rotate reg num into place
   19016  1.1.6.2  bouyer 	andi.w		&0xf,%d1		# extract register number
   19017  1.1.6.2  bouyer 
   19018  1.1.6.2  bouyer # count on fetch_dreg() not to alter a0...
   19019  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch index
   19020  1.1.6.2  bouyer 
   19021  1.1.6.2  bouyer 	mov.l		%d2,-(%sp)		# save d2
   19022  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d2		# fetch opword
   19023  1.1.6.2  bouyer 
   19024  1.1.6.2  bouyer 	btst		&0xb,%d2		# is index word or long?
   19025  1.1.6.2  bouyer 	bne.b		fpii8_long		# long
   19026  1.1.6.2  bouyer 	ext.l		%d0			# sign extend word index
   19027  1.1.6.2  bouyer fpii8_long:
   19028  1.1.6.2  bouyer 	mov.l		%d2,%d1
   19029  1.1.6.2  bouyer 	rol.w		&0x7,%d1		# rotate scale value into place
   19030  1.1.6.2  bouyer 	andi.l		&0x3,%d1		# extract scale value
   19031  1.1.6.2  bouyer 
   19032  1.1.6.2  bouyer 	lsl.l		%d1,%d0			# shift index by scale
   19033  1.1.6.2  bouyer 
   19034  1.1.6.2  bouyer 	extb.l		%d2			# sign extend displacement
   19035  1.1.6.2  bouyer 	add.l		%d2,%d0			# disp + index
   19036  1.1.6.2  bouyer 	add.l		%d0,%a0			# An + (index + disp)
   19037  1.1.6.2  bouyer 
   19038  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore temp register
   19039  1.1.6.2  bouyer 	rts
   19040  1.1.6.2  bouyer 
   19041  1.1.6.2  bouyer # d2 = index
   19042  1.1.6.2  bouyer # d3 = base
   19043  1.1.6.2  bouyer # d4 = od
   19044  1.1.6.2  bouyer # d5 = extword
   19045  1.1.6.2  bouyer fcalc_mem_ind:
   19046  1.1.6.2  bouyer 	btst		&0x6,%d0		# is the index suppressed?
   19047  1.1.6.2  bouyer 	beq.b		fcalc_index
   19048  1.1.6.2  bouyer 
   19049  1.1.6.2  bouyer 	movm.l		&0x3c00,-(%sp)		# save d2-d5
   19050  1.1.6.2  bouyer 
   19051  1.1.6.2  bouyer 	mov.l		%d0,%d5			# put extword in d5
   19052  1.1.6.2  bouyer 	mov.l		%a0,%d3			# put base in d3
   19053  1.1.6.2  bouyer 
   19054  1.1.6.2  bouyer 	clr.l		%d2			# yes, so index = 0
   19055  1.1.6.2  bouyer 	bra.b		fbase_supp_ck
   19056  1.1.6.2  bouyer 
   19057  1.1.6.2  bouyer # index:
   19058  1.1.6.2  bouyer fcalc_index:
   19059  1.1.6.2  bouyer 	mov.l		%d0,L_SCR1(%a6)		# save d0 (opword)
   19060  1.1.6.2  bouyer 	bfextu		%d0{&16:&4},%d1		# fetch dreg index
   19061  1.1.6.2  bouyer 	bsr.l		fetch_dreg
   19062  1.1.6.2  bouyer 
   19063  1.1.6.2  bouyer 	movm.l		&0x3c00,-(%sp)		# save d2-d5
   19064  1.1.6.2  bouyer 	mov.l		%d0,%d2			# put index in d2
   19065  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d5
   19066  1.1.6.2  bouyer 	mov.l		%a0,%d3
   19067  1.1.6.2  bouyer 
   19068  1.1.6.2  bouyer 	btst		&0xb,%d5		# is index word or long?
   19069  1.1.6.2  bouyer 	bne.b		fno_ext
   19070  1.1.6.2  bouyer 	ext.l		%d2
   19071  1.1.6.2  bouyer 
   19072  1.1.6.2  bouyer fno_ext:
   19073  1.1.6.2  bouyer 	bfextu		%d5{&21:&2},%d0
   19074  1.1.6.2  bouyer 	lsl.l		%d0,%d2
   19075  1.1.6.2  bouyer 
   19076  1.1.6.2  bouyer # base address (passed as parameter in d3):
   19077  1.1.6.2  bouyer # we clear the value here if it should actually be suppressed.
   19078  1.1.6.2  bouyer fbase_supp_ck:
   19079  1.1.6.2  bouyer 	btst		&0x7,%d5		# is the bd suppressed?
   19080  1.1.6.2  bouyer 	beq.b		fno_base_sup
   19081  1.1.6.2  bouyer 	clr.l		%d3
   19082  1.1.6.2  bouyer 
   19083  1.1.6.2  bouyer # base displacement:
   19084  1.1.6.2  bouyer fno_base_sup:
   19085  1.1.6.2  bouyer 	bfextu		%d5{&26:&2},%d0		# get bd size
   19086  1.1.6.2  bouyer #	beq.l		fmovm_error		# if (size == 0) it's reserved
   19087  1.1.6.2  bouyer 
   19088  1.1.6.2  bouyer 	cmpi.b	 	%d0,&0x2
   19089  1.1.6.2  bouyer 	blt.b		fno_bd
   19090  1.1.6.2  bouyer 	beq.b		fget_word_bd
   19091  1.1.6.2  bouyer 
   19092  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19093  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19094  1.1.6.2  bouyer 	bsr.l		_imem_read_long
   19095  1.1.6.2  bouyer 
   19096  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19097  1.1.6.2  bouyer 	bne.l		fcea_iacc		# yes
   19098  1.1.6.2  bouyer 
   19099  1.1.6.2  bouyer 	bra.b		fchk_ind
   19100  1.1.6.2  bouyer 
   19101  1.1.6.2  bouyer fget_word_bd:
   19102  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19103  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19104  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   19105  1.1.6.2  bouyer 
   19106  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19107  1.1.6.2  bouyer 	bne.l		fcea_iacc		# yes
   19108  1.1.6.2  bouyer 
   19109  1.1.6.2  bouyer 	ext.l		%d0			# sign extend bd
   19110  1.1.6.2  bouyer 
   19111  1.1.6.2  bouyer fchk_ind:
   19112  1.1.6.2  bouyer 	add.l		%d0,%d3			# base += bd
   19113  1.1.6.2  bouyer 
   19114  1.1.6.2  bouyer # outer displacement:
   19115  1.1.6.2  bouyer fno_bd:
   19116  1.1.6.2  bouyer 	bfextu		%d5{&30:&2},%d0		# is od suppressed?
   19117  1.1.6.2  bouyer 	beq.w		faii_bd
   19118  1.1.6.2  bouyer 
   19119  1.1.6.2  bouyer 	cmpi.b	 	%d0,&0x2
   19120  1.1.6.2  bouyer 	blt.b		fnull_od
   19121  1.1.6.2  bouyer 	beq.b		fword_od
   19122  1.1.6.2  bouyer 
   19123  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19124  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19125  1.1.6.2  bouyer 	bsr.l		_imem_read_long
   19126  1.1.6.2  bouyer 
   19127  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19128  1.1.6.2  bouyer 	bne.l		fcea_iacc		# yes
   19129  1.1.6.2  bouyer 
   19130  1.1.6.2  bouyer 	bra.b 		fadd_them
   19131  1.1.6.2  bouyer 
   19132  1.1.6.2  bouyer fword_od:
   19133  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19134  1.1.6.2  bouyer 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19135  1.1.6.2  bouyer 	bsr.l		_imem_read_word
   19136  1.1.6.2  bouyer 
   19137  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19138  1.1.6.2  bouyer 	bne.l		fcea_iacc		# yes
   19139  1.1.6.2  bouyer 
   19140  1.1.6.2  bouyer 	ext.l		%d0			# sign extend od
   19141  1.1.6.2  bouyer 	bra.b		fadd_them
   19142  1.1.6.2  bouyer 
   19143  1.1.6.2  bouyer fnull_od:
   19144  1.1.6.2  bouyer 	clr.l		%d0
   19145  1.1.6.2  bouyer 
   19146  1.1.6.2  bouyer fadd_them:
   19147  1.1.6.2  bouyer 	mov.l		%d0,%d4
   19148  1.1.6.2  bouyer 
   19149  1.1.6.2  bouyer 	btst		&0x2,%d5		# pre or post indexing?
   19150  1.1.6.2  bouyer 	beq.b		fpre_indexed
   19151  1.1.6.2  bouyer 
   19152  1.1.6.2  bouyer 	mov.l		%d3,%a0
   19153  1.1.6.2  bouyer 	bsr.l		_dmem_read_long
   19154  1.1.6.2  bouyer 
   19155  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   19156  1.1.6.2  bouyer 	bne.w		fcea_err		# yes
   19157  1.1.6.2  bouyer 
   19158  1.1.6.2  bouyer 	add.l		%d2,%d0			# <ea> += index
   19159  1.1.6.2  bouyer 	add.l		%d4,%d0			# <ea> += od
   19160  1.1.6.2  bouyer 	bra.b		fdone_ea
   19161  1.1.6.2  bouyer 
   19162  1.1.6.2  bouyer fpre_indexed:
   19163  1.1.6.2  bouyer 	add.l		%d2,%d3			# preindexing
   19164  1.1.6.2  bouyer 	mov.l		%d3,%a0
   19165  1.1.6.2  bouyer 	bsr.l		_dmem_read_long
   19166  1.1.6.2  bouyer 
   19167  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   19168  1.1.6.2  bouyer 	bne.w		fcea_err		# yes
   19169  1.1.6.2  bouyer 
   19170  1.1.6.2  bouyer 	add.l		%d4,%d0			# ea += od
   19171  1.1.6.2  bouyer 	bra.b		fdone_ea
   19172  1.1.6.2  bouyer 
   19173  1.1.6.2  bouyer faii_bd:
   19174  1.1.6.2  bouyer 	add.l		%d2,%d3			# ea = (base + bd) + index
   19175  1.1.6.2  bouyer 	mov.l		%d3,%d0
   19176  1.1.6.2  bouyer fdone_ea:
   19177  1.1.6.2  bouyer 	mov.l		%d0,%a0
   19178  1.1.6.2  bouyer 
   19179  1.1.6.2  bouyer 	movm.l		(%sp)+,&0x003c		# restore d2-d5
   19180  1.1.6.2  bouyer 	rts
   19181  1.1.6.2  bouyer 
   19182  1.1.6.2  bouyer #########################################################
   19183  1.1.6.2  bouyer fcea_err:
   19184  1.1.6.2  bouyer 	mov.l		%d3,%a0
   19185  1.1.6.2  bouyer 
   19186  1.1.6.2  bouyer 	movm.l		(%sp)+,&0x003c		# restore d2-d5
   19187  1.1.6.2  bouyer 	mov.w		&0x0101,%d0
   19188  1.1.6.2  bouyer 	bra.l		iea_dacc
   19189  1.1.6.2  bouyer 
   19190  1.1.6.2  bouyer fcea_iacc:
   19191  1.1.6.2  bouyer 	movm.l		(%sp)+,&0x003c		# restore d2-d5
   19192  1.1.6.2  bouyer 	bra.l		iea_iacc
   19193  1.1.6.2  bouyer 
   19194  1.1.6.2  bouyer fmovm_out_err:
   19195  1.1.6.2  bouyer 	bsr.l		restore
   19196  1.1.6.2  bouyer 	mov.w		&0x00e1,%d0
   19197  1.1.6.2  bouyer 	bra.b		fmovm_err
   19198  1.1.6.2  bouyer 
   19199  1.1.6.2  bouyer fmovm_in_err:
   19200  1.1.6.2  bouyer 	bsr.l		restore
   19201  1.1.6.2  bouyer 	mov.w		&0x0161,%d0
   19202  1.1.6.2  bouyer 
   19203  1.1.6.2  bouyer fmovm_err:
   19204  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%a0
   19205  1.1.6.2  bouyer 	bra.l		iea_dacc
   19206  1.1.6.2  bouyer 
   19207  1.1.6.2  bouyer #########################################################################
   19208  1.1.6.2  bouyer # XDEF ****************************************************************	#
   19209  1.1.6.2  bouyer # 	fmovm_ctrl(): emulate fmovm.l of control registers instr	#
   19210  1.1.6.2  bouyer #									#
   19211  1.1.6.2  bouyer # XREF ****************************************************************	#
   19212  1.1.6.2  bouyer #	_imem_read_long() - read longword from memory			#
   19213  1.1.6.2  bouyer #	iea_iacc() - _imem_read_long() failed; error recovery		#
   19214  1.1.6.2  bouyer #									#
   19215  1.1.6.2  bouyer # INPUT ***************************************************************	#
   19216  1.1.6.2  bouyer #	None								#
   19217  1.1.6.2  bouyer # 									#
   19218  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   19219  1.1.6.2  bouyer #	If _imem_read_long() doesn't fail:				#
   19220  1.1.6.2  bouyer #		USER_FPCR(a6)  = new FPCR value				#
   19221  1.1.6.2  bouyer #		USER_FPSR(a6)  = new FPSR value				#
   19222  1.1.6.2  bouyer #		USER_FPIAR(a6) = new FPIAR value			#
   19223  1.1.6.2  bouyer #									#
   19224  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   19225  1.1.6.2  bouyer # 	Decode the instruction type by looking at the extension word 	#
   19226  1.1.6.2  bouyer # in order to see how many control registers to fetch from memory.	#
   19227  1.1.6.2  bouyer # Fetch them using _imem_read_long(). If this fetch fails, exit through	#
   19228  1.1.6.2  bouyer # the special access error exit handler iea_iacc().			#
   19229  1.1.6.2  bouyer #									#
   19230  1.1.6.2  bouyer # Instruction word decoding:						#
   19231  1.1.6.2  bouyer #									#
   19232  1.1.6.2  bouyer # 	fmovem.l #<data>, {FPIAR&|FPCR&|FPSR}				#
   19233  1.1.6.2  bouyer #									#
   19234  1.1.6.2  bouyer #		WORD1			WORD2				#
   19235  1.1.6.2  bouyer #	1111 0010 00 111100	100$ $$00 0000 0000			#
   19236  1.1.6.2  bouyer #									#
   19237  1.1.6.2  bouyer #	$$$ (100): FPCR							#
   19238  1.1.6.2  bouyer #	    (010): FPSR							#
   19239  1.1.6.2  bouyer #	    (001): FPIAR						#
   19240  1.1.6.2  bouyer #	    (000): FPIAR						#
   19241  1.1.6.2  bouyer #									#
   19242  1.1.6.2  bouyer #########################################################################
   19243  1.1.6.2  bouyer 
   19244  1.1.6.2  bouyer 	global		fmovm_ctrl
   19245  1.1.6.2  bouyer fmovm_ctrl:
   19246  1.1.6.2  bouyer 	mov.b		EXC_EXTWORD(%a6),%d0	# fetch reg select bits
   19247  1.1.6.2  bouyer 	cmpi.b		%d0,&0x9c		# fpcr & fpsr & fpiar ?
   19248  1.1.6.2  bouyer 	beq.w		fctrl_in_7		# yes
   19249  1.1.6.2  bouyer 	cmpi.b		%d0,&0x98		# fpcr & fpsr ?
   19250  1.1.6.2  bouyer 	beq.w		fctrl_in_6		# yes
   19251  1.1.6.2  bouyer 	cmpi.b		%d0,&0x94		# fpcr & fpiar ?
   19252  1.1.6.2  bouyer 	beq.b		fctrl_in_5		# yes
   19253  1.1.6.2  bouyer 
   19254  1.1.6.2  bouyer # fmovem.l #<data>, fpsr/fpiar
   19255  1.1.6.2  bouyer fctrl_in_3:
   19256  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19257  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19258  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPSR from mem
   19259  1.1.6.2  bouyer 
   19260  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19261  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19262  1.1.6.2  bouyer 
   19263  1.1.6.2  bouyer 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to stack
   19264  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19265  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19266  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPIAR from mem
   19267  1.1.6.2  bouyer 
   19268  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19269  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19270  1.1.6.2  bouyer 
   19271  1.1.6.2  bouyer 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to stack
   19272  1.1.6.2  bouyer 	rts
   19273  1.1.6.2  bouyer 
   19274  1.1.6.2  bouyer # fmovem.l #<data>, fpcr/fpiar
   19275  1.1.6.2  bouyer fctrl_in_5:
   19276  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19277  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19278  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPCR from mem
   19279  1.1.6.2  bouyer 
   19280  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19281  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19282  1.1.6.2  bouyer 
   19283  1.1.6.2  bouyer 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to stack
   19284  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19285  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19286  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPIAR from mem
   19287  1.1.6.2  bouyer 
   19288  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19289  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19290  1.1.6.2  bouyer 
   19291  1.1.6.2  bouyer 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to stack
   19292  1.1.6.2  bouyer 	rts
   19293  1.1.6.2  bouyer 
   19294  1.1.6.2  bouyer # fmovem.l #<data>, fpcr/fpsr
   19295  1.1.6.2  bouyer fctrl_in_6:
   19296  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19297  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19298  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPCR from mem
   19299  1.1.6.2  bouyer 
   19300  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19301  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19302  1.1.6.2  bouyer 
   19303  1.1.6.2  bouyer 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to mem
   19304  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19305  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19306  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPSR from mem
   19307  1.1.6.2  bouyer 
   19308  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19309  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19310  1.1.6.2  bouyer 
   19311  1.1.6.2  bouyer 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to mem
   19312  1.1.6.2  bouyer 	rts
   19313  1.1.6.2  bouyer 
   19314  1.1.6.2  bouyer # fmovem.l #<data>, fpcr/fpsr/fpiar
   19315  1.1.6.2  bouyer fctrl_in_7:
   19316  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19317  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19318  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPCR from mem
   19319  1.1.6.2  bouyer 
   19320  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19321  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19322  1.1.6.2  bouyer 
   19323  1.1.6.2  bouyer 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to mem
   19324  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19325  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19326  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPSR from mem
   19327  1.1.6.2  bouyer 
   19328  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19329  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19330  1.1.6.2  bouyer 
   19331  1.1.6.2  bouyer 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to mem
   19332  1.1.6.2  bouyer 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
   19333  1.1.6.2  bouyer 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
   19334  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch FPIAR from mem
   19335  1.1.6.2  bouyer 
   19336  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19337  1.1.6.2  bouyer 	bne.l		iea_iacc		# yes
   19338  1.1.6.2  bouyer 
   19339  1.1.6.2  bouyer 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to mem
   19340  1.1.6.2  bouyer 	rts
   19341  1.1.6.2  bouyer 
   19342  1.1.6.2  bouyer #########################################################################
   19343  1.1.6.2  bouyer # XDEF ****************************************************************	#
   19344  1.1.6.2  bouyer #	_dcalc_ea(): calc correct <ea> from <ea> stacked on exception	#
   19345  1.1.6.2  bouyer #									#
   19346  1.1.6.2  bouyer # XREF ****************************************************************	#
   19347  1.1.6.2  bouyer #	inc_areg() - increment an address register			#
   19348  1.1.6.2  bouyer #	dec_areg() - decrement an address register			#
   19349  1.1.6.2  bouyer #									#
   19350  1.1.6.2  bouyer # INPUT ***************************************************************	#
   19351  1.1.6.2  bouyer #	d0 = number of bytes to adjust <ea> by				#
   19352  1.1.6.2  bouyer # 									#
   19353  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   19354  1.1.6.2  bouyer #	None								#
   19355  1.1.6.2  bouyer #									#
   19356  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   19357  1.1.6.2  bouyer # "Dummy" CALCulate Effective Address:					#
   19358  1.1.6.2  bouyer # 	The stacked <ea> for FP unimplemented instructions and opclass	#
   19359  1.1.6.2  bouyer #	two packed instructions is correct with the exception of...	#
   19360  1.1.6.2  bouyer #									#
   19361  1.1.6.2  bouyer #	1) -(An)   : The register is not updated regardless of size.	#
   19362  1.1.6.2  bouyer #		     Also, for extended precision and packed, the 	#
   19363  1.1.6.2  bouyer #		     stacked <ea> value is 8 bytes too big		#
   19364  1.1.6.2  bouyer #	2) (An)+   : The register is not updated.			#
   19365  1.1.6.2  bouyer #	3) #<data> : The upper longword of the immediate operand is 	#
   19366  1.1.6.2  bouyer #		     stacked b,w,l and s sizes are completely stacked. 	#
   19367  1.1.6.2  bouyer #		     d,x, and p are not.				#
   19368  1.1.6.2  bouyer #									#
   19369  1.1.6.2  bouyer #########################################################################
   19370  1.1.6.2  bouyer 
   19371  1.1.6.2  bouyer 	global		_dcalc_ea
   19372  1.1.6.2  bouyer _dcalc_ea:
   19373  1.1.6.2  bouyer 	mov.l		%d0, %a0		# move # bytes to %a0
   19374  1.1.6.2  bouyer 
   19375  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6), %d0	# fetch opcode word
   19376  1.1.6.2  bouyer 	mov.l		%d0, %d1		# make a copy
   19377  1.1.6.2  bouyer 
   19378  1.1.6.2  bouyer 	andi.w		&0x38, %d0		# extract mode field
   19379  1.1.6.2  bouyer 	andi.l		&0x7, %d1		# extract reg  field
   19380  1.1.6.2  bouyer 
   19381  1.1.6.2  bouyer 	cmpi.b		%d0,&0x18		# is mode (An)+ ?
   19382  1.1.6.2  bouyer 	beq.b		dcea_pi			# yes
   19383  1.1.6.2  bouyer 
   19384  1.1.6.2  bouyer 	cmpi.b		%d0,&0x20		# is mode -(An) ?
   19385  1.1.6.2  bouyer 	beq.b		dcea_pd			# yes
   19386  1.1.6.2  bouyer 
   19387  1.1.6.2  bouyer 	or.w		%d1,%d0			# concat mode,reg
   19388  1.1.6.2  bouyer 	cmpi.b		%d0,&0x3c		# is mode #<data>?
   19389  1.1.6.2  bouyer 
   19390  1.1.6.2  bouyer 	beq.b		dcea_imm		# yes
   19391  1.1.6.2  bouyer 
   19392  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# return <ea>
   19393  1.1.6.2  bouyer 	rts
   19394  1.1.6.2  bouyer 
   19395  1.1.6.2  bouyer # need to set immediate data flag here since we'll need to do
   19396  1.1.6.2  bouyer # an imem_read to fetch this later.
   19397  1.1.6.2  bouyer dcea_imm:
   19398  1.1.6.2  bouyer 	mov.b		&immed_flg,SPCOND_FLG(%a6)
   19399  1.1.6.2  bouyer 	lea		([USER_FPIAR,%a6],0x4),%a0 # no; return <ea>
   19400  1.1.6.2  bouyer 	rts
   19401  1.1.6.2  bouyer 
   19402  1.1.6.2  bouyer # here, the <ea> is stacked correctly. however, we must update the
   19403  1.1.6.2  bouyer # address register...
   19404  1.1.6.2  bouyer dcea_pi:
   19405  1.1.6.2  bouyer 	mov.l		%a0,%d0			# pass amt to inc by
   19406  1.1.6.2  bouyer 	bsr.l		inc_areg		# inc addr register
   19407  1.1.6.2  bouyer 
   19408  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   19409  1.1.6.2  bouyer 	rts
   19410  1.1.6.2  bouyer 
   19411  1.1.6.2  bouyer # the <ea> is stacked correctly for all but extended and packed which
   19412  1.1.6.2  bouyer # the <ea>s are 8 bytes too large.
   19413  1.1.6.2  bouyer # it would make no sense to have a pre-decrement to a7 in supervisor
   19414  1.1.6.2  bouyer # mode so we don't even worry about this tricky case here : )
   19415  1.1.6.2  bouyer dcea_pd:
   19416  1.1.6.2  bouyer 	mov.l		%a0,%d0			# pass amt to dec by
   19417  1.1.6.2  bouyer 	bsr.l		dec_areg		# dec addr register
   19418  1.1.6.2  bouyer 
   19419  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   19420  1.1.6.2  bouyer 
   19421  1.1.6.2  bouyer 	cmpi.b		%d0,&0xc		# is opsize ext or packed?
   19422  1.1.6.2  bouyer 	beq.b		dcea_pd2		# yes
   19423  1.1.6.2  bouyer 	rts
   19424  1.1.6.2  bouyer dcea_pd2:
   19425  1.1.6.2  bouyer 	sub.l		&0x8,%a0		# correct <ea>
   19426  1.1.6.2  bouyer 	mov.l		%a0,EXC_EA(%a6)		# put correct <ea> on stack
   19427  1.1.6.2  bouyer 	rts
   19428  1.1.6.2  bouyer 
   19429  1.1.6.2  bouyer #########################################################################
   19430  1.1.6.2  bouyer # XDEF ****************************************************************	#
   19431  1.1.6.2  bouyer # 	_calc_ea_fout(): calculate correct stacked <ea> for extended	#
   19432  1.1.6.2  bouyer #			 and packed data opclass 3 operations.		#
   19433  1.1.6.2  bouyer #									#
   19434  1.1.6.2  bouyer # XREF ****************************************************************	#
   19435  1.1.6.2  bouyer #	None								#
   19436  1.1.6.2  bouyer #									#
   19437  1.1.6.2  bouyer # INPUT ***************************************************************	#
   19438  1.1.6.2  bouyer #	None								#
   19439  1.1.6.2  bouyer # 									#
   19440  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   19441  1.1.6.2  bouyer #	a0 = return correct effective address				#
   19442  1.1.6.2  bouyer #									#
   19443  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   19444  1.1.6.2  bouyer #	For opclass 3 extended and packed data operations, the <ea>	#
   19445  1.1.6.2  bouyer # stacked for the exception is incorrect for -(an) and (an)+ addressing	#
   19446  1.1.6.2  bouyer # modes. Also, while we're at it, the index register itself must get 	#
   19447  1.1.6.2  bouyer # updated.								#
   19448  1.1.6.2  bouyer # 	So, for -(an), we must subtract 8 off of the stacked <ea> value	#
   19449  1.1.6.2  bouyer # and return that value as the correct <ea> and store that value in An.	#
   19450  1.1.6.2  bouyer # For (an)+, the stacked <ea> is correct but we must adjust An by +12.	#
   19451  1.1.6.2  bouyer #									#
   19452  1.1.6.2  bouyer #########################################################################
   19453  1.1.6.2  bouyer 
   19454  1.1.6.2  bouyer # This calc_ea is currently used to retrieve the correct <ea>
   19455  1.1.6.2  bouyer # for fmove outs of type extended and packed.
   19456  1.1.6.2  bouyer 	global		_calc_ea_fout
   19457  1.1.6.2  bouyer _calc_ea_fout:
   19458  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d0	# fetch opcode word
   19459  1.1.6.2  bouyer 	mov.l		%d0,%d1			# make a copy
   19460  1.1.6.2  bouyer 
   19461  1.1.6.2  bouyer 	andi.w		&0x38,%d0		# extract mode field
   19462  1.1.6.2  bouyer 	andi.l		&0x7,%d1		# extract reg  field
   19463  1.1.6.2  bouyer 
   19464  1.1.6.2  bouyer 	cmpi.b		%d0,&0x18		# is mode (An)+ ?
   19465  1.1.6.2  bouyer 	beq.b		ceaf_pi			# yes
   19466  1.1.6.2  bouyer 
   19467  1.1.6.2  bouyer 	cmpi.b		%d0,&0x20		# is mode -(An) ?
   19468  1.1.6.2  bouyer 	beq.w		ceaf_pd			# yes
   19469  1.1.6.2  bouyer 
   19470  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   19471  1.1.6.2  bouyer 	rts
   19472  1.1.6.2  bouyer 
   19473  1.1.6.2  bouyer # (An)+ : extended and packed fmove out
   19474  1.1.6.2  bouyer #	: stacked <ea> is correct
   19475  1.1.6.2  bouyer #	: "An" not updated
   19476  1.1.6.2  bouyer ceaf_pi:
   19477  1.1.6.2  bouyer 	mov.w		(tbl_ceaf_pi.b,%pc,%d1.w*2),%d1
   19478  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0
   19479  1.1.6.2  bouyer 	jmp		(tbl_ceaf_pi.b,%pc,%d1.w*1)
   19480  1.1.6.2  bouyer 
   19481  1.1.6.2  bouyer 	swbeg		&0x8
   19482  1.1.6.2  bouyer tbl_ceaf_pi:
   19483  1.1.6.2  bouyer 	short		ceaf_pi0 - tbl_ceaf_pi
   19484  1.1.6.2  bouyer 	short		ceaf_pi1 - tbl_ceaf_pi
   19485  1.1.6.2  bouyer 	short		ceaf_pi2 - tbl_ceaf_pi
   19486  1.1.6.2  bouyer 	short		ceaf_pi3 - tbl_ceaf_pi
   19487  1.1.6.2  bouyer 	short		ceaf_pi4 - tbl_ceaf_pi
   19488  1.1.6.2  bouyer 	short		ceaf_pi5 - tbl_ceaf_pi
   19489  1.1.6.2  bouyer 	short		ceaf_pi6 - tbl_ceaf_pi
   19490  1.1.6.2  bouyer 	short		ceaf_pi7 - tbl_ceaf_pi
   19491  1.1.6.2  bouyer 
   19492  1.1.6.2  bouyer ceaf_pi0:
   19493  1.1.6.2  bouyer 	addi.l		&0xc,EXC_DREGS+0x8(%a6)
   19494  1.1.6.2  bouyer 	rts
   19495  1.1.6.2  bouyer ceaf_pi1:
   19496  1.1.6.2  bouyer 	addi.l		&0xc,EXC_DREGS+0xc(%a6)
   19497  1.1.6.2  bouyer 	rts
   19498  1.1.6.2  bouyer ceaf_pi2:
   19499  1.1.6.2  bouyer 	add.l		&0xc,%a2
   19500  1.1.6.2  bouyer 	rts
   19501  1.1.6.2  bouyer ceaf_pi3:
   19502  1.1.6.2  bouyer 	add.l		&0xc,%a3
   19503  1.1.6.2  bouyer 	rts
   19504  1.1.6.2  bouyer ceaf_pi4:
   19505  1.1.6.2  bouyer 	add.l		&0xc,%a4
   19506  1.1.6.2  bouyer 	rts
   19507  1.1.6.2  bouyer ceaf_pi5:
   19508  1.1.6.2  bouyer 	add.l		&0xc,%a5
   19509  1.1.6.2  bouyer 	rts
   19510  1.1.6.2  bouyer ceaf_pi6:
   19511  1.1.6.2  bouyer 	addi.l		&0xc,EXC_A6(%a6)
   19512  1.1.6.2  bouyer 	rts
   19513  1.1.6.2  bouyer ceaf_pi7:
   19514  1.1.6.2  bouyer 	mov.b		&mia7_flg,SPCOND_FLG(%a6)
   19515  1.1.6.2  bouyer 	addi.l		&0xc,EXC_A7(%a6)
   19516  1.1.6.2  bouyer 	rts
   19517  1.1.6.2  bouyer 
   19518  1.1.6.2  bouyer # -(An) : extended and packed fmove out
   19519  1.1.6.2  bouyer #	: stacked <ea> = actual <ea> + 8
   19520  1.1.6.2  bouyer #	: "An" not updated
   19521  1.1.6.2  bouyer ceaf_pd:
   19522  1.1.6.2  bouyer 	mov.w		(tbl_ceaf_pd.b,%pc,%d1.w*2),%d1
   19523  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0
   19524  1.1.6.2  bouyer 	sub.l		&0x8,%a0
   19525  1.1.6.2  bouyer 	sub.l		&0x8,EXC_EA(%a6)
   19526  1.1.6.2  bouyer 	jmp		(tbl_ceaf_pd.b,%pc,%d1.w*1)
   19527  1.1.6.2  bouyer 
   19528  1.1.6.2  bouyer 	swbeg		&0x8
   19529  1.1.6.2  bouyer tbl_ceaf_pd:
   19530  1.1.6.2  bouyer 	short		ceaf_pd0 - tbl_ceaf_pd
   19531  1.1.6.2  bouyer 	short		ceaf_pd1 - tbl_ceaf_pd
   19532  1.1.6.2  bouyer 	short		ceaf_pd2 - tbl_ceaf_pd
   19533  1.1.6.2  bouyer 	short		ceaf_pd3 - tbl_ceaf_pd
   19534  1.1.6.2  bouyer 	short		ceaf_pd4 - tbl_ceaf_pd
   19535  1.1.6.2  bouyer 	short		ceaf_pd5 - tbl_ceaf_pd
   19536  1.1.6.2  bouyer 	short		ceaf_pd6 - tbl_ceaf_pd
   19537  1.1.6.2  bouyer 	short		ceaf_pd7 - tbl_ceaf_pd
   19538  1.1.6.2  bouyer 
   19539  1.1.6.2  bouyer ceaf_pd0:
   19540  1.1.6.2  bouyer 	mov.l		%a0,EXC_DREGS+0x8(%a6)
   19541  1.1.6.2  bouyer 	rts
   19542  1.1.6.2  bouyer ceaf_pd1:
   19543  1.1.6.2  bouyer 	mov.l		%a0,EXC_DREGS+0xc(%a6)
   19544  1.1.6.2  bouyer 	rts
   19545  1.1.6.2  bouyer ceaf_pd2:
   19546  1.1.6.2  bouyer 	mov.l		%a0,%a2
   19547  1.1.6.2  bouyer 	rts
   19548  1.1.6.2  bouyer ceaf_pd3:
   19549  1.1.6.2  bouyer 	mov.l		%a0,%a3
   19550  1.1.6.2  bouyer 	rts
   19551  1.1.6.2  bouyer ceaf_pd4:
   19552  1.1.6.2  bouyer 	mov.l		%a0,%a4
   19553  1.1.6.2  bouyer 	rts
   19554  1.1.6.2  bouyer ceaf_pd5:
   19555  1.1.6.2  bouyer 	mov.l		%a0,%a5
   19556  1.1.6.2  bouyer 	rts
   19557  1.1.6.2  bouyer ceaf_pd6:
   19558  1.1.6.2  bouyer 	mov.l		%a0,EXC_A6(%a6)
   19559  1.1.6.2  bouyer 	rts
   19560  1.1.6.2  bouyer ceaf_pd7:
   19561  1.1.6.2  bouyer 	mov.l		%a0,EXC_A7(%a6)
   19562  1.1.6.2  bouyer 	mov.b		&mda7_flg,SPCOND_FLG(%a6)
   19563  1.1.6.2  bouyer 	rts
   19564  1.1.6.2  bouyer 
   19565  1.1.6.2  bouyer #########################################################################
   19566  1.1.6.2  bouyer # XDEF ****************************************************************	#
   19567  1.1.6.2  bouyer #	_load_fop(): load operand for unimplemented FP exception	#
   19568  1.1.6.2  bouyer #									#
   19569  1.1.6.2  bouyer # XREF ****************************************************************	#
   19570  1.1.6.2  bouyer #	set_tag_x() - determine ext prec optype tag			#
   19571  1.1.6.2  bouyer #	set_tag_s() - determine sgl prec optype tag			#
   19572  1.1.6.2  bouyer #	set_tag_d() - determine dbl prec optype tag			#
   19573  1.1.6.2  bouyer #	unnorm_fix() - convert normalized number to denorm or zero	#
   19574  1.1.6.2  bouyer #	norm() - normalize a denormalized number			#
   19575  1.1.6.2  bouyer #	get_packed() - fetch a packed operand from memory		#
   19576  1.1.6.2  bouyer #	_dcalc_ea() - calculate <ea>, fixing An in process		#
   19577  1.1.6.2  bouyer #									#
   19578  1.1.6.2  bouyer #	_imem_read_{word,long}() - read from instruction memory		#
   19579  1.1.6.2  bouyer #	_dmem_read() - read from data memory				#
   19580  1.1.6.2  bouyer #	_dmem_read_{byte,word,long}() - read from data memory		#
   19581  1.1.6.2  bouyer #									#
   19582  1.1.6.2  bouyer #	facc_in_{b,w,l,d,x}() - mem read failed; special exit point	#
   19583  1.1.6.2  bouyer #									#
   19584  1.1.6.2  bouyer # INPUT ***************************************************************	#
   19585  1.1.6.2  bouyer #	None								#
   19586  1.1.6.2  bouyer # 									#
   19587  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   19588  1.1.6.2  bouyer #	If memory access doesn't fail:					#
   19589  1.1.6.2  bouyer #		FP_SRC(a6) = source operand in extended precision	#
   19590  1.1.6.2  bouyer # 		FP_DST(a6) = destination operand in extended precision	#
   19591  1.1.6.2  bouyer #									#
   19592  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   19593  1.1.6.2  bouyer # 	This is called from the Unimplemented FP exception handler in	#
   19594  1.1.6.2  bouyer # order to load the source and maybe destination operand into		#
   19595  1.1.6.2  bouyer # FP_SRC(a6) and FP_DST(a6). If the instruction was opclass zero, load	#
   19596  1.1.6.2  bouyer # the source and destination from the FP register file. Set the optype	#
   19597  1.1.6.2  bouyer # tags for both if dyadic, one for monadic. If a number is an UNNORM,	#
   19598  1.1.6.2  bouyer # convert it to a DENORM or a ZERO.					#
   19599  1.1.6.2  bouyer # 	If the instruction is opclass two (memory->reg), then fetch	#
   19600  1.1.6.2  bouyer # the destination from the register file and the source operand from 	#
   19601  1.1.6.2  bouyer # memory. Tag and fix both as above w/ opclass zero instructions.	#
   19602  1.1.6.2  bouyer # 	If the source operand is byte,word,long, or single, it may be	#
   19603  1.1.6.2  bouyer # in the data register file. If it's actually out in memory, use one of	#
   19604  1.1.6.2  bouyer # the mem_read() routines to fetch it. If the mem_read() access returns	#
   19605  1.1.6.2  bouyer # a failing value, exit through the special facc_in() routine which	#
   19606  1.1.6.2  bouyer # will create an acess error exception frame from the current exception #
   19607  1.1.6.2  bouyer # frame.								#
   19608  1.1.6.2  bouyer # 	Immediate data and regular data accesses are separated because 	#
   19609  1.1.6.2  bouyer # if an immediate data access fails, the resulting fault status		#
   19610  1.1.6.2  bouyer # longword stacked for the access error exception must have the 	#
   19611  1.1.6.2  bouyer # instruction bit set.							#
   19612  1.1.6.2  bouyer #									#
   19613  1.1.6.2  bouyer #########################################################################
   19614  1.1.6.2  bouyer 
   19615  1.1.6.2  bouyer 	global		_load_fop
   19616  1.1.6.2  bouyer _load_fop:
   19617  1.1.6.2  bouyer 
   19618  1.1.6.2  bouyer #  15     13 12 10  9 7  6       0
   19619  1.1.6.2  bouyer # /        \ /   \ /  \ /         \
   19620  1.1.6.2  bouyer # ---------------------------------
   19621  1.1.6.2  bouyer # | opclass | RX  | RY | EXTENSION |  (2nd word of general FP instruction)
   19622  1.1.6.2  bouyer # ---------------------------------
   19623  1.1.6.2  bouyer #
   19624  1.1.6.2  bouyer 
   19625  1.1.6.2  bouyer #	bfextu		EXC_CMDREG(%a6){&0:&3}, %d0 # extract opclass
   19626  1.1.6.2  bouyer #	cmpi.b		%d0, &0x2		# which class is it? ('000,'010,'011)
   19627  1.1.6.2  bouyer #	beq.w		op010			# handle <ea> -> fpn
   19628  1.1.6.2  bouyer #	bgt.w		op011			# handle fpn -> <ea>
   19629  1.1.6.2  bouyer 
   19630  1.1.6.2  bouyer # we're not using op011 for now...
   19631  1.1.6.2  bouyer 	btst		&0x6,EXC_CMDREG(%a6)
   19632  1.1.6.2  bouyer 	bne.b		op010
   19633  1.1.6.2  bouyer 
   19634  1.1.6.2  bouyer ############################
   19635  1.1.6.2  bouyer # OPCLASS '000: reg -> reg #
   19636  1.1.6.2  bouyer ############################
   19637  1.1.6.2  bouyer op000:
   19638  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension word lo
   19639  1.1.6.2  bouyer 	btst		&0x5,%d0		# testing extension bits
   19640  1.1.6.2  bouyer 	beq.b		op000_src		# (bit 5 == 0) => monadic
   19641  1.1.6.2  bouyer 	btst		&0x4,%d0		# (bit 5 == 1)
   19642  1.1.6.2  bouyer 	beq.b		op000_dst		# (bit 4 == 0) => dyadic
   19643  1.1.6.2  bouyer 	and.w		&0x007f,%d0		# extract extension bits {6:0}
   19644  1.1.6.2  bouyer 	cmpi.w		%d0,&0x0038		# is it an fcmp (dyadic) ?
   19645  1.1.6.2  bouyer 	bne.b		op000_src		# it's an fcmp
   19646  1.1.6.2  bouyer 
   19647  1.1.6.2  bouyer op000_dst:
   19648  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field
   19649  1.1.6.2  bouyer 	bsr.l		load_fpn2		# fetch dst fpreg into FP_DST
   19650  1.1.6.2  bouyer 
   19651  1.1.6.2  bouyer 	bsr.l		set_tag_x		# get dst optype tag
   19652  1.1.6.2  bouyer 
   19653  1.1.6.2  bouyer 	cmpi.b		%d0, &UNNORM		# is dst fpreg an UNNORM?
   19654  1.1.6.2  bouyer 	beq.b		op000_dst_unnorm	# yes
   19655  1.1.6.2  bouyer op000_dst_cont:
   19656  1.1.6.2  bouyer 	mov.b 		%d0, DTAG(%a6)		# store the dst optype tag
   19657  1.1.6.2  bouyer 
   19658  1.1.6.2  bouyer op000_src:
   19659  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&3:&3}, %d0 # extract src field
   19660  1.1.6.2  bouyer 	bsr.l		load_fpn1		# fetch src fpreg into FP_SRC
   19661  1.1.6.2  bouyer 
   19662  1.1.6.2  bouyer 	bsr.l		set_tag_x		# get src optype tag
   19663  1.1.6.2  bouyer 
   19664  1.1.6.2  bouyer 	cmpi.b		%d0, &UNNORM		# is src fpreg an UNNORM?
   19665  1.1.6.2  bouyer 	beq.b		op000_src_unnorm	# yes
   19666  1.1.6.2  bouyer op000_src_cont:
   19667  1.1.6.2  bouyer 	mov.b		%d0, STAG(%a6)		# store the src optype tag
   19668  1.1.6.2  bouyer 	rts
   19669  1.1.6.2  bouyer 
   19670  1.1.6.2  bouyer op000_dst_unnorm:
   19671  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# fix the dst UNNORM
   19672  1.1.6.2  bouyer 	bra.b		op000_dst_cont
   19673  1.1.6.2  bouyer op000_src_unnorm:
   19674  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# fix the src UNNORM
   19675  1.1.6.2  bouyer 	bra.b		op000_src_cont
   19676  1.1.6.2  bouyer 
   19677  1.1.6.2  bouyer #############################
   19678  1.1.6.2  bouyer # OPCLASS '010: <ea> -> reg #
   19679  1.1.6.2  bouyer #############################
   19680  1.1.6.2  bouyer op010:
   19681  1.1.6.2  bouyer 	mov.w		EXC_CMDREG(%a6),%d0	# fetch extension word
   19682  1.1.6.2  bouyer 	btst		&0x5,%d0		# testing extension bits
   19683  1.1.6.2  bouyer 	beq.b		op010_src		# (bit 5 == 0) => monadic
   19684  1.1.6.2  bouyer 	btst		&0x4,%d0		# (bit 5 == 1)
   19685  1.1.6.2  bouyer 	beq.b		op010_dst		# (bit 4 == 0) => dyadic
   19686  1.1.6.2  bouyer 	and.w		&0x007f,%d0		# extract extension bits {6:0}
   19687  1.1.6.2  bouyer 	cmpi.w		%d0,&0x0038		# is it an fcmp (dyadic) ?
   19688  1.1.6.2  bouyer 	bne.b		op010_src		# it's an fcmp
   19689  1.1.6.2  bouyer 
   19690  1.1.6.2  bouyer op010_dst:
   19691  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field
   19692  1.1.6.2  bouyer 	bsr.l		load_fpn2		# fetch dst fpreg ptr
   19693  1.1.6.2  bouyer 
   19694  1.1.6.2  bouyer 	bsr.l		set_tag_x		# get dst type tag
   19695  1.1.6.2  bouyer 
   19696  1.1.6.2  bouyer 	cmpi.b		%d0, &UNNORM		# is dst fpreg an UNNORM?
   19697  1.1.6.2  bouyer 	beq.b		op010_dst_unnorm	# yes
   19698  1.1.6.2  bouyer op010_dst_cont:
   19699  1.1.6.2  bouyer 	mov.b		%d0, DTAG(%a6)		# store the dst optype tag
   19700  1.1.6.2  bouyer 
   19701  1.1.6.2  bouyer op010_src:
   19702  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&3:&3}, %d0 # extract src type field
   19703  1.1.6.2  bouyer 
   19704  1.1.6.2  bouyer 	bfextu		EXC_OPWORD(%a6){&10:&3}, %d1 # extract <ea> mode field
   19705  1.1.6.2  bouyer 	bne.w		fetch_from_mem		# src op is in memory
   19706  1.1.6.2  bouyer 
   19707  1.1.6.2  bouyer op010_dreg:
   19708  1.1.6.2  bouyer 	clr.b		STAG(%a6)		# either NORM or ZERO
   19709  1.1.6.2  bouyer 	bfextu		EXC_OPWORD(%a6){&13:&3}, %d1 # extract src reg field
   19710  1.1.6.2  bouyer 
   19711  1.1.6.2  bouyer 	mov.w		(tbl_op010_dreg.b,%pc,%d0.w*2), %d0 # jmp based on optype
   19712  1.1.6.2  bouyer 	jmp		(tbl_op010_dreg.b,%pc,%d0.w*1) # fetch src from dreg
   19713  1.1.6.2  bouyer 
   19714  1.1.6.2  bouyer op010_dst_unnorm:
   19715  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# fix the dst UNNORM
   19716  1.1.6.2  bouyer 	bra.b		op010_dst_cont
   19717  1.1.6.2  bouyer 
   19718  1.1.6.2  bouyer 	swbeg		&0x8
   19719  1.1.6.2  bouyer tbl_op010_dreg:
   19720  1.1.6.2  bouyer 	short		opd_long	- tbl_op010_dreg
   19721  1.1.6.2  bouyer 	short		opd_sgl 	- tbl_op010_dreg
   19722  1.1.6.2  bouyer 	short		tbl_op010_dreg	- tbl_op010_dreg
   19723  1.1.6.2  bouyer 	short		tbl_op010_dreg	- tbl_op010_dreg
   19724  1.1.6.2  bouyer 	short		opd_word	- tbl_op010_dreg
   19725  1.1.6.2  bouyer 	short		tbl_op010_dreg	- tbl_op010_dreg
   19726  1.1.6.2  bouyer 	short		opd_byte	- tbl_op010_dreg
   19727  1.1.6.2  bouyer 	short		tbl_op010_dreg	- tbl_op010_dreg
   19728  1.1.6.2  bouyer 
   19729  1.1.6.2  bouyer #
   19730  1.1.6.2  bouyer # LONG: can be either NORM or ZERO...
   19731  1.1.6.2  bouyer #
   19732  1.1.6.2  bouyer opd_long:
   19733  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch long in d0
   19734  1.1.6.2  bouyer 	fmov.l		%d0, %fp0 		# load a long
   19735  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19736  1.1.6.2  bouyer 	fbeq.w		opd_long_zero		# long is a ZERO
   19737  1.1.6.2  bouyer 	rts
   19738  1.1.6.2  bouyer opd_long_zero:
   19739  1.1.6.2  bouyer 	mov.b		&ZERO, STAG(%a6)	# set ZERO optype flag
   19740  1.1.6.2  bouyer 	rts
   19741  1.1.6.2  bouyer 
   19742  1.1.6.2  bouyer #
   19743  1.1.6.2  bouyer # WORD: can be either NORM or ZERO...
   19744  1.1.6.2  bouyer #
   19745  1.1.6.2  bouyer opd_word:
   19746  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch word in d0
   19747  1.1.6.2  bouyer 	fmov.w		%d0, %fp0 		# load a word
   19748  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19749  1.1.6.2  bouyer 	fbeq.w		opd_word_zero		# WORD is a ZERO
   19750  1.1.6.2  bouyer 	rts
   19751  1.1.6.2  bouyer opd_word_zero:
   19752  1.1.6.2  bouyer 	mov.b		&ZERO, STAG(%a6)	# set ZERO optype flag
   19753  1.1.6.2  bouyer 	rts
   19754  1.1.6.2  bouyer 
   19755  1.1.6.2  bouyer #
   19756  1.1.6.2  bouyer # BYTE: can be either NORM or ZERO...
   19757  1.1.6.2  bouyer #
   19758  1.1.6.2  bouyer opd_byte:
   19759  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch word in d0
   19760  1.1.6.2  bouyer 	fmov.b		%d0, %fp0 		# load a byte
   19761  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19762  1.1.6.2  bouyer 	fbeq.w		opd_byte_zero		# byte is a ZERO
   19763  1.1.6.2  bouyer 	rts
   19764  1.1.6.2  bouyer opd_byte_zero:
   19765  1.1.6.2  bouyer 	mov.b		&ZERO, STAG(%a6)	# set ZERO optype flag
   19766  1.1.6.2  bouyer 	rts
   19767  1.1.6.2  bouyer 
   19768  1.1.6.2  bouyer #
   19769  1.1.6.2  bouyer # SGL: can be either NORM, DENORM, ZERO, INF, QNAN or SNAN but not UNNORM
   19770  1.1.6.2  bouyer #
   19771  1.1.6.2  bouyer # separate SNANs and DENORMs so they can be loaded w/ special care.
   19772  1.1.6.2  bouyer # all others can simply be moved "in" using fmove.
   19773  1.1.6.2  bouyer #
   19774  1.1.6.2  bouyer opd_sgl:
   19775  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch sgl in d0
   19776  1.1.6.2  bouyer 	mov.l		%d0,L_SCR1(%a6)
   19777  1.1.6.2  bouyer 
   19778  1.1.6.2  bouyer 	lea		L_SCR1(%a6), %a0 	# pass: ptr to the sgl
   19779  1.1.6.2  bouyer 	bsr.l		set_tag_s		# determine sgl type
   19780  1.1.6.2  bouyer 	mov.b		%d0, STAG(%a6)		# save the src tag
   19781  1.1.6.2  bouyer 
   19782  1.1.6.2  bouyer 	cmpi.b		%d0, &SNAN		# is it an SNAN?
   19783  1.1.6.2  bouyer 	beq.w		get_sgl_snan		# yes
   19784  1.1.6.2  bouyer 
   19785  1.1.6.2  bouyer 	cmpi.b		%d0, &DENORM		# is it a DENORM?
   19786  1.1.6.2  bouyer 	beq.w		get_sgl_denorm		# yes
   19787  1.1.6.2  bouyer 
   19788  1.1.6.2  bouyer 	fmov.s		(%a0), %fp0		# no, so can load it regular
   19789  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19790  1.1.6.2  bouyer 	rts
   19791  1.1.6.2  bouyer 
   19792  1.1.6.2  bouyer ##############################################################################
   19793  1.1.6.2  bouyer 
   19794  1.1.6.2  bouyer #########################################################################
   19795  1.1.6.2  bouyer # fetch_from_mem():							#
   19796  1.1.6.2  bouyer # - src is out in memory. must:						#
   19797  1.1.6.2  bouyer #	(1) calc ea - must read AFTER you know the src type since	#
   19798  1.1.6.2  bouyer #		      if the ea is -() or ()+, need to know # of bytes.	#
   19799  1.1.6.2  bouyer #	(2) read it in from either user or supervisor space		#
   19800  1.1.6.2  bouyer #	(3) if (b || w || l) then simply read in			#
   19801  1.1.6.2  bouyer #	    if (s || d || x) then check for SNAN,UNNORM,DENORM		#
   19802  1.1.6.2  bouyer #	    if (packed) then punt for now				#
   19803  1.1.6.2  bouyer # INPUT:								#
   19804  1.1.6.2  bouyer #	%d0 : src type field						#
   19805  1.1.6.2  bouyer #########################################################################
   19806  1.1.6.2  bouyer fetch_from_mem:
   19807  1.1.6.2  bouyer 	clr.b		STAG(%a6)		# either NORM or ZERO
   19808  1.1.6.2  bouyer 
   19809  1.1.6.2  bouyer 	mov.w		(tbl_fp_type.b,%pc,%d0.w*2), %d0 # index by src type field
   19810  1.1.6.2  bouyer 	jmp		(tbl_fp_type.b,%pc,%d0.w*1)
   19811  1.1.6.2  bouyer 
   19812  1.1.6.2  bouyer 	swbeg		&0x8
   19813  1.1.6.2  bouyer tbl_fp_type:
   19814  1.1.6.2  bouyer 	short		load_long	- tbl_fp_type
   19815  1.1.6.2  bouyer 	short		load_sgl	- tbl_fp_type
   19816  1.1.6.2  bouyer 	short		load_ext	- tbl_fp_type
   19817  1.1.6.2  bouyer 	short		load_packed	- tbl_fp_type
   19818  1.1.6.2  bouyer 	short		load_word	- tbl_fp_type
   19819  1.1.6.2  bouyer 	short		load_dbl	- tbl_fp_type
   19820  1.1.6.2  bouyer 	short		load_byte	- tbl_fp_type
   19821  1.1.6.2  bouyer 	short		tbl_fp_type	- tbl_fp_type
   19822  1.1.6.2  bouyer 
   19823  1.1.6.2  bouyer #########################################
   19824  1.1.6.2  bouyer # load a LONG into %fp0:		#
   19825  1.1.6.2  bouyer # 	-number can't fault		#
   19826  1.1.6.2  bouyer #	(1) calc ea			#
   19827  1.1.6.2  bouyer #	(2) read 4 bytes into L_SCR1	#
   19828  1.1.6.2  bouyer #	(3) fmov.l into %fp0		#
   19829  1.1.6.2  bouyer #########################################
   19830  1.1.6.2  bouyer load_long:
   19831  1.1.6.2  bouyer 	movq.l		&0x4, %d0		# pass: 4 (bytes)
   19832  1.1.6.2  bouyer 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19833  1.1.6.2  bouyer 
   19834  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19835  1.1.6.2  bouyer 	beq.b		load_long_immed
   19836  1.1.6.2  bouyer 
   19837  1.1.6.2  bouyer 	bsr.l		_dmem_read_long		# fetch src operand from memory
   19838  1.1.6.2  bouyer 
   19839  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   19840  1.1.6.2  bouyer 	bne.l		facc_in_l		# yes
   19841  1.1.6.2  bouyer 
   19842  1.1.6.2  bouyer load_long_cont:
   19843  1.1.6.2  bouyer 	fmov.l		%d0, %fp0		# read into %fp0;convert to xprec
   19844  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19845  1.1.6.2  bouyer 
   19846  1.1.6.2  bouyer 	fbeq.w		load_long_zero		# src op is a ZERO
   19847  1.1.6.2  bouyer 	rts
   19848  1.1.6.2  bouyer load_long_zero:
   19849  1.1.6.2  bouyer 	mov.b		&ZERO, STAG(%a6)	# set optype tag to ZERO
   19850  1.1.6.2  bouyer 	rts
   19851  1.1.6.2  bouyer 
   19852  1.1.6.2  bouyer load_long_immed:
   19853  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch src operand immed data
   19854  1.1.6.2  bouyer 
   19855  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19856  1.1.6.2  bouyer 	bne.l		funimp_iacc		# yes
   19857  1.1.6.2  bouyer 	bra.b		load_long_cont
   19858  1.1.6.2  bouyer 
   19859  1.1.6.2  bouyer #########################################
   19860  1.1.6.2  bouyer # load a WORD into %fp0:		#
   19861  1.1.6.2  bouyer # 	-number can't fault		#
   19862  1.1.6.2  bouyer #	(1) calc ea			#
   19863  1.1.6.2  bouyer #	(2) read 2 bytes into L_SCR1	#
   19864  1.1.6.2  bouyer #	(3) fmov.w into %fp0		#
   19865  1.1.6.2  bouyer #########################################
   19866  1.1.6.2  bouyer load_word:
   19867  1.1.6.2  bouyer 	movq.l		&0x2, %d0		# pass: 2 (bytes)
   19868  1.1.6.2  bouyer 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19869  1.1.6.2  bouyer 
   19870  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19871  1.1.6.2  bouyer 	beq.b		load_word_immed
   19872  1.1.6.2  bouyer 
   19873  1.1.6.2  bouyer 	bsr.l		_dmem_read_word		# fetch src operand from memory
   19874  1.1.6.2  bouyer 
   19875  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   19876  1.1.6.2  bouyer 	bne.l		facc_in_w		# yes
   19877  1.1.6.2  bouyer 
   19878  1.1.6.2  bouyer load_word_cont:
   19879  1.1.6.2  bouyer 	fmov.w		%d0, %fp0		# read into %fp0;convert to xprec
   19880  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19881  1.1.6.2  bouyer 
   19882  1.1.6.2  bouyer 	fbeq.w		load_word_zero		# src op is a ZERO
   19883  1.1.6.2  bouyer 	rts
   19884  1.1.6.2  bouyer load_word_zero:
   19885  1.1.6.2  bouyer 	mov.b		&ZERO, STAG(%a6)	# set optype tag to ZERO
   19886  1.1.6.2  bouyer 	rts
   19887  1.1.6.2  bouyer 
   19888  1.1.6.2  bouyer load_word_immed:
   19889  1.1.6.2  bouyer 	bsr.l		_imem_read_word		# fetch src operand immed data
   19890  1.1.6.2  bouyer 
   19891  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19892  1.1.6.2  bouyer 	bne.l		funimp_iacc		# yes
   19893  1.1.6.2  bouyer 	bra.b		load_word_cont
   19894  1.1.6.2  bouyer 
   19895  1.1.6.2  bouyer #########################################
   19896  1.1.6.2  bouyer # load a BYTE into %fp0:		#
   19897  1.1.6.2  bouyer # 	-number can't fault		#
   19898  1.1.6.2  bouyer #	(1) calc ea			#
   19899  1.1.6.2  bouyer #	(2) read 1 byte into L_SCR1	#
   19900  1.1.6.2  bouyer #	(3) fmov.b into %fp0		#
   19901  1.1.6.2  bouyer #########################################
   19902  1.1.6.2  bouyer load_byte:
   19903  1.1.6.2  bouyer 	movq.l		&0x1, %d0		# pass: 1 (byte)
   19904  1.1.6.2  bouyer 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19905  1.1.6.2  bouyer 
   19906  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19907  1.1.6.2  bouyer 	beq.b		load_byte_immed
   19908  1.1.6.2  bouyer 
   19909  1.1.6.2  bouyer 	bsr.l		_dmem_read_byte		# fetch src operand from memory
   19910  1.1.6.2  bouyer 
   19911  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   19912  1.1.6.2  bouyer 	bne.l		facc_in_b		# yes
   19913  1.1.6.2  bouyer 
   19914  1.1.6.2  bouyer load_byte_cont:
   19915  1.1.6.2  bouyer 	fmov.b		%d0, %fp0		# read into %fp0;convert to xprec
   19916  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19917  1.1.6.2  bouyer 
   19918  1.1.6.2  bouyer 	fbeq.w		load_byte_zero		# src op is a ZERO
   19919  1.1.6.2  bouyer 	rts
   19920  1.1.6.2  bouyer load_byte_zero:
   19921  1.1.6.2  bouyer 	mov.b		&ZERO, STAG(%a6)	# set optype tag to ZERO
   19922  1.1.6.2  bouyer 	rts
   19923  1.1.6.2  bouyer 
   19924  1.1.6.2  bouyer load_byte_immed:
   19925  1.1.6.2  bouyer 	bsr.l		_imem_read_word		# fetch src operand immed data
   19926  1.1.6.2  bouyer 
   19927  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19928  1.1.6.2  bouyer 	bne.l		funimp_iacc		# yes
   19929  1.1.6.2  bouyer 	bra.b		load_byte_cont
   19930  1.1.6.2  bouyer 
   19931  1.1.6.2  bouyer #########################################
   19932  1.1.6.2  bouyer # load a SGL into %fp0:			#
   19933  1.1.6.2  bouyer # 	-number can't fault		#
   19934  1.1.6.2  bouyer #	(1) calc ea			#
   19935  1.1.6.2  bouyer #	(2) read 4 bytes into L_SCR1	#
   19936  1.1.6.2  bouyer #	(3) fmov.s into %fp0		#
   19937  1.1.6.2  bouyer #########################################
   19938  1.1.6.2  bouyer load_sgl:
   19939  1.1.6.2  bouyer 	movq.l		&0x4, %d0		# pass: 4 (bytes)
   19940  1.1.6.2  bouyer 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   19941  1.1.6.2  bouyer 
   19942  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   19943  1.1.6.2  bouyer 	beq.b		load_sgl_immed
   19944  1.1.6.2  bouyer 
   19945  1.1.6.2  bouyer 	bsr.l		_dmem_read_long		# fetch src operand from memory
   19946  1.1.6.2  bouyer 	mov.l		%d0, L_SCR1(%a6)	# store src op on stack
   19947  1.1.6.2  bouyer 
   19948  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   19949  1.1.6.2  bouyer 	bne.l		facc_in_l		# yes
   19950  1.1.6.2  bouyer 
   19951  1.1.6.2  bouyer load_sgl_cont:
   19952  1.1.6.2  bouyer 	lea		L_SCR1(%a6), %a0	# pass: ptr to sgl src op
   19953  1.1.6.2  bouyer 	bsr.l		set_tag_s		# determine src type tag
   19954  1.1.6.2  bouyer 	mov.b		%d0, STAG(%a6)		# save src optype tag on stack
   19955  1.1.6.2  bouyer 
   19956  1.1.6.2  bouyer 	cmpi.b		%d0, &DENORM		# is it a sgl DENORM?
   19957  1.1.6.2  bouyer 	beq.w		get_sgl_denorm		# yes
   19958  1.1.6.2  bouyer 
   19959  1.1.6.2  bouyer 	cmpi.b		%d0, &SNAN		# is it a sgl SNAN?
   19960  1.1.6.2  bouyer 	beq.w		get_sgl_snan		# yes
   19961  1.1.6.2  bouyer 
   19962  1.1.6.2  bouyer 	fmov.s		L_SCR1(%a6), %fp0	# read into %fp0;convert to xprec
   19963  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   19964  1.1.6.2  bouyer 	rts
   19965  1.1.6.2  bouyer 
   19966  1.1.6.2  bouyer load_sgl_immed:
   19967  1.1.6.2  bouyer 	bsr.l		_imem_read_long		# fetch src operand immed data
   19968  1.1.6.2  bouyer 
   19969  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   19970  1.1.6.2  bouyer 	bne.l		funimp_iacc		# yes
   19971  1.1.6.2  bouyer 	bra.b		load_sgl_cont
   19972  1.1.6.2  bouyer 
   19973  1.1.6.2  bouyer # must convert sgl denorm format to an Xprec denorm fmt suitable for
   19974  1.1.6.2  bouyer # normalization...
   19975  1.1.6.2  bouyer # %a0 : points to sgl denorm
   19976  1.1.6.2  bouyer get_sgl_denorm:
   19977  1.1.6.2  bouyer 	clr.w		FP_SRC_EX(%a6)
   19978  1.1.6.2  bouyer 	bfextu		(%a0){&9:&23}, %d0	# fetch sgl hi(_mantissa)
   19979  1.1.6.2  bouyer 	lsl.l		&0x8, %d0
   19980  1.1.6.2  bouyer 	mov.l		%d0, FP_SRC_HI(%a6)	# set ext hi(_mantissa)
   19981  1.1.6.2  bouyer 	clr.l		FP_SRC_LO(%a6)		# set ext lo(_mantissa)
   19982  1.1.6.2  bouyer 
   19983  1.1.6.2  bouyer 	clr.w		FP_SRC_EX(%a6)
   19984  1.1.6.2  bouyer 	btst		&0x7, (%a0)		# is sgn bit set?
   19985  1.1.6.2  bouyer 	beq.b		sgl_dnrm_norm
   19986  1.1.6.2  bouyer 	bset		&0x7, FP_SRC_EX(%a6)	# set sgn of xprec value
   19987  1.1.6.2  bouyer 
   19988  1.1.6.2  bouyer sgl_dnrm_norm:
   19989  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   19990  1.1.6.2  bouyer 	bsr.l		norm			# normalize number
   19991  1.1.6.2  bouyer 	mov.w		&0x3f81, %d1		# xprec exp = 0x3f81
   19992  1.1.6.2  bouyer 	sub.w		%d0, %d1		# exp = 0x3f81 - shft amt.
   19993  1.1.6.2  bouyer 	or.w		%d1, FP_SRC_EX(%a6)	# {sgn,exp}
   19994  1.1.6.2  bouyer 
   19995  1.1.6.2  bouyer 	mov.b		&NORM, STAG(%a6)	# fix src type tag
   19996  1.1.6.2  bouyer 	rts
   19997  1.1.6.2  bouyer 
   19998  1.1.6.2  bouyer # convert sgl to ext SNAN
   19999  1.1.6.2  bouyer # %a0 : points to sgl SNAN
   20000  1.1.6.2  bouyer get_sgl_snan:
   20001  1.1.6.2  bouyer 	mov.w		&0x7fff, FP_SRC_EX(%a6) # set exp of SNAN
   20002  1.1.6.2  bouyer 	bfextu		(%a0){&9:&23}, %d0
   20003  1.1.6.2  bouyer 	lsl.l		&0x8, %d0		# extract and insert hi(man)
   20004  1.1.6.2  bouyer 	mov.l		%d0, FP_SRC_HI(%a6)
   20005  1.1.6.2  bouyer 	clr.l		FP_SRC_LO(%a6)
   20006  1.1.6.2  bouyer 
   20007  1.1.6.2  bouyer 	btst		&0x7, (%a0)		# see if sign of SNAN is set
   20008  1.1.6.2  bouyer 	beq.b		no_sgl_snan_sgn
   20009  1.1.6.2  bouyer 	bset		&0x7, FP_SRC_EX(%a6)
   20010  1.1.6.2  bouyer no_sgl_snan_sgn:
   20011  1.1.6.2  bouyer 	rts
   20012  1.1.6.2  bouyer 
   20013  1.1.6.2  bouyer #########################################
   20014  1.1.6.2  bouyer # load a DBL into %fp0:			#
   20015  1.1.6.2  bouyer # 	-number can't fault		#
   20016  1.1.6.2  bouyer #	(1) calc ea			#
   20017  1.1.6.2  bouyer #	(2) read 8 bytes into L_SCR(1,2)#
   20018  1.1.6.2  bouyer #	(3) fmov.d into %fp0		#
   20019  1.1.6.2  bouyer #########################################
   20020  1.1.6.2  bouyer load_dbl:
   20021  1.1.6.2  bouyer 	movq.l		&0x8, %d0		# pass: 8 (bytes)
   20022  1.1.6.2  bouyer 	bsr.l		_dcalc_ea		# calc <ea>; <ea> in %a0
   20023  1.1.6.2  bouyer 
   20024  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&immed_flg
   20025  1.1.6.2  bouyer 	beq.b		load_dbl_immed
   20026  1.1.6.2  bouyer 
   20027  1.1.6.2  bouyer 	lea		L_SCR1(%a6), %a1	# pass: ptr to input dbl tmp space
   20028  1.1.6.2  bouyer 	movq.l		&0x8, %d0		# pass: # bytes to read
   20029  1.1.6.2  bouyer 	bsr.l		_dmem_read		# fetch src operand from memory
   20030  1.1.6.2  bouyer 
   20031  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   20032  1.1.6.2  bouyer 	bne.l		facc_in_d		# yes
   20033  1.1.6.2  bouyer 
   20034  1.1.6.2  bouyer load_dbl_cont:
   20035  1.1.6.2  bouyer 	lea		L_SCR1(%a6), %a0	# pass: ptr to input dbl
   20036  1.1.6.2  bouyer 	bsr.l		set_tag_d		# determine src type tag
   20037  1.1.6.2  bouyer 	mov.b		%d0, STAG(%a6)		# set src optype tag
   20038  1.1.6.2  bouyer 
   20039  1.1.6.2  bouyer 	cmpi.b		%d0, &DENORM		# is it a dbl DENORM?
   20040  1.1.6.2  bouyer 	beq.w		get_dbl_denorm		# yes
   20041  1.1.6.2  bouyer 
   20042  1.1.6.2  bouyer 	cmpi.b		%d0, &SNAN		# is it a dbl SNAN?
   20043  1.1.6.2  bouyer 	beq.w		get_dbl_snan		# yes
   20044  1.1.6.2  bouyer 
   20045  1.1.6.2  bouyer 	fmov.d		L_SCR1(%a6), %fp0	# read into %fp0;convert to xprec
   20046  1.1.6.2  bouyer 	fmovm.x		&0x80, FP_SRC(%a6)	# return src op in FP_SRC
   20047  1.1.6.2  bouyer 	rts
   20048  1.1.6.2  bouyer 
   20049  1.1.6.2  bouyer load_dbl_immed:
   20050  1.1.6.2  bouyer 	lea		L_SCR1(%a6), %a1	# pass: ptr to input dbl tmp space
   20051  1.1.6.2  bouyer 	movq.l		&0x8, %d0		# pass: # bytes to read
   20052  1.1.6.2  bouyer 	bsr.l		_imem_read		# fetch src operand from memory
   20053  1.1.6.2  bouyer 
   20054  1.1.6.2  bouyer 	tst.l		%d1			# did ifetch fail?
   20055  1.1.6.2  bouyer 	bne.l		funimp_iacc		# yes
   20056  1.1.6.2  bouyer 	bra.b		load_dbl_cont
   20057  1.1.6.2  bouyer 
   20058  1.1.6.2  bouyer # must convert dbl denorm format to an Xprec denorm fmt suitable for
   20059  1.1.6.2  bouyer # normalization...
   20060  1.1.6.2  bouyer # %a0 : loc. of dbl denorm
   20061  1.1.6.2  bouyer get_dbl_denorm:
   20062  1.1.6.2  bouyer 	clr.w		FP_SRC_EX(%a6)
   20063  1.1.6.2  bouyer 	bfextu		(%a0){&12:&31}, %d0	# fetch hi(_mantissa)
   20064  1.1.6.2  bouyer 	mov.l		%d0, FP_SRC_HI(%a6)
   20065  1.1.6.2  bouyer 	bfextu		4(%a0){&11:&21}, %d0	# fetch lo(_mantissa)
   20066  1.1.6.2  bouyer 	mov.l		&0xb, %d1
   20067  1.1.6.2  bouyer 	lsl.l		%d1, %d0
   20068  1.1.6.2  bouyer 	mov.l		%d0, FP_SRC_LO(%a6)
   20069  1.1.6.2  bouyer 
   20070  1.1.6.2  bouyer 	btst		&0x7, (%a0)		# is sgn bit set?
   20071  1.1.6.2  bouyer 	beq.b		dbl_dnrm_norm
   20072  1.1.6.2  bouyer 	bset		&0x7, FP_SRC_EX(%a6)	# set sgn of xprec value
   20073  1.1.6.2  bouyer 
   20074  1.1.6.2  bouyer dbl_dnrm_norm:
   20075  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   20076  1.1.6.2  bouyer 	bsr.l		norm			# normalize number
   20077  1.1.6.2  bouyer 	mov.w		&0x3c01, %d1		# xprec exp = 0x3c01
   20078  1.1.6.2  bouyer 	sub.w		%d0, %d1		# exp = 0x3c01 - shft amt.
   20079  1.1.6.2  bouyer 	or.w		%d1, FP_SRC_EX(%a6)	# {sgn,exp}
   20080  1.1.6.2  bouyer 
   20081  1.1.6.2  bouyer 	mov.b		&NORM, STAG(%a6)	# fix src type tag
   20082  1.1.6.2  bouyer 	rts
   20083  1.1.6.2  bouyer 
   20084  1.1.6.2  bouyer # convert dbl to ext SNAN
   20085  1.1.6.2  bouyer # %a0 : points to dbl SNAN
   20086  1.1.6.2  bouyer get_dbl_snan:
   20087  1.1.6.2  bouyer 	mov.w		&0x7fff, FP_SRC_EX(%a6) # set exp of SNAN
   20088  1.1.6.2  bouyer 
   20089  1.1.6.2  bouyer 	bfextu		(%a0){&12:&31}, %d0	# fetch hi(_mantissa)
   20090  1.1.6.2  bouyer 	mov.l		%d0, FP_SRC_HI(%a6)
   20091  1.1.6.2  bouyer 	bfextu		4(%a0){&11:&21}, %d0	# fetch lo(_mantissa)
   20092  1.1.6.2  bouyer 	mov.l		&0xb, %d1
   20093  1.1.6.2  bouyer 	lsl.l		%d1, %d0
   20094  1.1.6.2  bouyer 	mov.l		%d0, FP_SRC_LO(%a6)
   20095  1.1.6.2  bouyer 
   20096  1.1.6.2  bouyer 	btst		&0x7, (%a0)		# see if sign of SNAN is set
   20097  1.1.6.2  bouyer 	beq.b		no_dbl_snan_sgn
   20098  1.1.6.2  bouyer 	bset		&0x7, FP_SRC_EX(%a6)
   20099  1.1.6.2  bouyer no_dbl_snan_sgn:
   20100  1.1.6.2  bouyer 	rts
   20101  1.1.6.2  bouyer 
   20102  1.1.6.2  bouyer #################################################
   20103  1.1.6.2  bouyer # load a Xprec into %fp0:			#
   20104  1.1.6.2  bouyer # 	-number can't fault			#
   20105  1.1.6.2  bouyer #	(1) calc ea				#
   20106  1.1.6.2  bouyer #	(2) read 12 bytes into L_SCR(1,2)	#
   20107  1.1.6.2  bouyer #	(3) fmov.x into %fp0			#
   20108  1.1.6.2  bouyer #################################################
   20109  1.1.6.2  bouyer load_ext:
   20110  1.1.6.2  bouyer 	mov.l		&0xc, %d0		# pass: 12 (bytes)
   20111  1.1.6.2  bouyer 	bsr.l		_dcalc_ea		# calc <ea>
   20112  1.1.6.2  bouyer 
   20113  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a1	# pass: ptr to input ext tmp space
   20114  1.1.6.2  bouyer 	mov.l		&0xc, %d0		# pass: # of bytes to read
   20115  1.1.6.2  bouyer 	bsr.l		_dmem_read		# fetch src operand from memory
   20116  1.1.6.2  bouyer 
   20117  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   20118  1.1.6.2  bouyer 	bne.l		facc_in_x		# yes
   20119  1.1.6.2  bouyer 
   20120  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0	# pass: ptr to src op
   20121  1.1.6.2  bouyer 	bsr.l		set_tag_x		# determine src type tag
   20122  1.1.6.2  bouyer 
   20123  1.1.6.2  bouyer 	cmpi.b		%d0, &UNNORM		# is the src op an UNNORM?
   20124  1.1.6.2  bouyer 	beq.b		load_ext_unnorm		# yes
   20125  1.1.6.2  bouyer 
   20126  1.1.6.2  bouyer 	mov.b		%d0, STAG(%a6)		# store the src optype tag
   20127  1.1.6.2  bouyer 	rts
   20128  1.1.6.2  bouyer 
   20129  1.1.6.2  bouyer load_ext_unnorm:
   20130  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# fix the src UNNORM
   20131  1.1.6.2  bouyer 	mov.b		%d0, STAG(%a6)		# store the src optype tag
   20132  1.1.6.2  bouyer 	rts
   20133  1.1.6.2  bouyer 
   20134  1.1.6.2  bouyer #################################################
   20135  1.1.6.2  bouyer # load a packed into %fp0:			#
   20136  1.1.6.2  bouyer # 	-number can't fault			#
   20137  1.1.6.2  bouyer #	(1) calc ea				#
   20138  1.1.6.2  bouyer #	(2) read 12 bytes into L_SCR(1,2,3)	#
   20139  1.1.6.2  bouyer #	(3) fmov.x into %fp0			#
   20140  1.1.6.2  bouyer #################################################
   20141  1.1.6.2  bouyer load_packed:
   20142  1.1.6.2  bouyer 	bsr.l		get_packed
   20143  1.1.6.2  bouyer 
   20144  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass ptr to src op
   20145  1.1.6.2  bouyer 	bsr.l		set_tag_x		# determine src type tag
   20146  1.1.6.2  bouyer 	cmpi.b		%d0,&UNNORM		# is the src op an UNNORM ZERO?
   20147  1.1.6.2  bouyer 	beq.b		load_packed_unnorm	# yes
   20148  1.1.6.2  bouyer 
   20149  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# store the src optype tag
   20150  1.1.6.2  bouyer 	rts
   20151  1.1.6.2  bouyer 
   20152  1.1.6.2  bouyer load_packed_unnorm:
   20153  1.1.6.2  bouyer 	bsr.l		unnorm_fix		# fix the UNNORM ZERO
   20154  1.1.6.2  bouyer 	mov.b		%d0,STAG(%a6)		# store the src optype tag
   20155  1.1.6.2  bouyer 	rts
   20156  1.1.6.2  bouyer 
   20157  1.1.6.2  bouyer #########################################################################
   20158  1.1.6.2  bouyer # XDEF ****************************************************************	#
   20159  1.1.6.2  bouyer # 	fout(): move from fp register to memory or data register	#
   20160  1.1.6.2  bouyer #									#
   20161  1.1.6.2  bouyer # XREF ****************************************************************	#
   20162  1.1.6.2  bouyer #	_round() - needed to create EXOP for sgl/dbl precision		#
   20163  1.1.6.2  bouyer #	norm() - needed to create EXOP for extended precision		#
   20164  1.1.6.2  bouyer #	ovf_res() - create default overflow result for sgl/dbl precision#
   20165  1.1.6.2  bouyer #	unf_res() - create default underflow result for sgl/dbl prec.	#
   20166  1.1.6.2  bouyer #	dst_dbl() - create rounded dbl precision result.		#
   20167  1.1.6.2  bouyer #	dst_sgl() - create rounded sgl precision result.		#
   20168  1.1.6.2  bouyer #	fetch_dreg() - fetch dynamic k-factor reg for packed.		#
   20169  1.1.6.2  bouyer #	bindec() - convert FP binary number to packed number.		#
   20170  1.1.6.2  bouyer #	_mem_write() - write data to memory.				#
   20171  1.1.6.2  bouyer #	_mem_write2() - write data to memory unless supv mode -(a7) exc.#
   20172  1.1.6.2  bouyer #	_dmem_write_{byte,word,long}() - write data to memory.		#
   20173  1.1.6.2  bouyer #	store_dreg_{b,w,l}() - store data to data register file.	#
   20174  1.1.6.2  bouyer #	facc_out_{b,w,l,d,x}() - data access error occurred.		#
   20175  1.1.6.2  bouyer #									#
   20176  1.1.6.2  bouyer # INPUT ***************************************************************	#
   20177  1.1.6.2  bouyer #	a0 = pointer to extended precision source operand		#
   20178  1.1.6.2  bouyer #	d0 = round prec,mode						#
   20179  1.1.6.2  bouyer # 									#
   20180  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   20181  1.1.6.2  bouyer #	fp0 : intermediate underflow or overflow result if		#
   20182  1.1.6.2  bouyer #	      OVFL/UNFL occurred for a sgl or dbl operand		#
   20183  1.1.6.2  bouyer #									#
   20184  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   20185  1.1.6.2  bouyer #	This routine is accessed by many handlers that need to do an	#
   20186  1.1.6.2  bouyer # opclass three move of an operand out to memory.			#
   20187  1.1.6.2  bouyer #	Decode an fmove out (opclass 3) instruction to determine if	#
   20188  1.1.6.2  bouyer # 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.6.2  bouyer # register or memory. The algorithm uses a standard "fmove" to create	#
   20190  1.1.6.2  bouyer # the rounded result. Also, since exceptions are disabled, this also	#
   20191  1.1.6.2  bouyer # create the correct OPERR default result if appropriate.		#
   20192  1.1.6.2  bouyer #	For sgl or dbl precision, overflow or underflow can occur. If	#
   20193  1.1.6.2  bouyer # either occurs and is enabled, the EXOP.				#
   20194  1.1.6.2  bouyer #	For extended precision, the stacked <ea> must be fixed along	#
   20195  1.1.6.2  bouyer # w/ the address index register as appropriate w/ _calc_ea_fout(). If	#
   20196  1.1.6.2  bouyer # the source is a denorm and if underflow is enabled, an EXOP must be	#
   20197  1.1.6.2  bouyer # created.								#
   20198  1.1.6.2  bouyer # 	For packed, the k-factor must be fetched from the instruction	#
   20199  1.1.6.2  bouyer # word or a data register. The <ea> must be fixed as w/ extended 	#
   20200  1.1.6.2  bouyer # precision. Then, bindec() is called to create the appropriate 	#
   20201  1.1.6.2  bouyer # packed result.							#
   20202  1.1.6.2  bouyer #	If at any time an access error is flagged by one of the move-	#
   20203  1.1.6.2  bouyer # to-memory routines, then a special exit must be made so that the	#
   20204  1.1.6.2  bouyer # access error can be handled properly.					#
   20205  1.1.6.2  bouyer #									#
   20206  1.1.6.2  bouyer #########################################################################
   20207  1.1.6.2  bouyer 
   20208  1.1.6.2  bouyer 	global		fout
   20209  1.1.6.2  bouyer fout:
   20210  1.1.6.2  bouyer 	bfextu		EXC_CMDREG(%a6){&3:&3},%d1 # extract dst fmt
   20211  1.1.6.2  bouyer 	mov.w		(tbl_fout.b,%pc,%d1.w*2),%a1 # use as index
   20212  1.1.6.2  bouyer 	jmp		(tbl_fout.b,%pc,%a1)	# jump to routine
   20213  1.1.6.2  bouyer 
   20214  1.1.6.2  bouyer 	swbeg		&0x8
   20215  1.1.6.2  bouyer tbl_fout:
   20216  1.1.6.2  bouyer 	short		fout_long	-	tbl_fout
   20217  1.1.6.2  bouyer 	short		fout_sgl	-	tbl_fout
   20218  1.1.6.2  bouyer 	short		fout_ext	-	tbl_fout
   20219  1.1.6.2  bouyer 	short		fout_pack	-	tbl_fout
   20220  1.1.6.2  bouyer 	short		fout_word	-	tbl_fout
   20221  1.1.6.2  bouyer 	short		fout_dbl	-	tbl_fout
   20222  1.1.6.2  bouyer 	short		fout_byte	-	tbl_fout
   20223  1.1.6.2  bouyer 	short		fout_pack	-	tbl_fout
   20224  1.1.6.2  bouyer 
   20225  1.1.6.2  bouyer #################################################################
   20226  1.1.6.2  bouyer # fmove.b out ###################################################
   20227  1.1.6.2  bouyer #################################################################
   20228  1.1.6.2  bouyer 
   20229  1.1.6.2  bouyer # Only "Unimplemented Data Type" exceptions enter here. The operand
   20230  1.1.6.2  bouyer # is either a DENORM or a NORM.
   20231  1.1.6.2  bouyer fout_byte:
   20232  1.1.6.2  bouyer 	tst.b		STAG(%a6)		# is operand normalized?
   20233  1.1.6.2  bouyer 	bne.b		fout_byte_denorm	# no
   20234  1.1.6.2  bouyer 
   20235  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# load value
   20236  1.1.6.2  bouyer 
   20237  1.1.6.2  bouyer fout_byte_norm:
   20238  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# insert rnd prec,mode
   20239  1.1.6.2  bouyer 
   20240  1.1.6.2  bouyer 	fmov.b		%fp0,%d0		# exec move out w/ correct rnd mode
   20241  1.1.6.2  bouyer 
   20242  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   20243  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# fetch FPSR
   20244  1.1.6.2  bouyer 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
   20245  1.1.6.2  bouyer 
   20246  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20247  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20248  1.1.6.2  bouyer 	beq.b		fout_byte_dn		# must save to integer regfile
   20249  1.1.6.2  bouyer 
   20250  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20251  1.1.6.2  bouyer 	bsr.l		_dmem_write_byte	# write byte
   20252  1.1.6.2  bouyer 
   20253  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20254  1.1.6.2  bouyer 	bne.l		facc_out_b		# yes
   20255  1.1.6.2  bouyer 
   20256  1.1.6.2  bouyer 	rts
   20257  1.1.6.2  bouyer 
   20258  1.1.6.2  bouyer fout_byte_dn:
   20259  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20260  1.1.6.2  bouyer 	andi.w		&0x7,%d1
   20261  1.1.6.2  bouyer 	bsr.l		store_dreg_b
   20262  1.1.6.2  bouyer 	rts
   20263  1.1.6.2  bouyer 
   20264  1.1.6.2  bouyer fout_byte_denorm:
   20265  1.1.6.2  bouyer 	mov.l		SRC_EX(%a0),%d1
   20266  1.1.6.2  bouyer 	andi.l		&0x80000000,%d1		# keep DENORM sign
   20267  1.1.6.2  bouyer 	ori.l		&0x00800000,%d1		# make smallest sgl
   20268  1.1.6.2  bouyer 	fmov.s		%d1,%fp0
   20269  1.1.6.2  bouyer 	bra.b		fout_byte_norm
   20270  1.1.6.2  bouyer 
   20271  1.1.6.2  bouyer #################################################################
   20272  1.1.6.2  bouyer # fmove.w out ###################################################
   20273  1.1.6.2  bouyer #################################################################
   20274  1.1.6.2  bouyer 
   20275  1.1.6.2  bouyer # Only "Unimplemented Data Type" exceptions enter here. The operand
   20276  1.1.6.2  bouyer # is either a DENORM or a NORM.
   20277  1.1.6.2  bouyer fout_word:
   20278  1.1.6.2  bouyer 	tst.b		STAG(%a6)		# is operand normalized?
   20279  1.1.6.2  bouyer 	bne.b		fout_word_denorm	# no
   20280  1.1.6.2  bouyer 
   20281  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# load value
   20282  1.1.6.2  bouyer 
   20283  1.1.6.2  bouyer fout_word_norm:
   20284  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# insert rnd prec:mode
   20285  1.1.6.2  bouyer 
   20286  1.1.6.2  bouyer 	fmov.w		%fp0,%d0		# exec move out w/ correct rnd mode
   20287  1.1.6.2  bouyer 
   20288  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   20289  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# fetch FPSR
   20290  1.1.6.2  bouyer 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
   20291  1.1.6.2  bouyer 
   20292  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20293  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20294  1.1.6.2  bouyer 	beq.b		fout_word_dn		# must save to integer regfile
   20295  1.1.6.2  bouyer 
   20296  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20297  1.1.6.2  bouyer 	bsr.l		_dmem_write_word	# write word
   20298  1.1.6.2  bouyer 
   20299  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20300  1.1.6.2  bouyer 	bne.l		facc_out_w		# yes
   20301  1.1.6.2  bouyer 
   20302  1.1.6.2  bouyer 	rts
   20303  1.1.6.2  bouyer 
   20304  1.1.6.2  bouyer fout_word_dn:
   20305  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20306  1.1.6.2  bouyer 	andi.w		&0x7,%d1
   20307  1.1.6.2  bouyer 	bsr.l		store_dreg_w
   20308  1.1.6.2  bouyer 	rts
   20309  1.1.6.2  bouyer 
   20310  1.1.6.2  bouyer fout_word_denorm:
   20311  1.1.6.2  bouyer 	mov.l		SRC_EX(%a0),%d1
   20312  1.1.6.2  bouyer 	andi.l		&0x80000000,%d1		# keep DENORM sign
   20313  1.1.6.2  bouyer 	ori.l		&0x00800000,%d1		# make smallest sgl
   20314  1.1.6.2  bouyer 	fmov.s		%d1,%fp0
   20315  1.1.6.2  bouyer 	bra.b		fout_word_norm
   20316  1.1.6.2  bouyer 
   20317  1.1.6.2  bouyer #################################################################
   20318  1.1.6.2  bouyer # fmove.l out ###################################################
   20319  1.1.6.2  bouyer #################################################################
   20320  1.1.6.2  bouyer 
   20321  1.1.6.2  bouyer # Only "Unimplemented Data Type" exceptions enter here. The operand
   20322  1.1.6.2  bouyer # is either a DENORM or a NORM.
   20323  1.1.6.2  bouyer fout_long:
   20324  1.1.6.2  bouyer 	tst.b		STAG(%a6)		# is operand normalized?
   20325  1.1.6.2  bouyer 	bne.b		fout_long_denorm	# no
   20326  1.1.6.2  bouyer 
   20327  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# load value
   20328  1.1.6.2  bouyer 
   20329  1.1.6.2  bouyer fout_long_norm:
   20330  1.1.6.2  bouyer 	fmov.l		%d0,%fpcr		# insert rnd prec:mode
   20331  1.1.6.2  bouyer 
   20332  1.1.6.2  bouyer 	fmov.l		%fp0,%d0		# exec move out w/ correct rnd mode
   20333  1.1.6.2  bouyer 
   20334  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   20335  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# fetch FPSR
   20336  1.1.6.2  bouyer 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
   20337  1.1.6.2  bouyer 
   20338  1.1.6.2  bouyer fout_long_write:
   20339  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20340  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20341  1.1.6.2  bouyer 	beq.b		fout_long_dn		# must save to integer regfile
   20342  1.1.6.2  bouyer 
   20343  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20344  1.1.6.2  bouyer 	bsr.l		_dmem_write_long	# write long
   20345  1.1.6.2  bouyer 
   20346  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20347  1.1.6.2  bouyer 	bne.l		facc_out_l		# yes
   20348  1.1.6.2  bouyer 
   20349  1.1.6.2  bouyer 	rts
   20350  1.1.6.2  bouyer 
   20351  1.1.6.2  bouyer fout_long_dn:
   20352  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20353  1.1.6.2  bouyer 	andi.w		&0x7,%d1
   20354  1.1.6.2  bouyer 	bsr.l		store_dreg_l
   20355  1.1.6.2  bouyer 	rts
   20356  1.1.6.2  bouyer 
   20357  1.1.6.2  bouyer fout_long_denorm:
   20358  1.1.6.2  bouyer 	mov.l		SRC_EX(%a0),%d1
   20359  1.1.6.2  bouyer 	andi.l		&0x80000000,%d1		# keep DENORM sign
   20360  1.1.6.2  bouyer 	ori.l		&0x00800000,%d1		# make smallest sgl
   20361  1.1.6.2  bouyer 	fmov.s		%d1,%fp0
   20362  1.1.6.2  bouyer 	bra.b		fout_long_norm
   20363  1.1.6.2  bouyer 
   20364  1.1.6.2  bouyer #################################################################
   20365  1.1.6.2  bouyer # fmove.x out ###################################################
   20366  1.1.6.2  bouyer #################################################################
   20367  1.1.6.2  bouyer 
   20368  1.1.6.2  bouyer # Only "Unimplemented Data Type" exceptions enter here. The operand
   20369  1.1.6.2  bouyer # is either a DENORM or a NORM.
   20370  1.1.6.2  bouyer # The DENORM causes an Underflow exception.
   20371  1.1.6.2  bouyer fout_ext:
   20372  1.1.6.2  bouyer 
   20373  1.1.6.2  bouyer # we copy the extended precision result to FP_SCR0 so that the reserved
   20374  1.1.6.2  bouyer # 16-bit field gets zeroed. we do this since we promise not to disturb
   20375  1.1.6.2  bouyer # what's at SRC(a0).
   20376  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20377  1.1.6.2  bouyer 	clr.w		2+FP_SCR0_EX(%a6)	# clear reserved field
   20378  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20379  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20380  1.1.6.2  bouyer 
   20381  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# return result
   20382  1.1.6.2  bouyer 
   20383  1.1.6.2  bouyer 	bsr.l		_calc_ea_fout		# fix stacked <ea>
   20384  1.1.6.2  bouyer 
   20385  1.1.6.2  bouyer 	mov.l		%a0,%a1			# pass: dst addr
   20386  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: src addr
   20387  1.1.6.2  bouyer 	mov.l		&0xc,%d0		# pass: opsize is 12 bytes
   20388  1.1.6.2  bouyer 
   20389  1.1.6.2  bouyer # we must not yet write the extended precision data to the stack
   20390  1.1.6.2  bouyer # in the pre-decrement case from supervisor mode or else we'll corrupt
   20391  1.1.6.2  bouyer # the stack frame. so, leave it in FP_SRC for now and deal with it later...
   20392  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   20393  1.1.6.2  bouyer 	beq.b		fout_ext_a7
   20394  1.1.6.2  bouyer 
   20395  1.1.6.2  bouyer 	bsr.l		_dmem_write		# write ext prec number to memory
   20396  1.1.6.2  bouyer 
   20397  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20398  1.1.6.2  bouyer 	bne.w		fout_ext_err		# yes
   20399  1.1.6.2  bouyer 
   20400  1.1.6.2  bouyer 	tst.b		STAG(%a6)		# is operand normalized?
   20401  1.1.6.2  bouyer 	bne.b		fout_ext_denorm		# no
   20402  1.1.6.2  bouyer 	rts
   20403  1.1.6.2  bouyer 
   20404  1.1.6.2  bouyer # the number is a DENORM. must set the underflow exception bit
   20405  1.1.6.2  bouyer fout_ext_denorm:
   20406  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set underflow exc bit
   20407  1.1.6.2  bouyer 
   20408  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d0
   20409  1.1.6.2  bouyer 	andi.b		&0x0a,%d0		# is UNFL or INEX enabled?
   20410  1.1.6.2  bouyer 	bne.b		fout_ext_exc		# yes
   20411  1.1.6.2  bouyer 	rts
   20412  1.1.6.2  bouyer 
   20413  1.1.6.2  bouyer # we don't want to do the write if the exception occurred in supervisor mode
   20414  1.1.6.2  bouyer # so _mem_write2() handles this for us.
   20415  1.1.6.2  bouyer fout_ext_a7:
   20416  1.1.6.2  bouyer 	bsr.l		_mem_write2		# write ext prec number to memory
   20417  1.1.6.2  bouyer 
   20418  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20419  1.1.6.2  bouyer 	bne.w		fout_ext_err		# yes
   20420  1.1.6.2  bouyer 
   20421  1.1.6.2  bouyer 	tst.b		STAG(%a6)		# is operand normalized?
   20422  1.1.6.2  bouyer 	bne.b		fout_ext_denorm		# no
   20423  1.1.6.2  bouyer 	rts
   20424  1.1.6.2  bouyer 
   20425  1.1.6.2  bouyer fout_ext_exc:
   20426  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   20427  1.1.6.2  bouyer 	bsr.l		norm			# normalize the mantissa
   20428  1.1.6.2  bouyer 	neg.w		%d0			# new exp = -(shft amt)
   20429  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0
   20430  1.1.6.2  bouyer 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# keep only old sign
   20431  1.1.6.2  bouyer 	or.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
   20432  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   20433  1.1.6.2  bouyer 	rts
   20434  1.1.6.2  bouyer 
   20435  1.1.6.2  bouyer fout_ext_err:
   20436  1.1.6.2  bouyer 	mov.l		EXC_A6(%a6),(%a6)	# fix stacked a6
   20437  1.1.6.2  bouyer 	bra.l		facc_out_x
   20438  1.1.6.2  bouyer 
   20439  1.1.6.2  bouyer #########################################################################
   20440  1.1.6.2  bouyer # fmove.s out ###########################################################
   20441  1.1.6.2  bouyer #########################################################################
   20442  1.1.6.2  bouyer fout_sgl:
   20443  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   20444  1.1.6.2  bouyer 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
   20445  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# save rnd prec,mode on stack
   20446  1.1.6.2  bouyer 
   20447  1.1.6.2  bouyer #
   20448  1.1.6.2  bouyer # operand is a normalized number. first, we check to see if the move out
   20449  1.1.6.2  bouyer # would cause either an underflow or overflow. these cases are handled
   20450  1.1.6.2  bouyer # separately. otherwise, set the FPCR to the proper rounding mode and
   20451  1.1.6.2  bouyer # execute the move.
   20452  1.1.6.2  bouyer #
   20453  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0		# extract exponent
   20454  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# strip sign
   20455  1.1.6.2  bouyer 
   20456  1.1.6.2  bouyer 	cmpi.w		%d0,&SGL_HI		# will operand overflow?
   20457  1.1.6.2  bouyer 	bgt.w		fout_sgl_ovfl		# yes; go handle OVFL
   20458  1.1.6.2  bouyer 	beq.w		fout_sgl_may_ovfl	# maybe; go handle possible OVFL
   20459  1.1.6.2  bouyer 	cmpi.w		%d0,&SGL_LO		# will operand underflow?
   20460  1.1.6.2  bouyer 	blt.w		fout_sgl_unfl		# yes; go handle underflow
   20461  1.1.6.2  bouyer 
   20462  1.1.6.2  bouyer #
   20463  1.1.6.2  bouyer # NORMs(in range) can be stored out by a simple "fmov.s"
   20464  1.1.6.2  bouyer # Unnormalized inputs can come through this point.
   20465  1.1.6.2  bouyer #
   20466  1.1.6.2  bouyer fout_sgl_exg:
   20467  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# fetch fop from stack
   20468  1.1.6.2  bouyer 
   20469  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20470  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   20471  1.1.6.2  bouyer 
   20472  1.1.6.2  bouyer 	fmov.s		%fp0,%d0		# store does convert and round
   20473  1.1.6.2  bouyer 
   20474  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   20475  1.1.6.2  bouyer 	fmov.l		%fpsr,%d1		# save FPSR
   20476  1.1.6.2  bouyer 
   20477  1.1.6.2  bouyer 	or.w		%d1,2+USER_FPSR(%a6) 	# set possible inex2/ainex
   20478  1.1.6.2  bouyer 
   20479  1.1.6.2  bouyer fout_sgl_exg_write:
   20480  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20481  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20482  1.1.6.2  bouyer 	beq.b		fout_sgl_exg_write_dn	# must save to integer regfile
   20483  1.1.6.2  bouyer 
   20484  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20485  1.1.6.2  bouyer 	bsr.l		_dmem_write_long	# write long
   20486  1.1.6.2  bouyer 
   20487  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20488  1.1.6.2  bouyer 	bne.l		facc_out_l		# yes
   20489  1.1.6.2  bouyer 
   20490  1.1.6.2  bouyer 	rts
   20491  1.1.6.2  bouyer 
   20492  1.1.6.2  bouyer fout_sgl_exg_write_dn:
   20493  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20494  1.1.6.2  bouyer 	andi.w		&0x7,%d1
   20495  1.1.6.2  bouyer 	bsr.l		store_dreg_l
   20496  1.1.6.2  bouyer 	rts
   20497  1.1.6.2  bouyer 
   20498  1.1.6.2  bouyer #
   20499  1.1.6.2  bouyer # here, we know that the operand would UNFL if moved out to single prec,
   20500  1.1.6.2  bouyer # so, denorm and round and then use generic store single routine to
   20501  1.1.6.2  bouyer # write the value to memory.
   20502  1.1.6.2  bouyer #
   20503  1.1.6.2  bouyer fout_sgl_unfl:
   20504  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
   20505  1.1.6.2  bouyer 
   20506  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20507  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20508  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20509  1.1.6.2  bouyer 	mov.l		%a0,-(%sp)
   20510  1.1.6.2  bouyer 
   20511  1.1.6.2  bouyer 	clr.l		%d0			# pass: S.F. = 0
   20512  1.1.6.2  bouyer 
   20513  1.1.6.2  bouyer 	cmpi.b		STAG(%a6),&DENORM	# fetch src optype tag
   20514  1.1.6.2  bouyer 	bne.b		fout_sgl_unfl_cont	# let DENORMs fall through
   20515  1.1.6.2  bouyer 
   20516  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   20517  1.1.6.2  bouyer 	bsr.l		norm			# normalize the DENORM
   20518  1.1.6.2  bouyer 
   20519  1.1.6.2  bouyer fout_sgl_unfl_cont:
   20520  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   20521  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   20522  1.1.6.2  bouyer 	bsr.l		unf_res			# calc default underflow result
   20523  1.1.6.2  bouyer 
   20524  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to fop
   20525  1.1.6.2  bouyer 	bsr.l		dst_sgl			# convert to single prec
   20526  1.1.6.2  bouyer 
   20527  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20528  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20529  1.1.6.2  bouyer 	beq.b		fout_sgl_unfl_dn	# must save to integer regfile
   20530  1.1.6.2  bouyer 
   20531  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20532  1.1.6.2  bouyer 	bsr.l		_dmem_write_long	# write long
   20533  1.1.6.2  bouyer 
   20534  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20535  1.1.6.2  bouyer 	bne.l		facc_out_l		# yes
   20536  1.1.6.2  bouyer 
   20537  1.1.6.2  bouyer 	bra.b		fout_sgl_unfl_chkexc
   20538  1.1.6.2  bouyer 
   20539  1.1.6.2  bouyer fout_sgl_unfl_dn:
   20540  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20541  1.1.6.2  bouyer 	andi.w		&0x7,%d1
   20542  1.1.6.2  bouyer 	bsr.l		store_dreg_l
   20543  1.1.6.2  bouyer 
   20544  1.1.6.2  bouyer fout_sgl_unfl_chkexc:
   20545  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   20546  1.1.6.2  bouyer 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20547  1.1.6.2  bouyer 	bne.w		fout_sd_exc_unfl	# yes
   20548  1.1.6.2  bouyer 	addq.l		&0x4,%sp
   20549  1.1.6.2  bouyer 	rts
   20550  1.1.6.2  bouyer 
   20551  1.1.6.2  bouyer #
   20552  1.1.6.2  bouyer # it's definitely an overflow so call ovf_res to get the correct answer
   20553  1.1.6.2  bouyer #
   20554  1.1.6.2  bouyer fout_sgl_ovfl:
   20555  1.1.6.2  bouyer 	tst.b		3+SRC_HI(%a0)		# is result inexact?
   20556  1.1.6.2  bouyer 	bne.b		fout_sgl_ovfl_inex2
   20557  1.1.6.2  bouyer 	tst.l		SRC_LO(%a0)		# is result inexact?
   20558  1.1.6.2  bouyer 	bne.b		fout_sgl_ovfl_inex2
   20559  1.1.6.2  bouyer 	ori.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
   20560  1.1.6.2  bouyer 	bra.b		fout_sgl_ovfl_cont
   20561  1.1.6.2  bouyer fout_sgl_ovfl_inex2:
   20562  1.1.6.2  bouyer 	ori.w		&ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
   20563  1.1.6.2  bouyer 
   20564  1.1.6.2  bouyer fout_sgl_ovfl_cont:
   20565  1.1.6.2  bouyer 	mov.l		%a0,-(%sp)
   20566  1.1.6.2  bouyer 
   20567  1.1.6.2  bouyer # call ovf_res() w/ sgl prec and the correct rnd mode to create the default
   20568  1.1.6.2  bouyer # overflow result. DON'T save the returned ccodes from ovf_res() since
   20569  1.1.6.2  bouyer # fmove out doesn't alter them.
   20570  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   20571  1.1.6.2  bouyer 	smi		%d1			# set if so
   20572  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass: sgl prec,rnd mode
   20573  1.1.6.2  bouyer 	bsr.l		ovf_res			# calc OVFL result
   20574  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# load default overflow result
   20575  1.1.6.2  bouyer 	fmov.s		%fp0,%d0		# store to single
   20576  1.1.6.2  bouyer 
   20577  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
   20578  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
   20579  1.1.6.2  bouyer 	beq.b		fout_sgl_ovfl_dn	# must save to integer regfile
   20580  1.1.6.2  bouyer 
   20581  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
   20582  1.1.6.2  bouyer 	bsr.l		_dmem_write_long	# write long
   20583  1.1.6.2  bouyer 
   20584  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20585  1.1.6.2  bouyer 	bne.l		facc_out_l		# yes
   20586  1.1.6.2  bouyer 
   20587  1.1.6.2  bouyer 	bra.b		fout_sgl_ovfl_chkexc
   20588  1.1.6.2  bouyer 
   20589  1.1.6.2  bouyer fout_sgl_ovfl_dn:
   20590  1.1.6.2  bouyer 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
   20591  1.1.6.2  bouyer 	andi.w		&0x7,%d1
   20592  1.1.6.2  bouyer 	bsr.l		store_dreg_l
   20593  1.1.6.2  bouyer 
   20594  1.1.6.2  bouyer fout_sgl_ovfl_chkexc:
   20595  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   20596  1.1.6.2  bouyer 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20597  1.1.6.2  bouyer 	bne.w		fout_sd_exc_ovfl	# yes
   20598  1.1.6.2  bouyer 	addq.l		&0x4,%sp
   20599  1.1.6.2  bouyer 	rts
   20600  1.1.6.2  bouyer 
   20601  1.1.6.2  bouyer #
   20602  1.1.6.2  bouyer # move out MAY overflow:
   20603  1.1.6.2  bouyer # (1) force the exp to 0x3fff
   20604  1.1.6.2  bouyer # (2) do a move w/ appropriate rnd mode
   20605  1.1.6.2  bouyer # (3) if exp still equals zero, then insert original exponent
   20606  1.1.6.2  bouyer #	for the correct result.
   20607  1.1.6.2  bouyer #     if exp now equals one, then it overflowed so call ovf_res.
   20608  1.1.6.2  bouyer #
   20609  1.1.6.2  bouyer fout_sgl_may_ovfl:
   20610  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d1		# fetch current sign
   20611  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep it,clear exp
   20612  1.1.6.2  bouyer 	ori.w		&0x3fff,%d1		# insert exp = 0
   20613  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert scaled exp
   20614  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
   20615  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
   20616  1.1.6.2  bouyer 
   20617  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20618  1.1.6.2  bouyer 
   20619  1.1.6.2  bouyer 	fmov.x		FP_SCR0(%a6),%fp0	# force fop to be rounded
   20620  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   20621  1.1.6.2  bouyer 
   20622  1.1.6.2  bouyer 	fabs.x		%fp0			# need absolute value
   20623  1.1.6.2  bouyer 	fcmp.b		%fp0,&0x2		# did exponent increase?
   20624  1.1.6.2  bouyer 	fblt.w		fout_sgl_exg		# no; go finish NORM
   20625  1.1.6.2  bouyer 	bra.w		fout_sgl_ovfl		# yes; go handle overflow
   20626  1.1.6.2  bouyer 
   20627  1.1.6.2  bouyer ################
   20628  1.1.6.2  bouyer 
   20629  1.1.6.2  bouyer fout_sd_exc_unfl:
   20630  1.1.6.2  bouyer 	mov.l		(%sp)+,%a0
   20631  1.1.6.2  bouyer 
   20632  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20633  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20634  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20635  1.1.6.2  bouyer 
   20636  1.1.6.2  bouyer 	cmpi.b		STAG(%a6),&DENORM	# was src a DENORM?
   20637  1.1.6.2  bouyer 	bne.b		fout_sd_exc_cont	# no
   20638  1.1.6.2  bouyer 
   20639  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   20640  1.1.6.2  bouyer 	bsr.l		norm
   20641  1.1.6.2  bouyer 	neg.l		%d0
   20642  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0
   20643  1.1.6.2  bouyer 	bfins		%d0,FP_SCR0_EX(%a6){&1:&15}
   20644  1.1.6.2  bouyer 	bra.b		fout_sd_exc_cont
   20645  1.1.6.2  bouyer 
   20646  1.1.6.2  bouyer fout_sd_exc:
   20647  1.1.6.2  bouyer fout_sd_exc_ovfl:
   20648  1.1.6.2  bouyer 	mov.l		(%sp)+,%a0		# restore a0
   20649  1.1.6.2  bouyer 
   20650  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20651  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20652  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20653  1.1.6.2  bouyer 
   20654  1.1.6.2  bouyer fout_sd_exc_cont:
   20655  1.1.6.2  bouyer 	bclr		&0x7,FP_SCR0_EX(%a6)	# clear sign bit
   20656  1.1.6.2  bouyer 	sne.b		2+FP_SCR0_EX(%a6)	# set internal sign bit
   20657  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to DENORM
   20658  1.1.6.2  bouyer 
   20659  1.1.6.2  bouyer 	mov.b		3+L_SCR3(%a6),%d1
   20660  1.1.6.2  bouyer 	lsr.b		&0x4,%d1
   20661  1.1.6.2  bouyer 	andi.w		&0x0c,%d1
   20662  1.1.6.2  bouyer 	swap		%d1
   20663  1.1.6.2  bouyer 	mov.b		3+L_SCR3(%a6),%d1
   20664  1.1.6.2  bouyer 	lsr.b		&0x4,%d1
   20665  1.1.6.2  bouyer 	andi.w		&0x03,%d1
   20666  1.1.6.2  bouyer 	clr.l		%d0			# pass: zero g,r,s
   20667  1.1.6.2  bouyer 	bsr.l		_round			# round the DENORM
   20668  1.1.6.2  bouyer 
   20669  1.1.6.2  bouyer 	tst.b		2+FP_SCR0_EX(%a6)	# is EXOP negative?
   20670  1.1.6.2  bouyer 	beq.b		fout_sd_exc_done	# no
   20671  1.1.6.2  bouyer 	bset		&0x7,FP_SCR0_EX(%a6)	# yes
   20672  1.1.6.2  bouyer 
   20673  1.1.6.2  bouyer fout_sd_exc_done:
   20674  1.1.6.2  bouyer 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
   20675  1.1.6.2  bouyer 	rts
   20676  1.1.6.2  bouyer 
   20677  1.1.6.2  bouyer #################################################################
   20678  1.1.6.2  bouyer # fmove.d out ###################################################
   20679  1.1.6.2  bouyer #################################################################
   20680  1.1.6.2  bouyer fout_dbl:
   20681  1.1.6.2  bouyer 	andi.b		&0x30,%d0		# clear rnd prec
   20682  1.1.6.2  bouyer 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
   20683  1.1.6.2  bouyer 	mov.l		%d0,L_SCR3(%a6)		# save rnd prec,mode on stack
   20684  1.1.6.2  bouyer 
   20685  1.1.6.2  bouyer #
   20686  1.1.6.2  bouyer # operand is a normalized number. first, we check to see if the move out
   20687  1.1.6.2  bouyer # would cause either an underflow or overflow. these cases are handled
   20688  1.1.6.2  bouyer # separately. otherwise, set the FPCR to the proper rounding mode and
   20689  1.1.6.2  bouyer # execute the move.
   20690  1.1.6.2  bouyer #
   20691  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d0		# extract exponent
   20692  1.1.6.2  bouyer 	andi.w		&0x7fff,%d0		# strip sign
   20693  1.1.6.2  bouyer 
   20694  1.1.6.2  bouyer 	cmpi.w		%d0,&DBL_HI		# will operand overflow?
   20695  1.1.6.2  bouyer 	bgt.w		fout_dbl_ovfl		# yes; go handle OVFL
   20696  1.1.6.2  bouyer 	beq.w		fout_dbl_may_ovfl	# maybe; go handle possible OVFL
   20697  1.1.6.2  bouyer 	cmpi.w		%d0,&DBL_LO		# will operand underflow?
   20698  1.1.6.2  bouyer 	blt.w		fout_dbl_unfl		# yes; go handle underflow
   20699  1.1.6.2  bouyer 
   20700  1.1.6.2  bouyer #
   20701  1.1.6.2  bouyer # NORMs(in range) can be stored out by a simple "fmov.d"
   20702  1.1.6.2  bouyer # Unnormalized inputs can come through this point.
   20703  1.1.6.2  bouyer #
   20704  1.1.6.2  bouyer fout_dbl_exg:
   20705  1.1.6.2  bouyer 	fmovm.x		SRC(%a0),&0x80		# fetch fop from stack
   20706  1.1.6.2  bouyer 
   20707  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20708  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr		# clear FPSR
   20709  1.1.6.2  bouyer 
   20710  1.1.6.2  bouyer 	fmov.d		%fp0,L_SCR1(%a6)	# store does convert and round
   20711  1.1.6.2  bouyer 
   20712  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   20713  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# save FPSR
   20714  1.1.6.2  bouyer 
   20715  1.1.6.2  bouyer 	or.w		%d0,2+USER_FPSR(%a6) 	# set possible inex2/ainex
   20716  1.1.6.2  bouyer 
   20717  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   20718  1.1.6.2  bouyer 	lea		L_SCR1(%a6),%a0		# pass: src addr
   20719  1.1.6.2  bouyer 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
   20720  1.1.6.2  bouyer 	bsr.l		_dmem_write		# store dbl fop to memory
   20721  1.1.6.2  bouyer 
   20722  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20723  1.1.6.2  bouyer 	bne.l		facc_out_d		# yes
   20724  1.1.6.2  bouyer 
   20725  1.1.6.2  bouyer 	rts					# no; so we're finished
   20726  1.1.6.2  bouyer 
   20727  1.1.6.2  bouyer #
   20728  1.1.6.2  bouyer # here, we know that the operand would UNFL if moved out to double prec,
   20729  1.1.6.2  bouyer # so, denorm and round and then use generic store double routine to
   20730  1.1.6.2  bouyer # write the value to memory.
   20731  1.1.6.2  bouyer #
   20732  1.1.6.2  bouyer fout_dbl_unfl:
   20733  1.1.6.2  bouyer 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
   20734  1.1.6.2  bouyer 
   20735  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
   20736  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
   20737  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
   20738  1.1.6.2  bouyer 	mov.l		%a0,-(%sp)
   20739  1.1.6.2  bouyer 
   20740  1.1.6.2  bouyer 	clr.l		%d0			# pass: S.F. = 0
   20741  1.1.6.2  bouyer 
   20742  1.1.6.2  bouyer 	cmpi.b		STAG(%a6),&DENORM	# fetch src optype tag
   20743  1.1.6.2  bouyer 	bne.b		fout_dbl_unfl_cont	# let DENORMs fall through
   20744  1.1.6.2  bouyer 
   20745  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   20746  1.1.6.2  bouyer 	bsr.l		norm			# normalize the DENORM
   20747  1.1.6.2  bouyer 
   20748  1.1.6.2  bouyer fout_dbl_unfl_cont:
   20749  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
   20750  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
   20751  1.1.6.2  bouyer 	bsr.l		unf_res			# calc default underflow result
   20752  1.1.6.2  bouyer 
   20753  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: ptr to fop
   20754  1.1.6.2  bouyer 	bsr.l		dst_dbl			# convert to single prec
   20755  1.1.6.2  bouyer 	mov.l		%d0,L_SCR1(%a6)
   20756  1.1.6.2  bouyer 	mov.l		%d1,L_SCR2(%a6)
   20757  1.1.6.2  bouyer 
   20758  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   20759  1.1.6.2  bouyer 	lea		L_SCR1(%a6),%a0		# pass: src addr
   20760  1.1.6.2  bouyer 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
   20761  1.1.6.2  bouyer 	bsr.l		_dmem_write		# store dbl fop to memory
   20762  1.1.6.2  bouyer 
   20763  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20764  1.1.6.2  bouyer 	bne.l		facc_out_d		# yes
   20765  1.1.6.2  bouyer 
   20766  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   20767  1.1.6.2  bouyer 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20768  1.1.6.2  bouyer 	bne.w		fout_sd_exc_unfl	# yes
   20769  1.1.6.2  bouyer 	addq.l		&0x4,%sp
   20770  1.1.6.2  bouyer 	rts
   20771  1.1.6.2  bouyer 
   20772  1.1.6.2  bouyer #
   20773  1.1.6.2  bouyer # it's definitely an overflow so call ovf_res to get the correct answer
   20774  1.1.6.2  bouyer #
   20775  1.1.6.2  bouyer fout_dbl_ovfl:
   20776  1.1.6.2  bouyer 	mov.w		2+SRC_LO(%a0),%d0
   20777  1.1.6.2  bouyer 	andi.w		&0x7ff,%d0
   20778  1.1.6.2  bouyer 	bne.b		fout_dbl_ovfl_inex2
   20779  1.1.6.2  bouyer 
   20780  1.1.6.2  bouyer 	ori.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
   20781  1.1.6.2  bouyer 	bra.b		fout_dbl_ovfl_cont
   20782  1.1.6.2  bouyer fout_dbl_ovfl_inex2:
   20783  1.1.6.2  bouyer 	ori.w		&ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
   20784  1.1.6.2  bouyer 
   20785  1.1.6.2  bouyer fout_dbl_ovfl_cont:
   20786  1.1.6.2  bouyer 	mov.l		%a0,-(%sp)
   20787  1.1.6.2  bouyer 
   20788  1.1.6.2  bouyer # call ovf_res() w/ dbl prec and the correct rnd mode to create the default
   20789  1.1.6.2  bouyer # overflow result. DON'T save the returned ccodes from ovf_res() since
   20790  1.1.6.2  bouyer # fmove out doesn't alter them.
   20791  1.1.6.2  bouyer 	tst.b		SRC_EX(%a0)		# is operand negative?
   20792  1.1.6.2  bouyer 	smi		%d1			# set if so
   20793  1.1.6.2  bouyer 	mov.l		L_SCR3(%a6),%d0		# pass: dbl prec,rnd mode
   20794  1.1.6.2  bouyer 	bsr.l		ovf_res			# calc OVFL result
   20795  1.1.6.2  bouyer 	fmovm.x		(%a0),&0x80		# load default overflow result
   20796  1.1.6.2  bouyer 	fmov.d		%fp0,L_SCR1(%a6)	# store to double
   20797  1.1.6.2  bouyer 
   20798  1.1.6.2  bouyer 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
   20799  1.1.6.2  bouyer 	lea		L_SCR1(%a6),%a0		# pass: src addr
   20800  1.1.6.2  bouyer 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
   20801  1.1.6.2  bouyer 	bsr.l		_dmem_write		# store dbl fop to memory
   20802  1.1.6.2  bouyer 
   20803  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   20804  1.1.6.2  bouyer 	bne.l		facc_out_d		# yes
   20805  1.1.6.2  bouyer 
   20806  1.1.6.2  bouyer 	mov.b		FPCR_ENABLE(%a6),%d1
   20807  1.1.6.2  bouyer 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
   20808  1.1.6.2  bouyer 	bne.w		fout_sd_exc_ovfl	# yes
   20809  1.1.6.2  bouyer 	addq.l		&0x4,%sp
   20810  1.1.6.2  bouyer 	rts
   20811  1.1.6.2  bouyer 
   20812  1.1.6.2  bouyer #
   20813  1.1.6.2  bouyer # move out MAY overflow:
   20814  1.1.6.2  bouyer # (1) force the exp to 0x3fff
   20815  1.1.6.2  bouyer # (2) do a move w/ appropriate rnd mode
   20816  1.1.6.2  bouyer # (3) if exp still equals zero, then insert original exponent
   20817  1.1.6.2  bouyer #	for the correct result.
   20818  1.1.6.2  bouyer #     if exp now equals one, then it overflowed so call ovf_res.
   20819  1.1.6.2  bouyer #
   20820  1.1.6.2  bouyer fout_dbl_may_ovfl:
   20821  1.1.6.2  bouyer 	mov.w		SRC_EX(%a0),%d1		# fetch current sign
   20822  1.1.6.2  bouyer 	andi.w		&0x8000,%d1		# keep it,clear exp
   20823  1.1.6.2  bouyer 	ori.w		&0x3fff,%d1		# insert exp = 0
   20824  1.1.6.2  bouyer 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert scaled exp
   20825  1.1.6.2  bouyer 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
   20826  1.1.6.2  bouyer 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
   20827  1.1.6.2  bouyer 
   20828  1.1.6.2  bouyer 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
   20829  1.1.6.2  bouyer 
   20830  1.1.6.2  bouyer 	fmov.x		FP_SCR0(%a6),%fp0	# force fop to be rounded
   20831  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr		# clear FPCR
   20832  1.1.6.2  bouyer 
   20833  1.1.6.2  bouyer 	fabs.x		%fp0			# need absolute value
   20834  1.1.6.2  bouyer 	fcmp.b		%fp0,&0x2		# did exponent increase?
   20835  1.1.6.2  bouyer 	fblt.w		fout_dbl_exg		# no; go finish NORM
   20836  1.1.6.2  bouyer 	bra.w		fout_dbl_ovfl		# yes; go handle overflow
   20837  1.1.6.2  bouyer 
   20838  1.1.6.2  bouyer #########################################################################
   20839  1.1.6.2  bouyer # XDEF ****************************************************************	#
   20840  1.1.6.2  bouyer # 	dst_dbl(): create double precision value from extended prec.	#
   20841  1.1.6.2  bouyer #									#
   20842  1.1.6.2  bouyer # XREF ****************************************************************	#
   20843  1.1.6.2  bouyer #	None								#
   20844  1.1.6.2  bouyer #									#
   20845  1.1.6.2  bouyer # INPUT ***************************************************************	#
   20846  1.1.6.2  bouyer #	a0 = pointer to source operand in extended precision		#
   20847  1.1.6.2  bouyer # 									#
   20848  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   20849  1.1.6.2  bouyer #	d0 = hi(double precision result)				#
   20850  1.1.6.2  bouyer #	d1 = lo(double precision result)				#
   20851  1.1.6.2  bouyer #									#
   20852  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   20853  1.1.6.2  bouyer #									#
   20854  1.1.6.2  bouyer #  Changes extended precision to double precision.			#
   20855  1.1.6.2  bouyer #  Note: no attempt is made to round the extended value to double.	#
   20856  1.1.6.2  bouyer #	dbl_sign = ext_sign						#
   20857  1.1.6.2  bouyer #	dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)		#
   20858  1.1.6.2  bouyer #	get rid of ext integer bit					#
   20859  1.1.6.2  bouyer #	dbl_mant = ext_mant{62:12}					#
   20860  1.1.6.2  bouyer #									#
   20861  1.1.6.2  bouyer #	    	---------------   ---------------    ---------------	#
   20862  1.1.6.2  bouyer #  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |	#
   20863  1.1.6.2  bouyer #	    	---------------   ---------------    ---------------	#
   20864  1.1.6.2  bouyer #	   	 95	    64    63 62	      32      31     11	  0	#
   20865  1.1.6.2  bouyer #				     |			     |		#
   20866  1.1.6.2  bouyer #				     |			     |		#
   20867  1.1.6.2  bouyer #				     |			     |		#
   20868  1.1.6.2  bouyer #		 	             v   		     v		#
   20869  1.1.6.2  bouyer #	    		      ---------------   ---------------		#
   20870  1.1.6.2  bouyer #  double   ->  	      |s|exp| mant  |   |  mant       |		#
   20871  1.1.6.2  bouyer #	    		      ---------------   ---------------		#
   20872  1.1.6.2  bouyer #	   	 	      63     51   32   31	       0	#
   20873  1.1.6.2  bouyer #									#
   20874  1.1.6.2  bouyer #########################################################################
   20875  1.1.6.2  bouyer 
   20876  1.1.6.2  bouyer dst_dbl:
   20877  1.1.6.2  bouyer 	clr.l		%d0			# clear d0
   20878  1.1.6.2  bouyer 	mov.w		FTEMP_EX(%a0),%d0	# get exponent
   20879  1.1.6.2  bouyer 	subi.w		&EXT_BIAS,%d0		# subtract extended precision bias
   20880  1.1.6.2  bouyer 	addi.w		&DBL_BIAS,%d0		# add double precision bias
   20881  1.1.6.2  bouyer 	tst.b		FTEMP_HI(%a0)		# is number a denorm?
   20882  1.1.6.2  bouyer 	bmi.b		dst_get_dupper		# no
   20883  1.1.6.2  bouyer 	subq.w		&0x1,%d0		# yes; denorm bias = DBL_BIAS - 1
   20884  1.1.6.2  bouyer dst_get_dupper:
   20885  1.1.6.2  bouyer 	swap		%d0			# d0 now in upper word
   20886  1.1.6.2  bouyer 	lsl.l		&0x4,%d0		# d0 in proper place for dbl prec exp
   20887  1.1.6.2  bouyer 	tst.b		FTEMP_EX(%a0)		# test sign
   20888  1.1.6.2  bouyer 	bpl.b		dst_get_dman		# if postive, go process mantissa
   20889  1.1.6.2  bouyer 	bset		&0x1f,%d0		# if negative, set sign
   20890  1.1.6.2  bouyer dst_get_dman:
   20891  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
   20892  1.1.6.2  bouyer 	bfextu		%d1{&1:&20},%d1		# get upper 20 bits of ms
   20893  1.1.6.2  bouyer 	or.l		%d1,%d0			# put these bits in ms word of double
   20894  1.1.6.2  bouyer 	mov.l		%d0,L_SCR1(%a6)		# put the new exp back on the stack
   20895  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
   20896  1.1.6.2  bouyer 	mov.l		&21,%d0			# load shift count
   20897  1.1.6.2  bouyer 	lsl.l		%d0,%d1			# put lower 11 bits in upper bits
   20898  1.1.6.2  bouyer 	mov.l		%d1,L_SCR2(%a6)		# build lower lword in memory
   20899  1.1.6.2  bouyer 	mov.l		FTEMP_LO(%a0),%d1	# get ls mantissa
   20900  1.1.6.2  bouyer 	bfextu		%d1{&0:&21},%d0		# get ls 21 bits of double
   20901  1.1.6.2  bouyer 	mov.l		L_SCR2(%a6),%d1
   20902  1.1.6.2  bouyer 	or.l		%d0,%d1			# put them in double result
   20903  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d0
   20904  1.1.6.2  bouyer 	rts
   20905  1.1.6.2  bouyer 
   20906  1.1.6.2  bouyer #########################################################################
   20907  1.1.6.2  bouyer # XDEF ****************************************************************	#
   20908  1.1.6.2  bouyer # 	dst_sgl(): create single precision value from extended prec	#
   20909  1.1.6.2  bouyer #									#
   20910  1.1.6.2  bouyer # XREF ****************************************************************	#
   20911  1.1.6.2  bouyer #									#
   20912  1.1.6.2  bouyer # INPUT ***************************************************************	#
   20913  1.1.6.2  bouyer #	a0 = pointer to source operand in extended precision		#
   20914  1.1.6.2  bouyer # 									#
   20915  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   20916  1.1.6.2  bouyer #	d0 = single precision result					#
   20917  1.1.6.2  bouyer #									#
   20918  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   20919  1.1.6.2  bouyer #									#
   20920  1.1.6.2  bouyer # Changes extended precision to single precision.			#
   20921  1.1.6.2  bouyer #	sgl_sign = ext_sign						#
   20922  1.1.6.2  bouyer #	sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)		#
   20923  1.1.6.2  bouyer #	get rid of ext integer bit					#
   20924  1.1.6.2  bouyer #	sgl_mant = ext_mant{62:12}					#
   20925  1.1.6.2  bouyer #									#
   20926  1.1.6.2  bouyer #	    	---------------   ---------------    ---------------	#
   20927  1.1.6.2  bouyer #  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |	#
   20928  1.1.6.2  bouyer #	    	---------------   ---------------    ---------------	#
   20929  1.1.6.2  bouyer #	   	 95	    64    63 62	   40 32      31     12	  0	#
   20930  1.1.6.2  bouyer #				     |	   |				#
   20931  1.1.6.2  bouyer #				     |	   |				#
   20932  1.1.6.2  bouyer #				     |	   |				#
   20933  1.1.6.2  bouyer #		 	             v     v				#
   20934  1.1.6.2  bouyer #	    		      ---------------				#
   20935  1.1.6.2  bouyer #  single   ->  	      |s|exp| mant  |				#
   20936  1.1.6.2  bouyer #	    		      ---------------				#
   20937  1.1.6.2  bouyer #	   	 	      31     22     0				#
   20938  1.1.6.2  bouyer #									#
   20939  1.1.6.2  bouyer #########################################################################
   20940  1.1.6.2  bouyer 
   20941  1.1.6.2  bouyer dst_sgl:
   20942  1.1.6.2  bouyer 	clr.l		%d0
   20943  1.1.6.2  bouyer 	mov.w		FTEMP_EX(%a0),%d0	# get exponent
   20944  1.1.6.2  bouyer 	subi.w		&EXT_BIAS,%d0		# subtract extended precision bias
   20945  1.1.6.2  bouyer 	addi.w		&SGL_BIAS,%d0		# add single precision bias
   20946  1.1.6.2  bouyer 	tst.b		FTEMP_HI(%a0)		# is number a denorm?
   20947  1.1.6.2  bouyer 	bmi.b		dst_get_supper		# no
   20948  1.1.6.2  bouyer 	subq.w		&0x1,%d0		# yes; denorm bias = SGL_BIAS - 1
   20949  1.1.6.2  bouyer dst_get_supper:
   20950  1.1.6.2  bouyer 	swap		%d0			# put exp in upper word of d0
   20951  1.1.6.2  bouyer 	lsl.l		&0x7,%d0		# shift it into single exp bits
   20952  1.1.6.2  bouyer 	tst.b		FTEMP_EX(%a0)		# test sign
   20953  1.1.6.2  bouyer 	bpl.b		dst_get_sman		# if positive, continue
   20954  1.1.6.2  bouyer 	bset		&0x1f,%d0		# if negative, put in sign first
   20955  1.1.6.2  bouyer dst_get_sman:
   20956  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
   20957  1.1.6.2  bouyer 	andi.l		&0x7fffff00,%d1		# get upper 23 bits of ms
   20958  1.1.6.2  bouyer 	lsr.l		&0x8,%d1		# and put them flush right
   20959  1.1.6.2  bouyer 	or.l		%d1,%d0			# put these bits in ms word of single
   20960  1.1.6.2  bouyer 	rts
   20961  1.1.6.2  bouyer 
   20962  1.1.6.2  bouyer ##############################################################################
   20963  1.1.6.2  bouyer fout_pack:
   20964  1.1.6.2  bouyer 	bsr.l		_calc_ea_fout		# fetch the <ea>
   20965  1.1.6.2  bouyer 	mov.l		%a0,-(%sp)
   20966  1.1.6.2  bouyer 
   20967  1.1.6.2  bouyer 	mov.b		STAG(%a6),%d0		# fetch input type
   20968  1.1.6.2  bouyer 	bne.w		fout_pack_not_norm	# input is not NORM
   20969  1.1.6.2  bouyer 
   20970  1.1.6.2  bouyer fout_pack_norm:
   20971  1.1.6.2  bouyer 	btst		&0x4,EXC_CMDREG(%a6)	# static or dynamic?
   20972  1.1.6.2  bouyer 	beq.b		fout_pack_s		# static
   20973  1.1.6.2  bouyer 
   20974  1.1.6.2  bouyer fout_pack_d:
   20975  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d1	# fetch dynamic reg
   20976  1.1.6.2  bouyer 	lsr.b		&0x4,%d1
   20977  1.1.6.2  bouyer 	andi.w		&0x7,%d1
   20978  1.1.6.2  bouyer 
   20979  1.1.6.2  bouyer 	bsr.l		fetch_dreg		# fetch Dn w/ k-factor
   20980  1.1.6.2  bouyer 
   20981  1.1.6.2  bouyer 	bra.b		fout_pack_type
   20982  1.1.6.2  bouyer fout_pack_s:
   20983  1.1.6.2  bouyer 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch static field
   20984  1.1.6.2  bouyer 
   20985  1.1.6.2  bouyer fout_pack_type:
   20986  1.1.6.2  bouyer 	bfexts		%d0{&25:&7},%d0		# extract k-factor
   20987  1.1.6.2  bouyer 	mov.l	%d0,-(%sp)
   20988  1.1.6.2  bouyer 
   20989  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to input
   20990  1.1.6.2  bouyer 
   20991  1.1.6.2  bouyer # bindec is currently scrambling FP_SRC for denorm inputs.
   20992  1.1.6.2  bouyer # we'll have to change this, but for now, tough luck!!!
   20993  1.1.6.2  bouyer 	bsr.l		bindec			# convert xprec to packed
   20994  1.1.6.2  bouyer 
   20995  1.1.6.2  bouyer #	andi.l		&0xcfff000f,FP_SCR0(%a6) # clear unused fields
   20996  1.1.6.2  bouyer 	andi.l		&0xcffff00f,FP_SCR0(%a6) # clear unused fields
   20997  1.1.6.2  bouyer 
   20998  1.1.6.2  bouyer 	mov.l	(%sp)+,%d0
   20999  1.1.6.2  bouyer 
   21000  1.1.6.2  bouyer 	tst.b		3+FP_SCR0_EX(%a6)
   21001  1.1.6.2  bouyer 	bne.b		fout_pack_set
   21002  1.1.6.2  bouyer 	tst.l		FP_SCR0_HI(%a6)
   21003  1.1.6.2  bouyer 	bne.b		fout_pack_set
   21004  1.1.6.2  bouyer 	tst.l		FP_SCR0_LO(%a6)
   21005  1.1.6.2  bouyer 	bne.b		fout_pack_set
   21006  1.1.6.2  bouyer 
   21007  1.1.6.2  bouyer # add the extra condition that only if the k-factor was zero, too, should
   21008  1.1.6.2  bouyer # we zero the exponent
   21009  1.1.6.2  bouyer 	tst.l		%d0
   21010  1.1.6.2  bouyer 	bne.b		fout_pack_set
   21011  1.1.6.2  bouyer # "mantissa" is all zero which means that the answer is zero. but, the '040
   21012  1.1.6.2  bouyer # algorithm allows the exponent to be non-zero. the 881/2 do not. therefore,
   21013  1.1.6.2  bouyer # if the mantissa is zero, I will zero the exponent, too.
   21014  1.1.6.2  bouyer # the question now is whether the exponents sign bit is allowed to be non-zero
   21015  1.1.6.2  bouyer # for a zero, also...
   21016  1.1.6.2  bouyer 	andi.w		&0xf000,FP_SCR0(%a6)
   21017  1.1.6.2  bouyer 
   21018  1.1.6.2  bouyer fout_pack_set:
   21019  1.1.6.2  bouyer 
   21020  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0	# pass: src addr
   21021  1.1.6.2  bouyer 
   21022  1.1.6.2  bouyer fout_pack_write:
   21023  1.1.6.2  bouyer 	mov.l		(%sp)+,%a1		# pass: dst addr
   21024  1.1.6.2  bouyer 	mov.l		&0xc,%d0		# pass: opsize is 12 bytes
   21025  1.1.6.2  bouyer 
   21026  1.1.6.2  bouyer 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
   21027  1.1.6.2  bouyer 	beq.b		fout_pack_a7
   21028  1.1.6.2  bouyer 
   21029  1.1.6.2  bouyer 	bsr.l		_dmem_write		# write ext prec number to memory
   21030  1.1.6.2  bouyer 
   21031  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   21032  1.1.6.2  bouyer 	bne.w		fout_ext_err		# yes
   21033  1.1.6.2  bouyer 
   21034  1.1.6.2  bouyer 	rts
   21035  1.1.6.2  bouyer 
   21036  1.1.6.2  bouyer # we don't want to do the write if the exception occurred in supervisor mode
   21037  1.1.6.2  bouyer # so _mem_write2() handles this for us.
   21038  1.1.6.2  bouyer fout_pack_a7:
   21039  1.1.6.2  bouyer 	bsr.l		_mem_write2		# write ext prec number to memory
   21040  1.1.6.2  bouyer 
   21041  1.1.6.2  bouyer 	tst.l		%d1			# did dstore fail?
   21042  1.1.6.2  bouyer 	bne.w		fout_ext_err		# yes
   21043  1.1.6.2  bouyer 
   21044  1.1.6.2  bouyer 	rts
   21045  1.1.6.2  bouyer 
   21046  1.1.6.2  bouyer fout_pack_not_norm:
   21047  1.1.6.2  bouyer 	cmpi.b		%d0,&DENORM		# is it a DENORM?
   21048  1.1.6.2  bouyer 	beq.w		fout_pack_norm		# yes
   21049  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0
   21050  1.1.6.2  bouyer 	clr.w		2+FP_SRC_EX(%a6)
   21051  1.1.6.2  bouyer 	cmpi.b		%d0,&SNAN		# is it an SNAN?
   21052  1.1.6.2  bouyer 	beq.b		fout_pack_snan		# yes
   21053  1.1.6.2  bouyer 	bra.b		fout_pack_write		# no
   21054  1.1.6.2  bouyer 
   21055  1.1.6.2  bouyer fout_pack_snan:
   21056  1.1.6.2  bouyer 	ori.w		&snaniop2_mask,FPSR_EXCEPT(%a6) # set SNAN/AIOP
   21057  1.1.6.2  bouyer 	bset		&0x6,FP_SRC_HI(%a6)	# set snan bit
   21058  1.1.6.2  bouyer 	bra.b		fout_pack_write
   21059  1.1.6.2  bouyer 
   21060  1.1.6.2  bouyer #########################################################################
   21061  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21062  1.1.6.2  bouyer #	fetch_dreg(): fetch register according to index in d1		#
   21063  1.1.6.2  bouyer #									#
   21064  1.1.6.2  bouyer # XREF ****************************************************************	#
   21065  1.1.6.2  bouyer #	None								#
   21066  1.1.6.2  bouyer #									#
   21067  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21068  1.1.6.2  bouyer #	d1 = index of register to fetch from				#
   21069  1.1.6.2  bouyer # 									#
   21070  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21071  1.1.6.2  bouyer #	d0 = value of register fetched					#
   21072  1.1.6.2  bouyer #									#
   21073  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21074  1.1.6.2  bouyer #	According to the index value in d1 which can range from zero 	#
   21075  1.1.6.2  bouyer # to fifteen, load the corresponding register file value (where 	#
   21076  1.1.6.2  bouyer # address register indexes start at 8). D0/D1/A0/A1/A6/A7 are on the	#
   21077  1.1.6.2  bouyer # stack. The rest should still be in their original places.		#
   21078  1.1.6.2  bouyer #									#
   21079  1.1.6.2  bouyer #########################################################################
   21080  1.1.6.2  bouyer 
   21081  1.1.6.2  bouyer # this routine leaves d1 intact for subsequent store_dreg calls.
   21082  1.1.6.2  bouyer 	global		fetch_dreg
   21083  1.1.6.2  bouyer fetch_dreg:
   21084  1.1.6.2  bouyer 	mov.w		(tbl_fdreg.b,%pc,%d1.w*2),%d0
   21085  1.1.6.2  bouyer 	jmp		(tbl_fdreg.b,%pc,%d0.w*1)
   21086  1.1.6.2  bouyer 
   21087  1.1.6.2  bouyer tbl_fdreg:
   21088  1.1.6.2  bouyer 	short		fdreg0 - tbl_fdreg
   21089  1.1.6.2  bouyer 	short		fdreg1 - tbl_fdreg
   21090  1.1.6.2  bouyer 	short		fdreg2 - tbl_fdreg
   21091  1.1.6.2  bouyer 	short		fdreg3 - tbl_fdreg
   21092  1.1.6.2  bouyer 	short		fdreg4 - tbl_fdreg
   21093  1.1.6.2  bouyer 	short		fdreg5 - tbl_fdreg
   21094  1.1.6.2  bouyer 	short		fdreg6 - tbl_fdreg
   21095  1.1.6.2  bouyer 	short		fdreg7 - tbl_fdreg
   21096  1.1.6.2  bouyer 	short		fdreg8 - tbl_fdreg
   21097  1.1.6.2  bouyer 	short		fdreg9 - tbl_fdreg
   21098  1.1.6.2  bouyer 	short		fdrega - tbl_fdreg
   21099  1.1.6.2  bouyer 	short		fdregb - tbl_fdreg
   21100  1.1.6.2  bouyer 	short		fdregc - tbl_fdreg
   21101  1.1.6.2  bouyer 	short		fdregd - tbl_fdreg
   21102  1.1.6.2  bouyer 	short		fdrege - tbl_fdreg
   21103  1.1.6.2  bouyer 	short		fdregf - tbl_fdreg
   21104  1.1.6.2  bouyer 
   21105  1.1.6.2  bouyer fdreg0:
   21106  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0x0(%a6),%d0
   21107  1.1.6.2  bouyer 	rts
   21108  1.1.6.2  bouyer fdreg1:
   21109  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0x4(%a6),%d0
   21110  1.1.6.2  bouyer 	rts
   21111  1.1.6.2  bouyer fdreg2:
   21112  1.1.6.2  bouyer 	mov.l		%d2,%d0
   21113  1.1.6.2  bouyer 	rts
   21114  1.1.6.2  bouyer fdreg3:
   21115  1.1.6.2  bouyer 	mov.l		%d3,%d0
   21116  1.1.6.2  bouyer 	rts
   21117  1.1.6.2  bouyer fdreg4:
   21118  1.1.6.2  bouyer 	mov.l		%d4,%d0
   21119  1.1.6.2  bouyer 	rts
   21120  1.1.6.2  bouyer fdreg5:
   21121  1.1.6.2  bouyer 	mov.l		%d5,%d0
   21122  1.1.6.2  bouyer 	rts
   21123  1.1.6.2  bouyer fdreg6:
   21124  1.1.6.2  bouyer 	mov.l		%d6,%d0
   21125  1.1.6.2  bouyer 	rts
   21126  1.1.6.2  bouyer fdreg7:
   21127  1.1.6.2  bouyer 	mov.l		%d7,%d0
   21128  1.1.6.2  bouyer 	rts
   21129  1.1.6.2  bouyer fdreg8:
   21130  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0x8(%a6),%d0
   21131  1.1.6.2  bouyer 	rts
   21132  1.1.6.2  bouyer fdreg9:
   21133  1.1.6.2  bouyer 	mov.l		EXC_DREGS+0xc(%a6),%d0
   21134  1.1.6.2  bouyer 	rts
   21135  1.1.6.2  bouyer fdrega:
   21136  1.1.6.2  bouyer 	mov.l		%a2,%d0
   21137  1.1.6.2  bouyer 	rts
   21138  1.1.6.2  bouyer fdregb:
   21139  1.1.6.2  bouyer 	mov.l		%a3,%d0
   21140  1.1.6.2  bouyer 	rts
   21141  1.1.6.2  bouyer fdregc:
   21142  1.1.6.2  bouyer 	mov.l		%a4,%d0
   21143  1.1.6.2  bouyer 	rts
   21144  1.1.6.2  bouyer fdregd:
   21145  1.1.6.2  bouyer 	mov.l		%a5,%d0
   21146  1.1.6.2  bouyer 	rts
   21147  1.1.6.2  bouyer fdrege:
   21148  1.1.6.2  bouyer 	mov.l		(%a6),%d0
   21149  1.1.6.2  bouyer 	rts
   21150  1.1.6.2  bouyer fdregf:
   21151  1.1.6.2  bouyer 	mov.l		EXC_A7(%a6),%d0
   21152  1.1.6.2  bouyer 	rts
   21153  1.1.6.2  bouyer 
   21154  1.1.6.2  bouyer #########################################################################
   21155  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21156  1.1.6.2  bouyer #	store_dreg_l(): store longword to data register specified by d1	#
   21157  1.1.6.2  bouyer #									#
   21158  1.1.6.2  bouyer # XREF ****************************************************************	#
   21159  1.1.6.2  bouyer #	None								#
   21160  1.1.6.2  bouyer #									#
   21161  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21162  1.1.6.2  bouyer #	d0 = longowrd value to store					#
   21163  1.1.6.2  bouyer #	d1 = index of register to fetch from				#
   21164  1.1.6.2  bouyer # 									#
   21165  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21166  1.1.6.2  bouyer #	(data register is updated)					#
   21167  1.1.6.2  bouyer #									#
   21168  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21169  1.1.6.2  bouyer #	According to the index value in d1, store the longword value	#
   21170  1.1.6.2  bouyer # in d0 to the corresponding data register. D0/D1 are on the stack	#
   21171  1.1.6.2  bouyer # while the rest are in their initial places.				#
   21172  1.1.6.2  bouyer #									#
   21173  1.1.6.2  bouyer #########################################################################
   21174  1.1.6.2  bouyer 
   21175  1.1.6.2  bouyer 	global		store_dreg_l
   21176  1.1.6.2  bouyer store_dreg_l:
   21177  1.1.6.2  bouyer 	mov.w		(tbl_sdregl.b,%pc,%d1.w*2),%d1
   21178  1.1.6.2  bouyer 	jmp		(tbl_sdregl.b,%pc,%d1.w*1)
   21179  1.1.6.2  bouyer 
   21180  1.1.6.2  bouyer tbl_sdregl:
   21181  1.1.6.2  bouyer 	short		sdregl0 - tbl_sdregl
   21182  1.1.6.2  bouyer 	short		sdregl1 - tbl_sdregl
   21183  1.1.6.2  bouyer 	short		sdregl2 - tbl_sdregl
   21184  1.1.6.2  bouyer 	short		sdregl3 - tbl_sdregl
   21185  1.1.6.2  bouyer 	short		sdregl4 - tbl_sdregl
   21186  1.1.6.2  bouyer 	short		sdregl5 - tbl_sdregl
   21187  1.1.6.2  bouyer 	short		sdregl6 - tbl_sdregl
   21188  1.1.6.2  bouyer 	short		sdregl7 - tbl_sdregl
   21189  1.1.6.2  bouyer 
   21190  1.1.6.2  bouyer sdregl0:
   21191  1.1.6.2  bouyer 	mov.l		%d0,EXC_DREGS+0x0(%a6)
   21192  1.1.6.2  bouyer 	rts
   21193  1.1.6.2  bouyer sdregl1:
   21194  1.1.6.2  bouyer 	mov.l		%d0,EXC_DREGS+0x4(%a6)
   21195  1.1.6.2  bouyer 	rts
   21196  1.1.6.2  bouyer sdregl2:
   21197  1.1.6.2  bouyer 	mov.l		%d0,%d2
   21198  1.1.6.2  bouyer 	rts
   21199  1.1.6.2  bouyer sdregl3:
   21200  1.1.6.2  bouyer 	mov.l		%d0,%d3
   21201  1.1.6.2  bouyer 	rts
   21202  1.1.6.2  bouyer sdregl4:
   21203  1.1.6.2  bouyer 	mov.l		%d0,%d4
   21204  1.1.6.2  bouyer 	rts
   21205  1.1.6.2  bouyer sdregl5:
   21206  1.1.6.2  bouyer 	mov.l		%d0,%d5
   21207  1.1.6.2  bouyer 	rts
   21208  1.1.6.2  bouyer sdregl6:
   21209  1.1.6.2  bouyer 	mov.l		%d0,%d6
   21210  1.1.6.2  bouyer 	rts
   21211  1.1.6.2  bouyer sdregl7:
   21212  1.1.6.2  bouyer 	mov.l		%d0,%d7
   21213  1.1.6.2  bouyer 	rts
   21214  1.1.6.2  bouyer 
   21215  1.1.6.2  bouyer #########################################################################
   21216  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21217  1.1.6.2  bouyer #	store_dreg_w(): store word to data register specified by d1	#
   21218  1.1.6.2  bouyer #									#
   21219  1.1.6.2  bouyer # XREF ****************************************************************	#
   21220  1.1.6.2  bouyer #	None								#
   21221  1.1.6.2  bouyer #									#
   21222  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21223  1.1.6.2  bouyer #	d0 = word value to store					#
   21224  1.1.6.2  bouyer #	d1 = index of register to fetch from				#
   21225  1.1.6.2  bouyer # 									#
   21226  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21227  1.1.6.2  bouyer #	(data register is updated)					#
   21228  1.1.6.2  bouyer #									#
   21229  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21230  1.1.6.2  bouyer #	According to the index value in d1, store the word value	#
   21231  1.1.6.2  bouyer # in d0 to the corresponding data register. D0/D1 are on the stack	#
   21232  1.1.6.2  bouyer # while the rest are in their initial places.				#
   21233  1.1.6.2  bouyer #									#
   21234  1.1.6.2  bouyer #########################################################################
   21235  1.1.6.2  bouyer 
   21236  1.1.6.2  bouyer 	global		store_dreg_w
   21237  1.1.6.2  bouyer store_dreg_w:
   21238  1.1.6.2  bouyer 	mov.w		(tbl_sdregw.b,%pc,%d1.w*2),%d1
   21239  1.1.6.2  bouyer 	jmp		(tbl_sdregw.b,%pc,%d1.w*1)
   21240  1.1.6.2  bouyer 
   21241  1.1.6.2  bouyer tbl_sdregw:
   21242  1.1.6.2  bouyer 	short		sdregw0 - tbl_sdregw
   21243  1.1.6.2  bouyer 	short		sdregw1 - tbl_sdregw
   21244  1.1.6.2  bouyer 	short		sdregw2 - tbl_sdregw
   21245  1.1.6.2  bouyer 	short		sdregw3 - tbl_sdregw
   21246  1.1.6.2  bouyer 	short		sdregw4 - tbl_sdregw
   21247  1.1.6.2  bouyer 	short		sdregw5 - tbl_sdregw
   21248  1.1.6.2  bouyer 	short		sdregw6 - tbl_sdregw
   21249  1.1.6.2  bouyer 	short		sdregw7 - tbl_sdregw
   21250  1.1.6.2  bouyer 
   21251  1.1.6.2  bouyer sdregw0:
   21252  1.1.6.2  bouyer 	mov.w		%d0,2+EXC_DREGS+0x0(%a6)
   21253  1.1.6.2  bouyer 	rts
   21254  1.1.6.2  bouyer sdregw1:
   21255  1.1.6.2  bouyer 	mov.w		%d0,2+EXC_DREGS+0x4(%a6)
   21256  1.1.6.2  bouyer 	rts
   21257  1.1.6.2  bouyer sdregw2:
   21258  1.1.6.2  bouyer 	mov.w		%d0,%d2
   21259  1.1.6.2  bouyer 	rts
   21260  1.1.6.2  bouyer sdregw3:
   21261  1.1.6.2  bouyer 	mov.w		%d0,%d3
   21262  1.1.6.2  bouyer 	rts
   21263  1.1.6.2  bouyer sdregw4:
   21264  1.1.6.2  bouyer 	mov.w		%d0,%d4
   21265  1.1.6.2  bouyer 	rts
   21266  1.1.6.2  bouyer sdregw5:
   21267  1.1.6.2  bouyer 	mov.w		%d0,%d5
   21268  1.1.6.2  bouyer 	rts
   21269  1.1.6.2  bouyer sdregw6:
   21270  1.1.6.2  bouyer 	mov.w		%d0,%d6
   21271  1.1.6.2  bouyer 	rts
   21272  1.1.6.2  bouyer sdregw7:
   21273  1.1.6.2  bouyer 	mov.w		%d0,%d7
   21274  1.1.6.2  bouyer 	rts
   21275  1.1.6.2  bouyer 
   21276  1.1.6.2  bouyer #########################################################################
   21277  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21278  1.1.6.2  bouyer #	store_dreg_b(): store byte to data register specified by d1	#
   21279  1.1.6.2  bouyer #									#
   21280  1.1.6.2  bouyer # XREF ****************************************************************	#
   21281  1.1.6.2  bouyer #	None								#
   21282  1.1.6.2  bouyer #									#
   21283  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21284  1.1.6.2  bouyer #	d0 = byte value to store					#
   21285  1.1.6.2  bouyer #	d1 = index of register to fetch from				#
   21286  1.1.6.2  bouyer # 									#
   21287  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21288  1.1.6.2  bouyer #	(data register is updated)					#
   21289  1.1.6.2  bouyer #									#
   21290  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21291  1.1.6.2  bouyer #	According to the index value in d1, store the byte value	#
   21292  1.1.6.2  bouyer # in d0 to the corresponding data register. D0/D1 are on the stack	#
   21293  1.1.6.2  bouyer # while the rest are in their initial places.				#
   21294  1.1.6.2  bouyer #									#
   21295  1.1.6.2  bouyer #########################################################################
   21296  1.1.6.2  bouyer 
   21297  1.1.6.2  bouyer 	global		store_dreg_b
   21298  1.1.6.2  bouyer store_dreg_b:
   21299  1.1.6.2  bouyer 	mov.w		(tbl_sdregb.b,%pc,%d1.w*2),%d1
   21300  1.1.6.2  bouyer 	jmp		(tbl_sdregb.b,%pc,%d1.w*1)
   21301  1.1.6.2  bouyer 
   21302  1.1.6.2  bouyer tbl_sdregb:
   21303  1.1.6.2  bouyer 	short		sdregb0 - tbl_sdregb
   21304  1.1.6.2  bouyer 	short		sdregb1 - tbl_sdregb
   21305  1.1.6.2  bouyer 	short		sdregb2 - tbl_sdregb
   21306  1.1.6.2  bouyer 	short		sdregb3 - tbl_sdregb
   21307  1.1.6.2  bouyer 	short		sdregb4 - tbl_sdregb
   21308  1.1.6.2  bouyer 	short		sdregb5 - tbl_sdregb
   21309  1.1.6.2  bouyer 	short		sdregb6 - tbl_sdregb
   21310  1.1.6.2  bouyer 	short		sdregb7 - tbl_sdregb
   21311  1.1.6.2  bouyer 
   21312  1.1.6.2  bouyer sdregb0:
   21313  1.1.6.2  bouyer 	mov.b		%d0,3+EXC_DREGS+0x0(%a6)
   21314  1.1.6.2  bouyer 	rts
   21315  1.1.6.2  bouyer sdregb1:
   21316  1.1.6.2  bouyer 	mov.b		%d0,3+EXC_DREGS+0x4(%a6)
   21317  1.1.6.2  bouyer 	rts
   21318  1.1.6.2  bouyer sdregb2:
   21319  1.1.6.2  bouyer 	mov.b		%d0,%d2
   21320  1.1.6.2  bouyer 	rts
   21321  1.1.6.2  bouyer sdregb3:
   21322  1.1.6.2  bouyer 	mov.b		%d0,%d3
   21323  1.1.6.2  bouyer 	rts
   21324  1.1.6.2  bouyer sdregb4:
   21325  1.1.6.2  bouyer 	mov.b		%d0,%d4
   21326  1.1.6.2  bouyer 	rts
   21327  1.1.6.2  bouyer sdregb5:
   21328  1.1.6.2  bouyer 	mov.b		%d0,%d5
   21329  1.1.6.2  bouyer 	rts
   21330  1.1.6.2  bouyer sdregb6:
   21331  1.1.6.2  bouyer 	mov.b		%d0,%d6
   21332  1.1.6.2  bouyer 	rts
   21333  1.1.6.2  bouyer sdregb7:
   21334  1.1.6.2  bouyer 	mov.b		%d0,%d7
   21335  1.1.6.2  bouyer 	rts
   21336  1.1.6.2  bouyer 
   21337  1.1.6.2  bouyer #########################################################################
   21338  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21339  1.1.6.2  bouyer #	inc_areg(): increment an address register by the value in d0	#
   21340  1.1.6.2  bouyer #									#
   21341  1.1.6.2  bouyer # XREF ****************************************************************	#
   21342  1.1.6.2  bouyer #	None								#
   21343  1.1.6.2  bouyer #									#
   21344  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21345  1.1.6.2  bouyer #	d0 = amount to increment by					#
   21346  1.1.6.2  bouyer #	d1 = index of address register to increment			#
   21347  1.1.6.2  bouyer # 									#
   21348  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21349  1.1.6.2  bouyer #	(address register is updated)					#
   21350  1.1.6.2  bouyer #									#
   21351  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21352  1.1.6.2  bouyer # 	Typically used for an instruction w/ a post-increment <ea>, 	#
   21353  1.1.6.2  bouyer # this routine adds the increment value in d0 to the address register	#
   21354  1.1.6.2  bouyer # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside	#
   21355  1.1.6.2  bouyer # in their original places.						#
   21356  1.1.6.2  bouyer # 	For a7, if the increment amount is one, then we have to 	#
   21357  1.1.6.2  bouyer # increment by two. For any a7 update, set the mia7_flag so that if	#
   21358  1.1.6.2  bouyer # an access error exception occurs later in emulation, this address	#
   21359  1.1.6.2  bouyer # register update can be undone.					#
   21360  1.1.6.2  bouyer #									#
   21361  1.1.6.2  bouyer #########################################################################
   21362  1.1.6.2  bouyer 
   21363  1.1.6.2  bouyer 	global		inc_areg
   21364  1.1.6.2  bouyer inc_areg:
   21365  1.1.6.2  bouyer 	mov.w		(tbl_iareg.b,%pc,%d1.w*2),%d1
   21366  1.1.6.2  bouyer 	jmp		(tbl_iareg.b,%pc,%d1.w*1)
   21367  1.1.6.2  bouyer 
   21368  1.1.6.2  bouyer tbl_iareg:
   21369  1.1.6.2  bouyer 	short		iareg0 - tbl_iareg
   21370  1.1.6.2  bouyer 	short		iareg1 - tbl_iareg
   21371  1.1.6.2  bouyer 	short		iareg2 - tbl_iareg
   21372  1.1.6.2  bouyer 	short		iareg3 - tbl_iareg
   21373  1.1.6.2  bouyer 	short		iareg4 - tbl_iareg
   21374  1.1.6.2  bouyer 	short		iareg5 - tbl_iareg
   21375  1.1.6.2  bouyer 	short		iareg6 - tbl_iareg
   21376  1.1.6.2  bouyer 	short		iareg7 - tbl_iareg
   21377  1.1.6.2  bouyer 
   21378  1.1.6.2  bouyer iareg0:	add.l		%d0,EXC_DREGS+0x8(%a6)
   21379  1.1.6.2  bouyer 	rts
   21380  1.1.6.2  bouyer iareg1:	add.l		%d0,EXC_DREGS+0xc(%a6)
   21381  1.1.6.2  bouyer 	rts
   21382  1.1.6.2  bouyer iareg2:	add.l		%d0,%a2
   21383  1.1.6.2  bouyer 	rts
   21384  1.1.6.2  bouyer iareg3:	add.l		%d0,%a3
   21385  1.1.6.2  bouyer 	rts
   21386  1.1.6.2  bouyer iareg4:	add.l		%d0,%a4
   21387  1.1.6.2  bouyer 	rts
   21388  1.1.6.2  bouyer iareg5:	add.l		%d0,%a5
   21389  1.1.6.2  bouyer 	rts
   21390  1.1.6.2  bouyer iareg6:	add.l		%d0,(%a6)
   21391  1.1.6.2  bouyer 	rts
   21392  1.1.6.2  bouyer iareg7:	mov.b		&mia7_flg,SPCOND_FLG(%a6)
   21393  1.1.6.2  bouyer 	cmpi.b		%d0,&0x1
   21394  1.1.6.2  bouyer 	beq.b		iareg7b
   21395  1.1.6.2  bouyer 	add.l		%d0,EXC_A7(%a6)
   21396  1.1.6.2  bouyer 	rts
   21397  1.1.6.2  bouyer iareg7b:
   21398  1.1.6.2  bouyer 	addq.l		&0x2,EXC_A7(%a6)
   21399  1.1.6.2  bouyer 	rts
   21400  1.1.6.2  bouyer 
   21401  1.1.6.2  bouyer #########################################################################
   21402  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21403  1.1.6.2  bouyer #	dec_areg(): decrement an address register by the value in d0	#
   21404  1.1.6.2  bouyer #									#
   21405  1.1.6.2  bouyer # XREF ****************************************************************	#
   21406  1.1.6.2  bouyer #	None								#
   21407  1.1.6.2  bouyer #									#
   21408  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21409  1.1.6.2  bouyer #	d0 = amount to decrement by					#
   21410  1.1.6.2  bouyer #	d1 = index of address register to decrement			#
   21411  1.1.6.2  bouyer # 									#
   21412  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21413  1.1.6.2  bouyer #	(address register is updated)					#
   21414  1.1.6.2  bouyer #									#
   21415  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21416  1.1.6.2  bouyer # 	Typically used for an instruction w/ a pre-decrement <ea>, 	#
   21417  1.1.6.2  bouyer # this routine adds the decrement value in d0 to the address register	#
   21418  1.1.6.2  bouyer # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside	#
   21419  1.1.6.2  bouyer # in their original places.						#
   21420  1.1.6.2  bouyer # 	For a7, if the decrement amount is one, then we have to 	#
   21421  1.1.6.2  bouyer # decrement by two. For any a7 update, set the mda7_flag so that if	#
   21422  1.1.6.2  bouyer # an access error exception occurs later in emulation, this address	#
   21423  1.1.6.2  bouyer # register update can be undone.					#
   21424  1.1.6.2  bouyer #									#
   21425  1.1.6.2  bouyer #########################################################################
   21426  1.1.6.2  bouyer 
   21427  1.1.6.2  bouyer 	global		dec_areg
   21428  1.1.6.2  bouyer dec_areg:
   21429  1.1.6.2  bouyer 	mov.w		(tbl_dareg.b,%pc,%d1.w*2),%d1
   21430  1.1.6.2  bouyer 	jmp		(tbl_dareg.b,%pc,%d1.w*1)
   21431  1.1.6.2  bouyer 
   21432  1.1.6.2  bouyer tbl_dareg:
   21433  1.1.6.2  bouyer 	short		dareg0 - tbl_dareg
   21434  1.1.6.2  bouyer 	short		dareg1 - tbl_dareg
   21435  1.1.6.2  bouyer 	short		dareg2 - tbl_dareg
   21436  1.1.6.2  bouyer 	short		dareg3 - tbl_dareg
   21437  1.1.6.2  bouyer 	short		dareg4 - tbl_dareg
   21438  1.1.6.2  bouyer 	short		dareg5 - tbl_dareg
   21439  1.1.6.2  bouyer 	short		dareg6 - tbl_dareg
   21440  1.1.6.2  bouyer 	short		dareg7 - tbl_dareg
   21441  1.1.6.2  bouyer 
   21442  1.1.6.2  bouyer dareg0:	sub.l		%d0,EXC_DREGS+0x8(%a6)
   21443  1.1.6.2  bouyer 	rts
   21444  1.1.6.2  bouyer dareg1:	sub.l		%d0,EXC_DREGS+0xc(%a6)
   21445  1.1.6.2  bouyer 	rts
   21446  1.1.6.2  bouyer dareg2:	sub.l		%d0,%a2
   21447  1.1.6.2  bouyer 	rts
   21448  1.1.6.2  bouyer dareg3:	sub.l		%d0,%a3
   21449  1.1.6.2  bouyer 	rts
   21450  1.1.6.2  bouyer dareg4:	sub.l		%d0,%a4
   21451  1.1.6.2  bouyer 	rts
   21452  1.1.6.2  bouyer dareg5:	sub.l		%d0,%a5
   21453  1.1.6.2  bouyer 	rts
   21454  1.1.6.2  bouyer dareg6:	sub.l		%d0,(%a6)
   21455  1.1.6.2  bouyer 	rts
   21456  1.1.6.2  bouyer dareg7:	mov.b		&mda7_flg,SPCOND_FLG(%a6)
   21457  1.1.6.2  bouyer 	cmpi.b		%d0,&0x1
   21458  1.1.6.2  bouyer 	beq.b		dareg7b
   21459  1.1.6.2  bouyer 	sub.l		%d0,EXC_A7(%a6)
   21460  1.1.6.2  bouyer 	rts
   21461  1.1.6.2  bouyer dareg7b:
   21462  1.1.6.2  bouyer 	subq.l		&0x2,EXC_A7(%a6)
   21463  1.1.6.2  bouyer 	rts
   21464  1.1.6.2  bouyer 
   21465  1.1.6.2  bouyer ##############################################################################
   21466  1.1.6.2  bouyer 
   21467  1.1.6.2  bouyer #########################################################################
   21468  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21469  1.1.6.2  bouyer #	load_fpn1(): load FP register value into FP_SRC(a6).		#
   21470  1.1.6.2  bouyer #									#
   21471  1.1.6.2  bouyer # XREF ****************************************************************	#
   21472  1.1.6.2  bouyer #	None								#
   21473  1.1.6.2  bouyer #									#
   21474  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21475  1.1.6.2  bouyer #	d0 = index of FP register to load				#
   21476  1.1.6.2  bouyer # 									#
   21477  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21478  1.1.6.2  bouyer #	FP_SRC(a6) = value loaded from FP register file			#
   21479  1.1.6.2  bouyer #									#
   21480  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21481  1.1.6.2  bouyer #	Using the index in d0, load FP_SRC(a6) with a number from the 	#
   21482  1.1.6.2  bouyer # FP register file.							#
   21483  1.1.6.2  bouyer #									#
   21484  1.1.6.2  bouyer #########################################################################
   21485  1.1.6.2  bouyer 
   21486  1.1.6.2  bouyer 	global 		load_fpn1
   21487  1.1.6.2  bouyer load_fpn1:
   21488  1.1.6.2  bouyer 	mov.w		(tbl_load_fpn1.b,%pc,%d0.w*2), %d0
   21489  1.1.6.2  bouyer 	jmp		(tbl_load_fpn1.b,%pc,%d0.w*1)
   21490  1.1.6.2  bouyer 
   21491  1.1.6.2  bouyer tbl_load_fpn1:
   21492  1.1.6.2  bouyer 	short		load_fpn1_0 - tbl_load_fpn1
   21493  1.1.6.2  bouyer 	short		load_fpn1_1 - tbl_load_fpn1
   21494  1.1.6.2  bouyer 	short		load_fpn1_2 - tbl_load_fpn1
   21495  1.1.6.2  bouyer 	short		load_fpn1_3 - tbl_load_fpn1
   21496  1.1.6.2  bouyer 	short		load_fpn1_4 - tbl_load_fpn1
   21497  1.1.6.2  bouyer 	short		load_fpn1_5 - tbl_load_fpn1
   21498  1.1.6.2  bouyer 	short		load_fpn1_6 - tbl_load_fpn1
   21499  1.1.6.2  bouyer 	short		load_fpn1_7 - tbl_load_fpn1
   21500  1.1.6.2  bouyer 
   21501  1.1.6.2  bouyer load_fpn1_0:
   21502  1.1.6.2  bouyer 	mov.l		0+EXC_FP0(%a6), 0+FP_SRC(%a6)
   21503  1.1.6.2  bouyer 	mov.l		4+EXC_FP0(%a6), 4+FP_SRC(%a6)
   21504  1.1.6.2  bouyer 	mov.l		8+EXC_FP0(%a6), 8+FP_SRC(%a6)
   21505  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21506  1.1.6.2  bouyer 	rts
   21507  1.1.6.2  bouyer load_fpn1_1:
   21508  1.1.6.2  bouyer 	mov.l		0+EXC_FP1(%a6), 0+FP_SRC(%a6)
   21509  1.1.6.2  bouyer 	mov.l		4+EXC_FP1(%a6), 4+FP_SRC(%a6)
   21510  1.1.6.2  bouyer 	mov.l		8+EXC_FP1(%a6), 8+FP_SRC(%a6)
   21511  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21512  1.1.6.2  bouyer 	rts
   21513  1.1.6.2  bouyer load_fpn1_2:
   21514  1.1.6.2  bouyer 	fmovm.x		&0x20, FP_SRC(%a6)
   21515  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21516  1.1.6.2  bouyer 	rts
   21517  1.1.6.2  bouyer load_fpn1_3:
   21518  1.1.6.2  bouyer 	fmovm.x		&0x10, FP_SRC(%a6)
   21519  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21520  1.1.6.2  bouyer 	rts
   21521  1.1.6.2  bouyer load_fpn1_4:
   21522  1.1.6.2  bouyer 	fmovm.x		&0x08, FP_SRC(%a6)
   21523  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21524  1.1.6.2  bouyer 	rts
   21525  1.1.6.2  bouyer load_fpn1_5:
   21526  1.1.6.2  bouyer 	fmovm.x		&0x04, FP_SRC(%a6)
   21527  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21528  1.1.6.2  bouyer 	rts
   21529  1.1.6.2  bouyer load_fpn1_6:
   21530  1.1.6.2  bouyer 	fmovm.x		&0x02, FP_SRC(%a6)
   21531  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21532  1.1.6.2  bouyer 	rts
   21533  1.1.6.2  bouyer load_fpn1_7:
   21534  1.1.6.2  bouyer 	fmovm.x		&0x01, FP_SRC(%a6)
   21535  1.1.6.2  bouyer 	lea		FP_SRC(%a6), %a0
   21536  1.1.6.2  bouyer 	rts
   21537  1.1.6.2  bouyer 
   21538  1.1.6.2  bouyer #############################################################################
   21539  1.1.6.2  bouyer 
   21540  1.1.6.2  bouyer #########################################################################
   21541  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21542  1.1.6.2  bouyer #	load_fpn2(): load FP register value into FP_DST(a6).		#
   21543  1.1.6.2  bouyer #									#
   21544  1.1.6.2  bouyer # XREF ****************************************************************	#
   21545  1.1.6.2  bouyer #	None								#
   21546  1.1.6.2  bouyer #									#
   21547  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21548  1.1.6.2  bouyer #	d0 = index of FP register to load				#
   21549  1.1.6.2  bouyer # 									#
   21550  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21551  1.1.6.2  bouyer #	FP_DST(a6) = value loaded from FP register file			#
   21552  1.1.6.2  bouyer #									#
   21553  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21554  1.1.6.2  bouyer #	Using the index in d0, load FP_DST(a6) with a number from the 	#
   21555  1.1.6.2  bouyer # FP register file.							#
   21556  1.1.6.2  bouyer #									#
   21557  1.1.6.2  bouyer #########################################################################
   21558  1.1.6.2  bouyer 
   21559  1.1.6.2  bouyer 	global		load_fpn2
   21560  1.1.6.2  bouyer load_fpn2:
   21561  1.1.6.2  bouyer 	mov.w		(tbl_load_fpn2.b,%pc,%d0.w*2), %d0
   21562  1.1.6.2  bouyer 	jmp		(tbl_load_fpn2.b,%pc,%d0.w*1)
   21563  1.1.6.2  bouyer 
   21564  1.1.6.2  bouyer tbl_load_fpn2:
   21565  1.1.6.2  bouyer 	short		load_fpn2_0 - tbl_load_fpn2
   21566  1.1.6.2  bouyer 	short		load_fpn2_1 - tbl_load_fpn2
   21567  1.1.6.2  bouyer 	short		load_fpn2_2 - tbl_load_fpn2
   21568  1.1.6.2  bouyer 	short		load_fpn2_3 - tbl_load_fpn2
   21569  1.1.6.2  bouyer 	short		load_fpn2_4 - tbl_load_fpn2
   21570  1.1.6.2  bouyer 	short		load_fpn2_5 - tbl_load_fpn2
   21571  1.1.6.2  bouyer 	short		load_fpn2_6 - tbl_load_fpn2
   21572  1.1.6.2  bouyer 	short		load_fpn2_7 - tbl_load_fpn2
   21573  1.1.6.2  bouyer 
   21574  1.1.6.2  bouyer load_fpn2_0:
   21575  1.1.6.2  bouyer 	mov.l		0+EXC_FP0(%a6), 0+FP_DST(%a6)
   21576  1.1.6.2  bouyer 	mov.l		4+EXC_FP0(%a6), 4+FP_DST(%a6)
   21577  1.1.6.2  bouyer 	mov.l		8+EXC_FP0(%a6), 8+FP_DST(%a6)
   21578  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21579  1.1.6.2  bouyer 	rts
   21580  1.1.6.2  bouyer load_fpn2_1:
   21581  1.1.6.2  bouyer 	mov.l		0+EXC_FP1(%a6), 0+FP_DST(%a6)
   21582  1.1.6.2  bouyer 	mov.l		4+EXC_FP1(%a6), 4+FP_DST(%a6)
   21583  1.1.6.2  bouyer 	mov.l		8+EXC_FP1(%a6), 8+FP_DST(%a6)
   21584  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21585  1.1.6.2  bouyer 	rts
   21586  1.1.6.2  bouyer load_fpn2_2:
   21587  1.1.6.2  bouyer 	fmovm.x		&0x20, FP_DST(%a6)
   21588  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21589  1.1.6.2  bouyer 	rts
   21590  1.1.6.2  bouyer load_fpn2_3:
   21591  1.1.6.2  bouyer 	fmovm.x		&0x10, FP_DST(%a6)
   21592  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21593  1.1.6.2  bouyer 	rts
   21594  1.1.6.2  bouyer load_fpn2_4:
   21595  1.1.6.2  bouyer 	fmovm.x		&0x08, FP_DST(%a6)
   21596  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21597  1.1.6.2  bouyer 	rts
   21598  1.1.6.2  bouyer load_fpn2_5:
   21599  1.1.6.2  bouyer 	fmovm.x		&0x04, FP_DST(%a6)
   21600  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21601  1.1.6.2  bouyer 	rts
   21602  1.1.6.2  bouyer load_fpn2_6:
   21603  1.1.6.2  bouyer 	fmovm.x		&0x02, FP_DST(%a6)
   21604  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21605  1.1.6.2  bouyer 	rts
   21606  1.1.6.2  bouyer load_fpn2_7:
   21607  1.1.6.2  bouyer 	fmovm.x		&0x01, FP_DST(%a6)
   21608  1.1.6.2  bouyer 	lea		FP_DST(%a6), %a0
   21609  1.1.6.2  bouyer 	rts
   21610  1.1.6.2  bouyer 
   21611  1.1.6.2  bouyer #############################################################################
   21612  1.1.6.2  bouyer 
   21613  1.1.6.2  bouyer #########################################################################
   21614  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21615  1.1.6.2  bouyer # 	store_fpreg(): store an fp value to the fpreg designated d0.	#
   21616  1.1.6.2  bouyer #									#
   21617  1.1.6.2  bouyer # XREF ****************************************************************	#
   21618  1.1.6.2  bouyer #	None								#
   21619  1.1.6.2  bouyer #									#
   21620  1.1.6.2  bouyer # INPUT ***************************************************************	#
   21621  1.1.6.2  bouyer #	fp0 = extended precision value to store				#
   21622  1.1.6.2  bouyer #	d0  = index of floating-point register				#
   21623  1.1.6.2  bouyer # 									#
   21624  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21625  1.1.6.2  bouyer #	None								#
   21626  1.1.6.2  bouyer #									#
   21627  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21628  1.1.6.2  bouyer #	Store the value in fp0 to the FP register designated by the	#
   21629  1.1.6.2  bouyer # value in d0. The FP number can be DENORM or SNAN so we have to be	#
   21630  1.1.6.2  bouyer # careful that we don't take an exception here.				#
   21631  1.1.6.2  bouyer #									#
   21632  1.1.6.2  bouyer #########################################################################
   21633  1.1.6.2  bouyer 
   21634  1.1.6.2  bouyer 	global		store_fpreg
   21635  1.1.6.2  bouyer store_fpreg:
   21636  1.1.6.2  bouyer 	mov.w		(tbl_store_fpreg.b,%pc,%d0.w*2), %d0
   21637  1.1.6.2  bouyer 	jmp		(tbl_store_fpreg.b,%pc,%d0.w*1)
   21638  1.1.6.2  bouyer 
   21639  1.1.6.2  bouyer tbl_store_fpreg:
   21640  1.1.6.2  bouyer 	short		store_fpreg_0 - tbl_store_fpreg
   21641  1.1.6.2  bouyer 	short		store_fpreg_1 - tbl_store_fpreg
   21642  1.1.6.2  bouyer 	short		store_fpreg_2 - tbl_store_fpreg
   21643  1.1.6.2  bouyer 	short		store_fpreg_3 - tbl_store_fpreg
   21644  1.1.6.2  bouyer 	short		store_fpreg_4 - tbl_store_fpreg
   21645  1.1.6.2  bouyer 	short		store_fpreg_5 - tbl_store_fpreg
   21646  1.1.6.2  bouyer 	short		store_fpreg_6 - tbl_store_fpreg
   21647  1.1.6.2  bouyer 	short		store_fpreg_7 - tbl_store_fpreg
   21648  1.1.6.2  bouyer 
   21649  1.1.6.2  bouyer store_fpreg_0:
   21650  1.1.6.2  bouyer 	fmovm.x		&0x80, EXC_FP0(%a6)
   21651  1.1.6.2  bouyer 	rts
   21652  1.1.6.2  bouyer store_fpreg_1:
   21653  1.1.6.2  bouyer 	fmovm.x		&0x80, EXC_FP1(%a6)
   21654  1.1.6.2  bouyer 	rts
   21655  1.1.6.2  bouyer store_fpreg_2:
   21656  1.1.6.2  bouyer 	fmovm.x 	&0x01, -(%sp)
   21657  1.1.6.2  bouyer 	fmovm.x		(%sp)+, &0x20
   21658  1.1.6.2  bouyer 	rts
   21659  1.1.6.2  bouyer store_fpreg_3:
   21660  1.1.6.2  bouyer 	fmovm.x 	&0x01, -(%sp)
   21661  1.1.6.2  bouyer 	fmovm.x		(%sp)+, &0x10
   21662  1.1.6.2  bouyer 	rts
   21663  1.1.6.2  bouyer store_fpreg_4:
   21664  1.1.6.2  bouyer 	fmovm.x 	&0x01, -(%sp)
   21665  1.1.6.2  bouyer 	fmovm.x		(%sp)+, &0x08
   21666  1.1.6.2  bouyer 	rts
   21667  1.1.6.2  bouyer store_fpreg_5:
   21668  1.1.6.2  bouyer 	fmovm.x 	&0x01, -(%sp)
   21669  1.1.6.2  bouyer 	fmovm.x		(%sp)+, &0x04
   21670  1.1.6.2  bouyer 	rts
   21671  1.1.6.2  bouyer store_fpreg_6:
   21672  1.1.6.2  bouyer 	fmovm.x 	&0x01, -(%sp)
   21673  1.1.6.2  bouyer 	fmovm.x		(%sp)+, &0x02
   21674  1.1.6.2  bouyer 	rts
   21675  1.1.6.2  bouyer store_fpreg_7:
   21676  1.1.6.2  bouyer 	fmovm.x 	&0x01, -(%sp)
   21677  1.1.6.2  bouyer 	fmovm.x		(%sp)+, &0x01
   21678  1.1.6.2  bouyer 	rts
   21679  1.1.6.2  bouyer 
   21680  1.1.6.2  bouyer #########################################################################
   21681  1.1.6.2  bouyer # XDEF ****************************************************************	#
   21682  1.1.6.2  bouyer # 	_denorm(): denormalize an intermediate result			#
   21683  1.1.6.2  bouyer #									#
   21684  1.1.6.2  bouyer # XREF ****************************************************************	#
   21685  1.1.6.2  bouyer #	None								#
   21686  1.1.6.2  bouyer #									#
   21687  1.1.6.2  bouyer # INPUT *************************************************************** #
   21688  1.1.6.2  bouyer #	a0 = points to the operand to be denormalized			#
   21689  1.1.6.2  bouyer #		(in the internal extended format)			#
   21690  1.1.6.2  bouyer #		 							#
   21691  1.1.6.2  bouyer #	d0 = rounding precision						#
   21692  1.1.6.2  bouyer #									#
   21693  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   21694  1.1.6.2  bouyer #	a0 = pointer to the denormalized result				#
   21695  1.1.6.2  bouyer #		(in the internal extended format)			#
   21696  1.1.6.2  bouyer #									#
   21697  1.1.6.2  bouyer #	d0 = guard,round,sticky						#
   21698  1.1.6.2  bouyer #									#
   21699  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   21700  1.1.6.2  bouyer # 	According to the exponent underflow threshold for the given	#
   21701  1.1.6.2  bouyer # precision, shift the mantissa bits to the right in order raise the	#
   21702  1.1.6.2  bouyer # exponent of the operand to the threshold value. While shifting the 	#
   21703  1.1.6.2  bouyer # mantissa bits right, maintain the value of the guard, round, and 	#
   21704  1.1.6.2  bouyer # sticky bits.								#
   21705  1.1.6.2  bouyer # other notes:								#
   21706  1.1.6.2  bouyer #	(1) _denorm() is called by the underflow routines		#
   21707  1.1.6.2  bouyer #	(2) _denorm() does NOT affect the status register		#
   21708  1.1.6.2  bouyer #									#
   21709  1.1.6.2  bouyer #########################################################################
   21710  1.1.6.2  bouyer 
   21711  1.1.6.2  bouyer #
   21712  1.1.6.2  bouyer # table of exponent threshold values for each precision
   21713  1.1.6.2  bouyer #
   21714  1.1.6.2  bouyer tbl_thresh:
   21715  1.1.6.2  bouyer 	short		0x0
   21716  1.1.6.2  bouyer 	short		sgl_thresh
   21717  1.1.6.2  bouyer 	short		dbl_thresh
   21718  1.1.6.2  bouyer 
   21719  1.1.6.2  bouyer 	global		_denorm
   21720  1.1.6.2  bouyer _denorm:
   21721  1.1.6.2  bouyer #
   21722  1.1.6.2  bouyer # Load the exponent threshold for the precision selected and check
   21723  1.1.6.2  bouyer # to see if (threshold - exponent) is > 65 in which case we can
   21724  1.1.6.2  bouyer # simply calculate the sticky bit and zero the mantissa. otherwise
   21725  1.1.6.2  bouyer # we have to call the denormalization routine.
   21726  1.1.6.2  bouyer #
   21727  1.1.6.2  bouyer 	lsr.b		&0x2, %d0		# shift prec to lo bits
   21728  1.1.6.2  bouyer 	mov.w		(tbl_thresh.b,%pc,%d0.w*2), %d1 # load prec threshold
   21729  1.1.6.2  bouyer 	mov.w		%d1, %d0		# copy d1 into d0
   21730  1.1.6.2  bouyer 	sub.w		FTEMP_EX(%a0), %d0	# diff = threshold - exp
   21731  1.1.6.2  bouyer 	cmpi.w		%d0, &66		# is diff > 65? (mant + g,r bits)
   21732  1.1.6.2  bouyer 	bpl.b		denorm_set_stky		# yes; just calc sticky
   21733  1.1.6.2  bouyer 
   21734  1.1.6.2  bouyer 	clr.l		%d0			# clear g,r,s
   21735  1.1.6.2  bouyer 	btst		&inex2_bit, FPSR_EXCEPT(%a6) # yes; was INEX2 set?
   21736  1.1.6.2  bouyer 	beq.b		denorm_call		# no; don't change anything
   21737  1.1.6.2  bouyer 	bset		&29, %d0		# yes; set sticky bit
   21738  1.1.6.2  bouyer 
   21739  1.1.6.2  bouyer denorm_call:
   21740  1.1.6.2  bouyer 	bsr.l		dnrm_lp			# denormalize the number
   21741  1.1.6.2  bouyer 	rts
   21742  1.1.6.2  bouyer 
   21743  1.1.6.2  bouyer #
   21744  1.1.6.2  bouyer # all bit would have been shifted off during the denorm so simply
   21745  1.1.6.2  bouyer # calculate if the sticky should be set and clear the entire mantissa.
   21746  1.1.6.2  bouyer #
   21747  1.1.6.2  bouyer denorm_set_stky:
   21748  1.1.6.2  bouyer 	mov.l		&0x20000000, %d0	# set sticky bit in return value
   21749  1.1.6.2  bouyer 	mov.w		%d1, FTEMP_EX(%a0)	# load exp with threshold
   21750  1.1.6.2  bouyer 	clr.l		FTEMP_HI(%a0)		# set d1 = 0 (ms mantissa)
   21751  1.1.6.2  bouyer 	clr.l		FTEMP_LO(%a0)		# set d2 = 0 (ms mantissa)
   21752  1.1.6.2  bouyer 	rts
   21753  1.1.6.2  bouyer 
   21754  1.1.6.2  bouyer #									#
   21755  1.1.6.2  bouyer # dnrm_lp(): normalize exponent/mantissa to specified threshhold	#
   21756  1.1.6.2  bouyer #									#
   21757  1.1.6.2  bouyer # INPUT:								#
   21758  1.1.6.2  bouyer #	%a0	   : points to the operand to be denormalized		#
   21759  1.1.6.2  bouyer #	%d0{31:29} : initial guard,round,sticky				#
   21760  1.1.6.2  bouyer #	%d1{15:0}  : denormalization threshold				#
   21761  1.1.6.2  bouyer # OUTPUT:								#
   21762  1.1.6.2  bouyer #	%a0	   : points to the denormalized operand		 	#
   21763  1.1.6.2  bouyer #	%d0{31:29} : final guard,round,sticky				#
   21764  1.1.6.2  bouyer #									#
   21765  1.1.6.2  bouyer 
   21766  1.1.6.2  bouyer # *** Local Equates *** #
   21767  1.1.6.2  bouyer set	GRS,		L_SCR2			# g,r,s temp storage
   21768  1.1.6.2  bouyer set	FTEMP_LO2,	L_SCR1			# FTEMP_LO copy
   21769  1.1.6.2  bouyer 
   21770  1.1.6.2  bouyer 	global		dnrm_lp
   21771  1.1.6.2  bouyer dnrm_lp:
   21772  1.1.6.2  bouyer 
   21773  1.1.6.2  bouyer #
   21774  1.1.6.2  bouyer # make a copy of FTEMP_LO and place the g,r,s bits directly after it
   21775  1.1.6.2  bouyer # in memory so as to make the bitfield extraction for denormalization easier.
   21776  1.1.6.2  bouyer #
   21777  1.1.6.2  bouyer 	mov.l		FTEMP_LO(%a0), FTEMP_LO2(%a6) # make FTEMP_LO copy
   21778  1.1.6.2  bouyer 	mov.l		%d0, GRS(%a6)		# place g,r,s after it
   21779  1.1.6.2  bouyer 
   21780  1.1.6.2  bouyer #
   21781  1.1.6.2  bouyer # check to see how much less than the underflow threshold the operand
   21782  1.1.6.2  bouyer # exponent is.
   21783  1.1.6.2  bouyer #
   21784  1.1.6.2  bouyer 	mov.l		%d1, %d0		# copy the denorm threshold
   21785  1.1.6.2  bouyer 	sub.w		FTEMP_EX(%a0), %d1	# d1 = threshold - uns exponent
   21786  1.1.6.2  bouyer 	ble.b		dnrm_no_lp		# d1 <= 0
   21787  1.1.6.2  bouyer 	cmpi.w		%d1, &0x20		# is ( 0 <= d1 < 32) ?
   21788  1.1.6.2  bouyer 	blt.b		case_1			# yes
   21789  1.1.6.2  bouyer 	cmpi.w		%d1, &0x40		# is (32 <= d1 < 64) ?
   21790  1.1.6.2  bouyer 	blt.b		case_2			# yes
   21791  1.1.6.2  bouyer 	bra.w		case_3			# (d1 >= 64)
   21792  1.1.6.2  bouyer 
   21793  1.1.6.2  bouyer #
   21794  1.1.6.2  bouyer # No normalization necessary
   21795  1.1.6.2  bouyer #
   21796  1.1.6.2  bouyer dnrm_no_lp:
   21797  1.1.6.2  bouyer 	mov.l		GRS(%a6), %d0 		# restore original g,r,s
   21798  1.1.6.2  bouyer 	rts
   21799  1.1.6.2  bouyer 
   21800  1.1.6.2  bouyer #
   21801  1.1.6.2  bouyer # case (0<d1<32)
   21802  1.1.6.2  bouyer #
   21803  1.1.6.2  bouyer # %d0 = denorm threshold
   21804  1.1.6.2  bouyer # %d1 = "n" = amt to shift
   21805  1.1.6.2  bouyer #
   21806  1.1.6.2  bouyer #	---------------------------------------------------------
   21807  1.1.6.2  bouyer #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21808  1.1.6.2  bouyer #	---------------------------------------------------------
   21809  1.1.6.2  bouyer #	<-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
   21810  1.1.6.2  bouyer #	\	   \		      \			 \
   21811  1.1.6.2  bouyer #	 \	    \		       \		  \
   21812  1.1.6.2  bouyer #	  \	     \			\		   \
   21813  1.1.6.2  bouyer #	   \	      \			 \		    \
   21814  1.1.6.2  bouyer #	    \	       \		  \		     \
   21815  1.1.6.2  bouyer #	     \		\		   \		      \
   21816  1.1.6.2  bouyer #	      \		 \		    \		       \
   21817  1.1.6.2  bouyer #	       \	  \		     \			\
   21818  1.1.6.2  bouyer #	<-(n)-><-(32 - n)-><------(32)-------><------(32)------->
   21819  1.1.6.2  bouyer #	---------------------------------------------------------
   21820  1.1.6.2  bouyer #	|0.....0| NEW_HI  |  NEW_FTEMP_LO     |grs		|
   21821  1.1.6.2  bouyer #	---------------------------------------------------------
   21822  1.1.6.2  bouyer #
   21823  1.1.6.2  bouyer case_1:
   21824  1.1.6.2  bouyer 	mov.l		%d2, -(%sp)		# create temp storage
   21825  1.1.6.2  bouyer 
   21826  1.1.6.2  bouyer 	mov.w		%d0, FTEMP_EX(%a0)	# exponent = denorm threshold
   21827  1.1.6.2  bouyer 	mov.l		&32, %d0
   21828  1.1.6.2  bouyer 	sub.w		%d1, %d0		# %d0 = 32 - %d1
   21829  1.1.6.2  bouyer 
   21830  1.1.6.2  bouyer 	cmpi.w		%d1, &29		# is shft amt >= 29
   21831  1.1.6.2  bouyer 	blt.b		case1_extract		# no; no fix needed
   21832  1.1.6.2  bouyer 	mov.b		GRS(%a6), %d2
   21833  1.1.6.2  bouyer 	or.b		%d2, 3+FTEMP_LO2(%a6)
   21834  1.1.6.2  bouyer 
   21835  1.1.6.2  bouyer case1_extract:
   21836  1.1.6.2  bouyer 	bfextu		FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_HI
   21837  1.1.6.2  bouyer 	bfextu		FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new FTEMP_LO
   21838  1.1.6.2  bouyer 	bfextu		FTEMP_LO2(%a6){%d0:&32}, %d0 # %d0 = new G,R,S
   21839  1.1.6.2  bouyer 
   21840  1.1.6.2  bouyer 	mov.l		%d2, FTEMP_HI(%a0)	# store new FTEMP_HI
   21841  1.1.6.2  bouyer 	mov.l		%d1, FTEMP_LO(%a0)	# store new FTEMP_LO
   21842  1.1.6.2  bouyer 
   21843  1.1.6.2  bouyer 	bftst		%d0{&2:&30}		# were bits shifted off?
   21844  1.1.6.2  bouyer 	beq.b		case1_sticky_clear	# no; go finish
   21845  1.1.6.2  bouyer 	bset		&rnd_stky_bit, %d0	# yes; set sticky bit
   21846  1.1.6.2  bouyer 
   21847  1.1.6.2  bouyer case1_sticky_clear:
   21848  1.1.6.2  bouyer 	and.l		&0xe0000000, %d0	# clear all but G,R,S
   21849  1.1.6.2  bouyer 	mov.l		(%sp)+, %d2		# restore temp register
   21850  1.1.6.2  bouyer 	rts
   21851  1.1.6.2  bouyer 
   21852  1.1.6.2  bouyer #
   21853  1.1.6.2  bouyer # case (32<=d1<64)
   21854  1.1.6.2  bouyer #
   21855  1.1.6.2  bouyer # %d0 = denorm threshold
   21856  1.1.6.2  bouyer # %d1 = "n" = amt to shift
   21857  1.1.6.2  bouyer #
   21858  1.1.6.2  bouyer #	---------------------------------------------------------
   21859  1.1.6.2  bouyer #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21860  1.1.6.2  bouyer #	---------------------------------------------------------
   21861  1.1.6.2  bouyer #	<-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
   21862  1.1.6.2  bouyer #	\	   \		      \
   21863  1.1.6.2  bouyer #	 \	    \		       \
   21864  1.1.6.2  bouyer #	  \	     \			-------------------
   21865  1.1.6.2  bouyer #	   \	      --------------------		   \
   21866  1.1.6.2  bouyer #	    -------------------	  	  \		    \
   21867  1.1.6.2  bouyer #	     		       \	   \		     \
   21868  1.1.6.2  bouyer #	      		 	\     	    \		      \
   21869  1.1.6.2  bouyer #	       		  	 \	     \		       \
   21870  1.1.6.2  bouyer #	<-------(32)------><-(n)-><-(32 - n)-><------(32)------->
   21871  1.1.6.2  bouyer #	---------------------------------------------------------
   21872  1.1.6.2  bouyer #	|0...............0|0....0| NEW_LO     |grs		|
   21873  1.1.6.2  bouyer #	---------------------------------------------------------
   21874  1.1.6.2  bouyer #
   21875  1.1.6.2  bouyer case_2:
   21876  1.1.6.2  bouyer 	mov.l		%d2, -(%sp)		# create temp storage
   21877  1.1.6.2  bouyer 
   21878  1.1.6.2  bouyer 	mov.w		%d0, FTEMP_EX(%a0)	# exponent = denorm threshold
   21879  1.1.6.2  bouyer 	subi.w		&0x20, %d1		# %d1 now between 0 and 32
   21880  1.1.6.2  bouyer 	mov.l		&0x20, %d0
   21881  1.1.6.2  bouyer 	sub.w		%d1, %d0		# %d0 = 32 - %d1
   21882  1.1.6.2  bouyer 
   21883  1.1.6.2  bouyer # subtle step here; or in the g,r,s at the bottom of FTEMP_LO to minimize
   21884  1.1.6.2  bouyer # the number of bits to check for the sticky detect.
   21885  1.1.6.2  bouyer # it only plays a role in shift amounts of 61-63.
   21886  1.1.6.2  bouyer 	mov.b		GRS(%a6), %d2
   21887  1.1.6.2  bouyer 	or.b		%d2, 3+FTEMP_LO2(%a6)
   21888  1.1.6.2  bouyer 
   21889  1.1.6.2  bouyer 	bfextu		FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_LO
   21890  1.1.6.2  bouyer 	bfextu		FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new G,R,S
   21891  1.1.6.2  bouyer 
   21892  1.1.6.2  bouyer 	bftst		%d1{&2:&30}		# were any bits shifted off?
   21893  1.1.6.2  bouyer 	bne.b		case2_set_sticky	# yes; set sticky bit
   21894  1.1.6.2  bouyer 	bftst		FTEMP_LO2(%a6){%d0:&31}	# were any bits shifted off?
   21895  1.1.6.2  bouyer 	bne.b		case2_set_sticky	# yes; set sticky bit
   21896  1.1.6.2  bouyer 
   21897  1.1.6.2  bouyer 	mov.l		%d1, %d0		# move new G,R,S to %d0
   21898  1.1.6.2  bouyer 	bra.b		case2_end
   21899  1.1.6.2  bouyer 
   21900  1.1.6.2  bouyer case2_set_sticky:
   21901  1.1.6.2  bouyer 	mov.l		%d1, %d0		# move new G,R,S to %d0
   21902  1.1.6.2  bouyer 	bset		&rnd_stky_bit, %d0	# set sticky bit
   21903  1.1.6.2  bouyer 
   21904  1.1.6.2  bouyer case2_end:
   21905  1.1.6.2  bouyer 	clr.l		FTEMP_HI(%a0)		# store FTEMP_HI = 0
   21906  1.1.6.2  bouyer 	mov.l		%d2, FTEMP_LO(%a0)	# store FTEMP_LO
   21907  1.1.6.2  bouyer 	and.l		&0xe0000000, %d0	# clear all but G,R,S
   21908  1.1.6.2  bouyer 
   21909  1.1.6.2  bouyer 	mov.l		(%sp)+,%d2		# restore temp register
   21910  1.1.6.2  bouyer 	rts
   21911  1.1.6.2  bouyer 
   21912  1.1.6.2  bouyer #
   21913  1.1.6.2  bouyer # case (d1>=64)
   21914  1.1.6.2  bouyer #
   21915  1.1.6.2  bouyer # %d0 = denorm threshold
   21916  1.1.6.2  bouyer # %d1 = amt to shift
   21917  1.1.6.2  bouyer #
   21918  1.1.6.2  bouyer case_3:
   21919  1.1.6.2  bouyer 	mov.w		%d0, FTEMP_EX(%a0)	# insert denorm threshold
   21920  1.1.6.2  bouyer 
   21921  1.1.6.2  bouyer 	cmpi.w		%d1, &65		# is shift amt > 65?
   21922  1.1.6.2  bouyer 	blt.b		case3_64		# no; it's == 64
   21923  1.1.6.2  bouyer 	beq.b		case3_65		# no; it's == 65
   21924  1.1.6.2  bouyer 
   21925  1.1.6.2  bouyer #
   21926  1.1.6.2  bouyer # case (d1>65)
   21927  1.1.6.2  bouyer #
   21928  1.1.6.2  bouyer # Shift value is > 65 and out of range. All bits are shifted off.
   21929  1.1.6.2  bouyer # Return a zero mantissa with the sticky bit set
   21930  1.1.6.2  bouyer #
   21931  1.1.6.2  bouyer 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
   21932  1.1.6.2  bouyer 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
   21933  1.1.6.2  bouyer 	mov.l		&0x20000000, %d0	# set sticky bit
   21934  1.1.6.2  bouyer 	rts
   21935  1.1.6.2  bouyer 
   21936  1.1.6.2  bouyer #
   21937  1.1.6.2  bouyer # case (d1 == 64)
   21938  1.1.6.2  bouyer #
   21939  1.1.6.2  bouyer #	---------------------------------------------------------
   21940  1.1.6.2  bouyer #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21941  1.1.6.2  bouyer #	---------------------------------------------------------
   21942  1.1.6.2  bouyer #	<-------(32)------>
   21943  1.1.6.2  bouyer #	\	   	   \
   21944  1.1.6.2  bouyer #	 \	    	    \
   21945  1.1.6.2  bouyer #	  \	     	     \
   21946  1.1.6.2  bouyer #	   \	      	      ------------------------------
   21947  1.1.6.2  bouyer #	    -------------------------------		    \
   21948  1.1.6.2  bouyer #	     		       		   \		     \
   21949  1.1.6.2  bouyer #	      		 	     	    \		      \
   21950  1.1.6.2  bouyer #	       		  	 	     \		       \
   21951  1.1.6.2  bouyer #					      <-------(32)------>
   21952  1.1.6.2  bouyer #	---------------------------------------------------------
   21953  1.1.6.2  bouyer #	|0...............0|0................0|grs		|
   21954  1.1.6.2  bouyer #	---------------------------------------------------------
   21955  1.1.6.2  bouyer #
   21956  1.1.6.2  bouyer case3_64:
   21957  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0), %d0	# fetch hi(mantissa)
   21958  1.1.6.2  bouyer 	mov.l		%d0, %d1		# make a copy
   21959  1.1.6.2  bouyer 	and.l		&0xc0000000, %d0	# extract G,R
   21960  1.1.6.2  bouyer 	and.l		&0x3fffffff, %d1	# extract other bits
   21961  1.1.6.2  bouyer 
   21962  1.1.6.2  bouyer 	bra.b		case3_complete
   21963  1.1.6.2  bouyer 
   21964  1.1.6.2  bouyer #
   21965  1.1.6.2  bouyer # case (d1 == 65)
   21966  1.1.6.2  bouyer #
   21967  1.1.6.2  bouyer #	---------------------------------------------------------
   21968  1.1.6.2  bouyer #	|     FTEMP_HI	  |    	FTEMP_LO     |grs000.........000|
   21969  1.1.6.2  bouyer #	---------------------------------------------------------
   21970  1.1.6.2  bouyer #	<-------(32)------>
   21971  1.1.6.2  bouyer #	\	   	   \
   21972  1.1.6.2  bouyer #	 \	    	    \
   21973  1.1.6.2  bouyer #	  \	     	     \
   21974  1.1.6.2  bouyer #	   \	      	      ------------------------------
   21975  1.1.6.2  bouyer #	    --------------------------------		    \
   21976  1.1.6.2  bouyer #	     		       		    \		     \
   21977  1.1.6.2  bouyer #	      		 	     	     \		      \
   21978  1.1.6.2  bouyer #	       		  	 	      \		       \
   21979  1.1.6.2  bouyer #					       <-------(31)----->
   21980  1.1.6.2  bouyer #	---------------------------------------------------------
   21981  1.1.6.2  bouyer #	|0...............0|0................0|0rs		|
   21982  1.1.6.2  bouyer #	---------------------------------------------------------
   21983  1.1.6.2  bouyer #
   21984  1.1.6.2  bouyer case3_65:
   21985  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0), %d0	# fetch hi(mantissa)
   21986  1.1.6.2  bouyer 	and.l		&0x80000000, %d0	# extract R bit
   21987  1.1.6.2  bouyer 	lsr.l		&0x1, %d0		# shift high bit into R bit
   21988  1.1.6.2  bouyer 	and.l		&0x7fffffff, %d1	# extract other bits
   21989  1.1.6.2  bouyer 
   21990  1.1.6.2  bouyer case3_complete:
   21991  1.1.6.2  bouyer # last operation done was an "and" of the bits shifted off so the condition
   21992  1.1.6.2  bouyer # codes are already set so branch accordingly.
   21993  1.1.6.2  bouyer 	bne.b		case3_set_sticky	# yes; go set new sticky
   21994  1.1.6.2  bouyer 	tst.l		FTEMP_LO(%a0)		# were any bits shifted off?
   21995  1.1.6.2  bouyer 	bne.b		case3_set_sticky	# yes; go set new sticky
   21996  1.1.6.2  bouyer 	tst.b		GRS(%a6)		# were any bits shifted off?
   21997  1.1.6.2  bouyer 	bne.b		case3_set_sticky	# yes; go set new sticky
   21998  1.1.6.2  bouyer 
   21999  1.1.6.2  bouyer #
   22000  1.1.6.2  bouyer # no bits were shifted off so don't set the sticky bit.
   22001  1.1.6.2  bouyer # the guard and
   22002  1.1.6.2  bouyer # the entire mantissa is zero.
   22003  1.1.6.2  bouyer #
   22004  1.1.6.2  bouyer 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
   22005  1.1.6.2  bouyer 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
   22006  1.1.6.2  bouyer 	rts
   22007  1.1.6.2  bouyer 
   22008  1.1.6.2  bouyer #
   22009  1.1.6.2  bouyer # some bits were shifted off so set the sticky bit.
   22010  1.1.6.2  bouyer # the entire mantissa is zero.
   22011  1.1.6.2  bouyer #
   22012  1.1.6.2  bouyer case3_set_sticky:
   22013  1.1.6.2  bouyer 	bset		&rnd_stky_bit,%d0	# set new sticky bit
   22014  1.1.6.2  bouyer 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
   22015  1.1.6.2  bouyer 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
   22016  1.1.6.2  bouyer 	rts
   22017  1.1.6.2  bouyer 
   22018  1.1.6.2  bouyer #########################################################################
   22019  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22020  1.1.6.2  bouyer #	_round(): round result according to precision/mode		#
   22021  1.1.6.2  bouyer #									#
   22022  1.1.6.2  bouyer # XREF ****************************************************************	#
   22023  1.1.6.2  bouyer #	None								#
   22024  1.1.6.2  bouyer #									#
   22025  1.1.6.2  bouyer # INPUT ***************************************************************	#
   22026  1.1.6.2  bouyer #	a0	  = ptr to input operand in internal extended format 	#
   22027  1.1.6.2  bouyer #	d1(hi)    = contains rounding precision:			#
   22028  1.1.6.2  bouyer #			ext = $0000xxxx					#
   22029  1.1.6.2  bouyer #			sgl = $0004xxxx					#
   22030  1.1.6.2  bouyer #			dbl = $0008xxxx					#
   22031  1.1.6.2  bouyer #	d1(lo)	  = contains rounding mode:				#
   22032  1.1.6.2  bouyer #			RN  = $xxxx0000					#
   22033  1.1.6.2  bouyer #			RZ  = $xxxx0001					#
   22034  1.1.6.2  bouyer #			RM  = $xxxx0002					#
   22035  1.1.6.2  bouyer #			RP  = $xxxx0003					#
   22036  1.1.6.2  bouyer #	d0{31:29} = contains the g,r,s bits (extended)			#
   22037  1.1.6.2  bouyer #									#
   22038  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   22039  1.1.6.2  bouyer #	a0 = pointer to rounded result					#
   22040  1.1.6.2  bouyer #									#
   22041  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   22042  1.1.6.2  bouyer #	On return the value pointed to by a0 is correctly rounded,	#
   22043  1.1.6.2  bouyer #	a0 is preserved and the g-r-s bits in d0 are cleared.		#
   22044  1.1.6.2  bouyer #	The result is not typed - the tag field is invalid.  The	#
   22045  1.1.6.2  bouyer #	result is still in the internal extended format.		#
   22046  1.1.6.2  bouyer #									#
   22047  1.1.6.2  bouyer #	The INEX bit of USER_FPSR will be set if the rounded result was	#
   22048  1.1.6.2  bouyer #	inexact (i.e. if any of the g-r-s bits were set).		#
   22049  1.1.6.2  bouyer #									#
   22050  1.1.6.2  bouyer #########################################################################
   22051  1.1.6.2  bouyer 
   22052  1.1.6.2  bouyer 	global		_round
   22053  1.1.6.2  bouyer _round:
   22054  1.1.6.2  bouyer #
   22055  1.1.6.2  bouyer # ext_grs() looks at the rounding precision and sets the appropriate
   22056  1.1.6.2  bouyer # G,R,S bits.
   22057  1.1.6.2  bouyer # If (G,R,S == 0) then result is exact and round is done, else set
   22058  1.1.6.2  bouyer # the inex flag in status reg and continue.
   22059  1.1.6.2  bouyer #
   22060  1.1.6.2  bouyer 	bsr.l		ext_grs			# extract G,R,S
   22061  1.1.6.2  bouyer 
   22062  1.1.6.2  bouyer 	tst.l		%d0			# are G,R,S zero?
   22063  1.1.6.2  bouyer 	beq.w		truncate		# yes; round is complete
   22064  1.1.6.2  bouyer 
   22065  1.1.6.2  bouyer 	or.w		&inx2a_mask, 2+USER_FPSR(%a6) # set inex2/ainex
   22066  1.1.6.2  bouyer 
   22067  1.1.6.2  bouyer #
   22068  1.1.6.2  bouyer # Use rounding mode as an index into a jump table for these modes.
   22069  1.1.6.2  bouyer # All of the following assumes grs != 0.
   22070  1.1.6.2  bouyer #
   22071  1.1.6.2  bouyer 	mov.w		(tbl_mode.b,%pc,%d1.w*2), %a1 # load jump offset
   22072  1.1.6.2  bouyer 	jmp		(tbl_mode.b,%pc,%a1)	# jmp to rnd mode handler
   22073  1.1.6.2  bouyer 
   22074  1.1.6.2  bouyer tbl_mode:
   22075  1.1.6.2  bouyer 	short		rnd_near - tbl_mode
   22076  1.1.6.2  bouyer 	short		truncate - tbl_mode	# RZ always truncates
   22077  1.1.6.2  bouyer 	short		rnd_mnus - tbl_mode
   22078  1.1.6.2  bouyer 	short		rnd_plus - tbl_mode
   22079  1.1.6.2  bouyer 
   22080  1.1.6.2  bouyer #################################################################
   22081  1.1.6.2  bouyer #	ROUND PLUS INFINITY					#
   22082  1.1.6.2  bouyer #								#
   22083  1.1.6.2  bouyer #	If sign of fp number = 0 (positive), then add 1 to l.	#
   22084  1.1.6.2  bouyer #################################################################
   22085  1.1.6.2  bouyer rnd_plus:
   22086  1.1.6.2  bouyer 	tst.b		FTEMP_SGN(%a0)		# check for sign
   22087  1.1.6.2  bouyer 	bmi.w		truncate		# if positive then truncate
   22088  1.1.6.2  bouyer 
   22089  1.1.6.2  bouyer 	mov.l		&0xffffffff, %d0	# force g,r,s to be all f's
   22090  1.1.6.2  bouyer 	swap		%d1			# set up d1 for round prec.
   22091  1.1.6.2  bouyer 
   22092  1.1.6.2  bouyer 	cmpi.b		%d1, &s_mode		# is prec = sgl?
   22093  1.1.6.2  bouyer 	beq.w		add_sgl			# yes
   22094  1.1.6.2  bouyer 	bgt.w		add_dbl			# no; it's dbl
   22095  1.1.6.2  bouyer 	bra.w		add_ext			# no; it's ext
   22096  1.1.6.2  bouyer 
   22097  1.1.6.2  bouyer #################################################################
   22098  1.1.6.2  bouyer #	ROUND MINUS INFINITY					#
   22099  1.1.6.2  bouyer #								#
   22100  1.1.6.2  bouyer #	If sign of fp number = 1 (negative), then add 1 to l.	#
   22101  1.1.6.2  bouyer #################################################################
   22102  1.1.6.2  bouyer rnd_mnus:
   22103  1.1.6.2  bouyer 	tst.b		FTEMP_SGN(%a0)		# check for sign
   22104  1.1.6.2  bouyer 	bpl.w		truncate		# if negative then truncate
   22105  1.1.6.2  bouyer 
   22106  1.1.6.2  bouyer 	mov.l		&0xffffffff, %d0	# force g,r,s to be all f's
   22107  1.1.6.2  bouyer 	swap		%d1			# set up d1 for round prec.
   22108  1.1.6.2  bouyer 
   22109  1.1.6.2  bouyer 	cmpi.b		%d1, &s_mode		# is prec = sgl?
   22110  1.1.6.2  bouyer 	beq.w		add_sgl			# yes
   22111  1.1.6.2  bouyer 	bgt.w		add_dbl			# no; it's dbl
   22112  1.1.6.2  bouyer 	bra.w		add_ext			# no; it's ext
   22113  1.1.6.2  bouyer 
   22114  1.1.6.2  bouyer #################################################################
   22115  1.1.6.2  bouyer #	ROUND NEAREST						#
   22116  1.1.6.2  bouyer #								#
   22117  1.1.6.2  bouyer #	If (g=1), then add 1 to l and if (r=s=0), then clear l	#
   22118  1.1.6.2  bouyer #	Note that this will round to even in case of a tie.	#
   22119  1.1.6.2  bouyer #################################################################
   22120  1.1.6.2  bouyer rnd_near:
   22121  1.1.6.2  bouyer 	asl.l		&0x1, %d0		# shift g-bit to c-bit
   22122  1.1.6.2  bouyer 	bcc.w		truncate		# if (g=1) then
   22123  1.1.6.2  bouyer 
   22124  1.1.6.2  bouyer 	swap		%d1			# set up d1 for round prec.
   22125  1.1.6.2  bouyer 
   22126  1.1.6.2  bouyer 	cmpi.b		%d1, &s_mode		# is prec = sgl?
   22127  1.1.6.2  bouyer 	beq.w		add_sgl			# yes
   22128  1.1.6.2  bouyer 	bgt.w		add_dbl			# no; it's dbl
   22129  1.1.6.2  bouyer 	bra.w		add_ext			# no; it's ext
   22130  1.1.6.2  bouyer 
   22131  1.1.6.2  bouyer # *** LOCAL EQUATES ***
   22132  1.1.6.2  bouyer set	ad_1_sgl,	0x00000100	# constant to add 1 to l-bit in sgl prec
   22133  1.1.6.2  bouyer set	ad_1_dbl,	0x00000800	# constant to add 1 to l-bit in dbl prec
   22134  1.1.6.2  bouyer 
   22135  1.1.6.2  bouyer #########################
   22136  1.1.6.2  bouyer #	ADD SINGLE	#
   22137  1.1.6.2  bouyer #########################
   22138  1.1.6.2  bouyer add_sgl:
   22139  1.1.6.2  bouyer 	add.l		&ad_1_sgl, FTEMP_HI(%a0)
   22140  1.1.6.2  bouyer 	bcc.b		scc_clr			# no mantissa overflow
   22141  1.1.6.2  bouyer 	roxr.w		FTEMP_HI(%a0)		# shift v-bit back in
   22142  1.1.6.2  bouyer 	roxr.w		FTEMP_HI+2(%a0)		# shift v-bit back in
   22143  1.1.6.2  bouyer 	add.w		&0x1, FTEMP_EX(%a0)	# and incr exponent
   22144  1.1.6.2  bouyer scc_clr:
   22145  1.1.6.2  bouyer 	tst.l		%d0			# test for rs = 0
   22146  1.1.6.2  bouyer 	bne.b		sgl_done
   22147  1.1.6.2  bouyer 	and.w		&0xfe00, FTEMP_HI+2(%a0) # clear the l-bit
   22148  1.1.6.2  bouyer sgl_done:
   22149  1.1.6.2  bouyer 	and.l		&0xffffff00, FTEMP_HI(%a0) # truncate bits beyond sgl limit
   22150  1.1.6.2  bouyer 	clr.l		FTEMP_LO(%a0)		# clear d2
   22151  1.1.6.2  bouyer 	rts
   22152  1.1.6.2  bouyer 
   22153  1.1.6.2  bouyer #########################
   22154  1.1.6.2  bouyer #	ADD EXTENDED	#
   22155  1.1.6.2  bouyer #########################
   22156  1.1.6.2  bouyer add_ext:
   22157  1.1.6.2  bouyer 	addq.l		&1,FTEMP_LO(%a0)	# add 1 to l-bit
   22158  1.1.6.2  bouyer 	bcc.b		xcc_clr			# test for carry out
   22159  1.1.6.2  bouyer 	addq.l		&1,FTEMP_HI(%a0)	# propogate carry
   22160  1.1.6.2  bouyer 	bcc.b		xcc_clr
   22161  1.1.6.2  bouyer 	roxr.w		FTEMP_HI(%a0)		# mant is 0 so restore v-bit
   22162  1.1.6.2  bouyer 	roxr.w		FTEMP_HI+2(%a0)		# mant is 0 so restore v-bit
   22163  1.1.6.2  bouyer 	roxr.w		FTEMP_LO(%a0)
   22164  1.1.6.2  bouyer 	roxr.w		FTEMP_LO+2(%a0)
   22165  1.1.6.2  bouyer 	add.w		&0x1,FTEMP_EX(%a0)	# and inc exp
   22166  1.1.6.2  bouyer xcc_clr:
   22167  1.1.6.2  bouyer 	tst.l		%d0			# test rs = 0
   22168  1.1.6.2  bouyer 	bne.b		add_ext_done
   22169  1.1.6.2  bouyer 	and.b		&0xfe,FTEMP_LO+3(%a0)	# clear the l bit
   22170  1.1.6.2  bouyer add_ext_done:
   22171  1.1.6.2  bouyer 	rts
   22172  1.1.6.2  bouyer 
   22173  1.1.6.2  bouyer #########################
   22174  1.1.6.2  bouyer #	ADD DOUBLE	#
   22175  1.1.6.2  bouyer #########################
   22176  1.1.6.2  bouyer add_dbl:
   22177  1.1.6.2  bouyer 	add.l		&ad_1_dbl, FTEMP_LO(%a0) # add 1 to lsb
   22178  1.1.6.2  bouyer 	bcc.b		dcc_clr			# no carry
   22179  1.1.6.2  bouyer 	addq.l		&0x1, FTEMP_HI(%a0)	# propogate carry
   22180  1.1.6.2  bouyer 	bcc.b		dcc_clr			# no carry
   22181  1.1.6.2  bouyer 
   22182  1.1.6.2  bouyer 	roxr.w		FTEMP_HI(%a0)		# mant is 0 so restore v-bit
   22183  1.1.6.2  bouyer 	roxr.w		FTEMP_HI+2(%a0)		# mant is 0 so restore v-bit
   22184  1.1.6.2  bouyer 	roxr.w		FTEMP_LO(%a0)
   22185  1.1.6.2  bouyer 	roxr.w		FTEMP_LO+2(%a0)
   22186  1.1.6.2  bouyer 	addq.w		&0x1, FTEMP_EX(%a0)	# incr exponent
   22187  1.1.6.2  bouyer dcc_clr:
   22188  1.1.6.2  bouyer 	tst.l		%d0			# test for rs = 0
   22189  1.1.6.2  bouyer 	bne.b		dbl_done
   22190  1.1.6.2  bouyer 	and.w		&0xf000, FTEMP_LO+2(%a0) # clear the l-bit
   22191  1.1.6.2  bouyer 
   22192  1.1.6.2  bouyer dbl_done:
   22193  1.1.6.2  bouyer 	and.l		&0xfffff800,FTEMP_LO(%a0) # truncate bits beyond dbl limit
   22194  1.1.6.2  bouyer 	rts
   22195  1.1.6.2  bouyer 
   22196  1.1.6.2  bouyer ###########################
   22197  1.1.6.2  bouyer # Truncate all other bits #
   22198  1.1.6.2  bouyer ###########################
   22199  1.1.6.2  bouyer truncate:
   22200  1.1.6.2  bouyer 	swap		%d1			# select rnd prec
   22201  1.1.6.2  bouyer 
   22202  1.1.6.2  bouyer 	cmpi.b		%d1, &s_mode		# is prec sgl?
   22203  1.1.6.2  bouyer 	beq.w		sgl_done		# yes
   22204  1.1.6.2  bouyer 	bgt.b		dbl_done		# no; it's dbl
   22205  1.1.6.2  bouyer 	rts					# no; it's ext
   22206  1.1.6.2  bouyer 
   22207  1.1.6.2  bouyer 
   22208  1.1.6.2  bouyer #
   22209  1.1.6.2  bouyer # ext_grs(): extract guard, round and sticky bits according to
   22210  1.1.6.2  bouyer #	     rounding precision.
   22211  1.1.6.2  bouyer #
   22212  1.1.6.2  bouyer # INPUT
   22213  1.1.6.2  bouyer #	d0	   = extended precision g,r,s (in d0{31:29})
   22214  1.1.6.2  bouyer #	d1 	   = {PREC,ROUND}
   22215  1.1.6.2  bouyer # OUTPUT
   22216  1.1.6.2  bouyer #	d0{31:29}  = guard, round, sticky
   22217  1.1.6.2  bouyer #
   22218  1.1.6.2  bouyer # The ext_grs extract the guard/round/sticky bits according to the
   22219  1.1.6.2  bouyer # selected rounding precision. It is called by the round subroutine
   22220  1.1.6.2  bouyer # only.  All registers except d0 are kept intact. d0 becomes an
   22221  1.1.6.2  bouyer # updated guard,round,sticky in d0{31:29}
   22222  1.1.6.2  bouyer #
   22223  1.1.6.2  bouyer # Notes: the ext_grs uses the round PREC, and therefore has to swap d1
   22224  1.1.6.2  bouyer #	 prior to usage, and needs to restore d1 to original. this
   22225  1.1.6.2  bouyer #	 routine is tightly tied to the round routine and not meant to
   22226  1.1.6.2  bouyer #	 uphold standard subroutine calling practices.
   22227  1.1.6.2  bouyer #
   22228  1.1.6.2  bouyer 
   22229  1.1.6.2  bouyer ext_grs:
   22230  1.1.6.2  bouyer 	swap		%d1			# have d1.w point to round precision
   22231  1.1.6.2  bouyer 	tst.b		%d1			# is rnd prec = extended?
   22232  1.1.6.2  bouyer 	bne.b		ext_grs_not_ext		# no; go handle sgl or dbl
   22233  1.1.6.2  bouyer 
   22234  1.1.6.2  bouyer #
   22235  1.1.6.2  bouyer # %d0 actually already hold g,r,s since _round() had it before calling
   22236  1.1.6.2  bouyer # this function. so, as long as we don't disturb it, we are "returning" it.
   22237  1.1.6.2  bouyer #
   22238  1.1.6.2  bouyer ext_grs_ext:
   22239  1.1.6.2  bouyer 	swap		%d1			# yes; return to correct positions
   22240  1.1.6.2  bouyer 	rts
   22241  1.1.6.2  bouyer 
   22242  1.1.6.2  bouyer ext_grs_not_ext:
   22243  1.1.6.2  bouyer 	movm.l		&0x3000, -(%sp)		# make some temp registers {d2/d3}
   22244  1.1.6.2  bouyer 
   22245  1.1.6.2  bouyer 	cmpi.b		%d1, &s_mode		# is rnd prec = sgl?
   22246  1.1.6.2  bouyer 	bne.b		ext_grs_dbl		# no; go handle dbl
   22247  1.1.6.2  bouyer 
   22248  1.1.6.2  bouyer #
   22249  1.1.6.2  bouyer # sgl:
   22250  1.1.6.2  bouyer #	96		64	  40	32		0
   22251  1.1.6.2  bouyer #	-----------------------------------------------------
   22252  1.1.6.2  bouyer #	| EXP	|XXXXXXX|	  |xx	|		|grs|
   22253  1.1.6.2  bouyer #	-----------------------------------------------------
   22254  1.1.6.2  bouyer #			<--(24)--->nn\			   /
   22255  1.1.6.2  bouyer #				   ee ---------------------
   22256  1.1.6.2  bouyer #				   ww		|
   22257  1.1.6.2  bouyer #						v
   22258  1.1.6.2  bouyer #				   gr	   new sticky
   22259  1.1.6.2  bouyer #
   22260  1.1.6.2  bouyer ext_grs_sgl:
   22261  1.1.6.2  bouyer 	bfextu		FTEMP_HI(%a0){&24:&2}, %d3 # sgl prec. g-r are 2 bits right
   22262  1.1.6.2  bouyer 	mov.l		&30, %d2		# of the sgl prec. limits
   22263  1.1.6.2  bouyer 	lsl.l		%d2, %d3		# shift g-r bits to MSB of d3
   22264  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0), %d2	# get word 2 for s-bit test
   22265  1.1.6.2  bouyer 	and.l		&0x0000003f, %d2	# s bit is the or of all other
   22266  1.1.6.2  bouyer 	bne.b		ext_grs_st_stky		# bits to the right of g-r
   22267  1.1.6.2  bouyer 	tst.l		FTEMP_LO(%a0)		# test lower mantissa
   22268  1.1.6.2  bouyer 	bne.b		ext_grs_st_stky		# if any are set, set sticky
   22269  1.1.6.2  bouyer 	tst.l		%d0			# test original g,r,s
   22270  1.1.6.2  bouyer 	bne.b		ext_grs_st_stky		# if any are set, set sticky
   22271  1.1.6.2  bouyer 	bra.b		ext_grs_end_sd		# if words 3 and 4 are clr, exit
   22272  1.1.6.2  bouyer 
   22273  1.1.6.2  bouyer #
   22274  1.1.6.2  bouyer # dbl:
   22275  1.1.6.2  bouyer #	96		64	  	32	 11	0
   22276  1.1.6.2  bouyer #	-----------------------------------------------------
   22277  1.1.6.2  bouyer #	| EXP	|XXXXXXX|	  	|	 |xx	|grs|
   22278  1.1.6.2  bouyer #	-----------------------------------------------------
   22279  1.1.6.2  bouyer #						  nn\	    /
   22280  1.1.6.2  bouyer #						  ee -------
   22281  1.1.6.2  bouyer #						  ww	|
   22282  1.1.6.2  bouyer #							v
   22283  1.1.6.2  bouyer #						  gr	new sticky
   22284  1.1.6.2  bouyer #
   22285  1.1.6.2  bouyer ext_grs_dbl:
   22286  1.1.6.2  bouyer 	bfextu		FTEMP_LO(%a0){&21:&2}, %d3 # dbl-prec. g-r are 2 bits right
   22287  1.1.6.2  bouyer 	mov.l		&30, %d2		# of the dbl prec. limits
   22288  1.1.6.2  bouyer 	lsl.l		%d2, %d3		# shift g-r bits to the MSB of d3
   22289  1.1.6.2  bouyer 	mov.l		FTEMP_LO(%a0), %d2	# get lower mantissa  for s-bit test
   22290  1.1.6.2  bouyer 	and.l		&0x000001ff, %d2	# s bit is the or-ing of all
   22291  1.1.6.2  bouyer 	bne.b		ext_grs_st_stky		# other bits to the right of g-r
   22292  1.1.6.2  bouyer 	tst.l		%d0			# test word original g,r,s
   22293  1.1.6.2  bouyer 	bne.b		ext_grs_st_stky		# if any are set, set sticky
   22294  1.1.6.2  bouyer 	bra.b		ext_grs_end_sd		# if clear, exit
   22295  1.1.6.2  bouyer 
   22296  1.1.6.2  bouyer ext_grs_st_stky:
   22297  1.1.6.2  bouyer 	bset		&rnd_stky_bit, %d3	# set sticky bit
   22298  1.1.6.2  bouyer ext_grs_end_sd:
   22299  1.1.6.2  bouyer 	mov.l		%d3, %d0		# return grs to d0
   22300  1.1.6.2  bouyer 
   22301  1.1.6.2  bouyer 	movm.l		(%sp)+, &0xc		# restore scratch registers {d2/d3}
   22302  1.1.6.2  bouyer 
   22303  1.1.6.2  bouyer 	swap		%d1			# restore d1 to original
   22304  1.1.6.2  bouyer 	rts
   22305  1.1.6.2  bouyer 
   22306  1.1.6.2  bouyer #########################################################################
   22307  1.1.6.2  bouyer # norm(): normalize the mantissa of an extended precision input. the	#
   22308  1.1.6.2  bouyer #	  input operand should not be normalized already.		#
   22309  1.1.6.2  bouyer #									#
   22310  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22311  1.1.6.2  bouyer #	norm()								#
   22312  1.1.6.2  bouyer #									#
   22313  1.1.6.2  bouyer # XREF **************************************************************** #
   22314  1.1.6.2  bouyer #	none								#
   22315  1.1.6.2  bouyer #									#
   22316  1.1.6.2  bouyer # INPUT *************************************************************** #
   22317  1.1.6.2  bouyer #	a0 = pointer fp extended precision operand to normalize		#
   22318  1.1.6.2  bouyer #									#
   22319  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   22320  1.1.6.2  bouyer # 	d0 = number of bit positions the mantissa was shifted		#
   22321  1.1.6.2  bouyer #	a0 = the input operand's mantissa is normalized; the exponent	#
   22322  1.1.6.2  bouyer #	     is unchanged.						#
   22323  1.1.6.2  bouyer #									#
   22324  1.1.6.2  bouyer #########################################################################
   22325  1.1.6.2  bouyer 	global		norm
   22326  1.1.6.2  bouyer norm:
   22327  1.1.6.2  bouyer 	mov.l		%d2, -(%sp)		# create some temp regs
   22328  1.1.6.2  bouyer 	mov.l		%d3, -(%sp)
   22329  1.1.6.2  bouyer 
   22330  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
   22331  1.1.6.2  bouyer 	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
   22332  1.1.6.2  bouyer 
   22333  1.1.6.2  bouyer 	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
   22334  1.1.6.2  bouyer 	beq.b		norm_lo			# hi(man) is all zeroes!
   22335  1.1.6.2  bouyer 
   22336  1.1.6.2  bouyer norm_hi:
   22337  1.1.6.2  bouyer 	lsl.l		%d2, %d0		# left shift hi(man)
   22338  1.1.6.2  bouyer 	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
   22339  1.1.6.2  bouyer 
   22340  1.1.6.2  bouyer 	or.l		%d3, %d0		# create hi(man)
   22341  1.1.6.2  bouyer 	lsl.l		%d2, %d1		# create lo(man)
   22342  1.1.6.2  bouyer 
   22343  1.1.6.2  bouyer 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
   22344  1.1.6.2  bouyer 	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
   22345  1.1.6.2  bouyer 
   22346  1.1.6.2  bouyer 	mov.l		%d2, %d0		# return shift amount
   22347  1.1.6.2  bouyer 
   22348  1.1.6.2  bouyer 	mov.l		(%sp)+, %d3		# restore temp regs
   22349  1.1.6.2  bouyer 	mov.l		(%sp)+, %d2
   22350  1.1.6.2  bouyer 
   22351  1.1.6.2  bouyer 	rts
   22352  1.1.6.2  bouyer 
   22353  1.1.6.2  bouyer norm_lo:
   22354  1.1.6.2  bouyer 	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
   22355  1.1.6.2  bouyer 	lsl.l		%d2, %d1		# shift lo(man)
   22356  1.1.6.2  bouyer 	add.l		&32, %d2		# add 32 to shft amount
   22357  1.1.6.2  bouyer 
   22358  1.1.6.2  bouyer 	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
   22359  1.1.6.2  bouyer 	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
   22360  1.1.6.2  bouyer 
   22361  1.1.6.2  bouyer 	mov.l		%d2, %d0		# return shift amount
   22362  1.1.6.2  bouyer 
   22363  1.1.6.2  bouyer 	mov.l		(%sp)+, %d3		# restore temp regs
   22364  1.1.6.2  bouyer 	mov.l		(%sp)+, %d2
   22365  1.1.6.2  bouyer 
   22366  1.1.6.2  bouyer 	rts
   22367  1.1.6.2  bouyer 
   22368  1.1.6.2  bouyer #########################################################################
   22369  1.1.6.2  bouyer # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
   22370  1.1.6.2  bouyer #		- returns corresponding optype tag			#
   22371  1.1.6.2  bouyer #									#
   22372  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22373  1.1.6.2  bouyer #	unnorm_fix()							#
   22374  1.1.6.2  bouyer #									#
   22375  1.1.6.2  bouyer # XREF **************************************************************** #
   22376  1.1.6.2  bouyer #	norm() - normalize the mantissa					#
   22377  1.1.6.2  bouyer #									#
   22378  1.1.6.2  bouyer # INPUT *************************************************************** #
   22379  1.1.6.2  bouyer #	a0 = pointer to unnormalized extended precision number		#
   22380  1.1.6.2  bouyer #									#
   22381  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   22382  1.1.6.2  bouyer #	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
   22383  1.1.6.2  bouyer #	a0 = input operand has been converted to a norm, denorm, or	#
   22384  1.1.6.2  bouyer #	     zero; both the exponent and mantissa are changed.		#
   22385  1.1.6.2  bouyer #									#
   22386  1.1.6.2  bouyer #########################################################################
   22387  1.1.6.2  bouyer 
   22388  1.1.6.2  bouyer 	global		unnorm_fix
   22389  1.1.6.2  bouyer unnorm_fix:
   22390  1.1.6.2  bouyer 	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
   22391  1.1.6.2  bouyer 	bne.b		unnorm_shift		# hi(man) is not all zeroes
   22392  1.1.6.2  bouyer 
   22393  1.1.6.2  bouyer #
   22394  1.1.6.2  bouyer # hi(man) is all zeroes so see if any bits in lo(man) are set
   22395  1.1.6.2  bouyer #
   22396  1.1.6.2  bouyer unnorm_chk_lo:
   22397  1.1.6.2  bouyer 	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
   22398  1.1.6.2  bouyer 	beq.w		unnorm_zero		# yes
   22399  1.1.6.2  bouyer 
   22400  1.1.6.2  bouyer 	add.w		&32, %d0		# no; fix shift distance
   22401  1.1.6.2  bouyer 
   22402  1.1.6.2  bouyer #
   22403  1.1.6.2  bouyer # d0 = # shifts needed for complete normalization
   22404  1.1.6.2  bouyer #
   22405  1.1.6.2  bouyer unnorm_shift:
   22406  1.1.6.2  bouyer 	clr.l		%d1			# clear top word
   22407  1.1.6.2  bouyer 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
   22408  1.1.6.2  bouyer 	and.w		&0x7fff, %d1		# strip off sgn
   22409  1.1.6.2  bouyer 
   22410  1.1.6.2  bouyer 	cmp.w		%d0, %d1		# will denorm push exp < 0?
   22411  1.1.6.2  bouyer 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
   22412  1.1.6.2  bouyer 
   22413  1.1.6.2  bouyer #
   22414  1.1.6.2  bouyer # exponent would not go < 0. therefore, number stays normalized
   22415  1.1.6.2  bouyer #
   22416  1.1.6.2  bouyer 	sub.w		%d0, %d1		# shift exponent value
   22417  1.1.6.2  bouyer 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
   22418  1.1.6.2  bouyer 	and.w		&0x8000, %d0		# save old sign
   22419  1.1.6.2  bouyer 	or.w		%d0, %d1		# {sgn,new exp}
   22420  1.1.6.2  bouyer 	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
   22421  1.1.6.2  bouyer 
   22422  1.1.6.2  bouyer 	bsr.l		norm			# normalize UNNORM
   22423  1.1.6.2  bouyer 
   22424  1.1.6.2  bouyer 	mov.b		&NORM, %d0		# return new optype tag
   22425  1.1.6.2  bouyer 	rts
   22426  1.1.6.2  bouyer 
   22427  1.1.6.2  bouyer #
   22428  1.1.6.2  bouyer # exponent would go < 0, so only denormalize until exp = 0
   22429  1.1.6.2  bouyer #
   22430  1.1.6.2  bouyer unnorm_nrm_zero:
   22431  1.1.6.2  bouyer 	cmp.b		%d1, &32		# is exp <= 32?
   22432  1.1.6.2  bouyer 	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
   22433  1.1.6.2  bouyer 
   22434  1.1.6.2  bouyer 	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
   22435  1.1.6.2  bouyer 	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
   22436  1.1.6.2  bouyer 
   22437  1.1.6.2  bouyer 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
   22438  1.1.6.2  bouyer 	lsl.l		%d1, %d0		# extract new lo(man)
   22439  1.1.6.2  bouyer 	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
   22440  1.1.6.2  bouyer 
   22441  1.1.6.2  bouyer 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
   22442  1.1.6.2  bouyer 
   22443  1.1.6.2  bouyer 	mov.b		&DENORM, %d0		# return new optype tag
   22444  1.1.6.2  bouyer 	rts
   22445  1.1.6.2  bouyer 
   22446  1.1.6.2  bouyer #
   22447  1.1.6.2  bouyer # only mantissa bits set are in lo(man)
   22448  1.1.6.2  bouyer #
   22449  1.1.6.2  bouyer unnorm_nrm_zero_lrg:
   22450  1.1.6.2  bouyer 	sub.w		&32, %d1		# adjust shft amt by 32
   22451  1.1.6.2  bouyer 
   22452  1.1.6.2  bouyer 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
   22453  1.1.6.2  bouyer 	lsl.l		%d1, %d0		# left shift lo(man)
   22454  1.1.6.2  bouyer 
   22455  1.1.6.2  bouyer 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
   22456  1.1.6.2  bouyer 	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
   22457  1.1.6.2  bouyer 
   22458  1.1.6.2  bouyer 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
   22459  1.1.6.2  bouyer 
   22460  1.1.6.2  bouyer 	mov.b		&DENORM, %d0		# return new optype tag
   22461  1.1.6.2  bouyer 	rts
   22462  1.1.6.2  bouyer 
   22463  1.1.6.2  bouyer #
   22464  1.1.6.2  bouyer # whole mantissa is zero so this UNNORM is actually a zero
   22465  1.1.6.2  bouyer #
   22466  1.1.6.2  bouyer unnorm_zero:
   22467  1.1.6.2  bouyer 	and.w		&0x8000, FTEMP_EX(%a0) 	# force exponent to zero
   22468  1.1.6.2  bouyer 
   22469  1.1.6.2  bouyer 	mov.b		&ZERO, %d0		# fix optype tag
   22470  1.1.6.2  bouyer 	rts
   22471  1.1.6.2  bouyer 
   22472  1.1.6.2  bouyer #########################################################################
   22473  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22474  1.1.6.2  bouyer # 	set_tag_x(): return the optype of the input ext fp number	#
   22475  1.1.6.2  bouyer #									#
   22476  1.1.6.2  bouyer # XREF ****************************************************************	#
   22477  1.1.6.2  bouyer #	None								#
   22478  1.1.6.2  bouyer #									#
   22479  1.1.6.2  bouyer # INPUT ***************************************************************	#
   22480  1.1.6.2  bouyer #	a0 = pointer to extended precision operand			#
   22481  1.1.6.2  bouyer # 									#
   22482  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   22483  1.1.6.2  bouyer #	d0 = value of type tag						#
   22484  1.1.6.2  bouyer # 		one of: NORM, INF, QNAN, SNAN, DENORM, UNNORM, ZERO	#
   22485  1.1.6.2  bouyer #									#
   22486  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   22487  1.1.6.2  bouyer #	Simply test the exponent, j-bit, and mantissa values to 	#
   22488  1.1.6.2  bouyer # determine the type of operand.					#
   22489  1.1.6.2  bouyer #	If it's an unnormalized zero, alter the operand and force it	#
   22490  1.1.6.2  bouyer # to be a normal zero.							#
   22491  1.1.6.2  bouyer #									#
   22492  1.1.6.2  bouyer #########################################################################
   22493  1.1.6.2  bouyer 
   22494  1.1.6.2  bouyer 	global		set_tag_x
   22495  1.1.6.2  bouyer set_tag_x:
   22496  1.1.6.2  bouyer 	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
   22497  1.1.6.2  bouyer 	andi.w		&0x7fff, %d0		# strip off sign
   22498  1.1.6.2  bouyer 	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
   22499  1.1.6.2  bouyer 	beq.b		inf_or_nan_x
   22500  1.1.6.2  bouyer not_inf_or_nan_x:
   22501  1.1.6.2  bouyer 	btst		&0x7,FTEMP_HI(%a0)
   22502  1.1.6.2  bouyer 	beq.b		not_norm_x
   22503  1.1.6.2  bouyer is_norm_x:
   22504  1.1.6.2  bouyer 	mov.b		&NORM, %d0
   22505  1.1.6.2  bouyer 	rts
   22506  1.1.6.2  bouyer not_norm_x:
   22507  1.1.6.2  bouyer 	tst.w		%d0			# is exponent = 0?
   22508  1.1.6.2  bouyer 	bne.b		is_unnorm_x
   22509  1.1.6.2  bouyer not_unnorm_x:
   22510  1.1.6.2  bouyer 	tst.l		FTEMP_HI(%a0)
   22511  1.1.6.2  bouyer 	bne.b		is_denorm_x
   22512  1.1.6.2  bouyer 	tst.l		FTEMP_LO(%a0)
   22513  1.1.6.2  bouyer 	bne.b		is_denorm_x
   22514  1.1.6.2  bouyer is_zero_x:
   22515  1.1.6.2  bouyer 	mov.b		&ZERO, %d0
   22516  1.1.6.2  bouyer 	rts
   22517  1.1.6.2  bouyer is_denorm_x:
   22518  1.1.6.2  bouyer 	mov.b		&DENORM, %d0
   22519  1.1.6.2  bouyer 	rts
   22520  1.1.6.2  bouyer # must distinguish now "Unnormalized zeroes" which we
   22521  1.1.6.2  bouyer # must convert to zero.
   22522  1.1.6.2  bouyer is_unnorm_x:
   22523  1.1.6.2  bouyer 	tst.l		FTEMP_HI(%a0)
   22524  1.1.6.2  bouyer 	bne.b		is_unnorm_reg_x
   22525  1.1.6.2  bouyer 	tst.l		FTEMP_LO(%a0)
   22526  1.1.6.2  bouyer 	bne.b		is_unnorm_reg_x
   22527  1.1.6.2  bouyer # it's an "unnormalized zero". let's convert it to an actual zero...
   22528  1.1.6.2  bouyer 	andi.w		&0x8000,FTEMP_EX(%a0)	# clear exponent
   22529  1.1.6.2  bouyer 	mov.b		&ZERO, %d0
   22530  1.1.6.2  bouyer 	rts
   22531  1.1.6.2  bouyer is_unnorm_reg_x:
   22532  1.1.6.2  bouyer 	mov.b		&UNNORM, %d0
   22533  1.1.6.2  bouyer 	rts
   22534  1.1.6.2  bouyer inf_or_nan_x:
   22535  1.1.6.2  bouyer 	tst.l		FTEMP_LO(%a0)
   22536  1.1.6.2  bouyer 	bne.b		is_nan_x
   22537  1.1.6.2  bouyer 	mov.l		FTEMP_HI(%a0), %d0
   22538  1.1.6.2  bouyer 	and.l		&0x7fffffff, %d0	# msb is a don't care!
   22539  1.1.6.2  bouyer 	bne.b		is_nan_x
   22540  1.1.6.2  bouyer is_inf_x:
   22541  1.1.6.2  bouyer 	mov.b		&INF, %d0
   22542  1.1.6.2  bouyer 	rts
   22543  1.1.6.2  bouyer is_nan_x:
   22544  1.1.6.2  bouyer 	btst		&0x6, FTEMP_HI(%a0)
   22545  1.1.6.2  bouyer 	beq.b		is_snan_x
   22546  1.1.6.2  bouyer 	mov.b		&QNAN, %d0
   22547  1.1.6.2  bouyer 	rts
   22548  1.1.6.2  bouyer is_snan_x:
   22549  1.1.6.2  bouyer 	mov.b		&SNAN, %d0
   22550  1.1.6.2  bouyer 	rts
   22551  1.1.6.2  bouyer 
   22552  1.1.6.2  bouyer #########################################################################
   22553  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22554  1.1.6.2  bouyer # 	set_tag_d(): return the optype of the input dbl fp number	#
   22555  1.1.6.2  bouyer #									#
   22556  1.1.6.2  bouyer # XREF ****************************************************************	#
   22557  1.1.6.2  bouyer #	None								#
   22558  1.1.6.2  bouyer #									#
   22559  1.1.6.2  bouyer # INPUT ***************************************************************	#
   22560  1.1.6.2  bouyer #	a0 = points to double precision operand				#
   22561  1.1.6.2  bouyer # 									#
   22562  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   22563  1.1.6.2  bouyer #	d0 = value of type tag						#
   22564  1.1.6.2  bouyer # 		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
   22565  1.1.6.2  bouyer #									#
   22566  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   22567  1.1.6.2  bouyer #	Simply test the exponent, j-bit, and mantissa values to 	#
   22568  1.1.6.2  bouyer # determine the type of operand.					#
   22569  1.1.6.2  bouyer #									#
   22570  1.1.6.2  bouyer #########################################################################
   22571  1.1.6.2  bouyer 
   22572  1.1.6.2  bouyer 	global		set_tag_d
   22573  1.1.6.2  bouyer set_tag_d:
   22574  1.1.6.2  bouyer 	mov.l		FTEMP(%a0), %d0
   22575  1.1.6.2  bouyer 	mov.l		%d0, %d1
   22576  1.1.6.2  bouyer 
   22577  1.1.6.2  bouyer 	andi.l		&0x7ff00000, %d0
   22578  1.1.6.2  bouyer 	beq.b		zero_or_denorm_d
   22579  1.1.6.2  bouyer 
   22580  1.1.6.2  bouyer 	cmpi.l		%d0, &0x7ff00000
   22581  1.1.6.2  bouyer 	beq.b		inf_or_nan_d
   22582  1.1.6.2  bouyer 
   22583  1.1.6.2  bouyer is_norm_d:
   22584  1.1.6.2  bouyer 	mov.b		&NORM, %d0
   22585  1.1.6.2  bouyer 	rts
   22586  1.1.6.2  bouyer zero_or_denorm_d:
   22587  1.1.6.2  bouyer 	and.l		&0x000fffff, %d1
   22588  1.1.6.2  bouyer 	bne		is_denorm_d
   22589  1.1.6.2  bouyer 	tst.l		4+FTEMP(%a0)
   22590  1.1.6.2  bouyer 	bne		is_denorm_d
   22591  1.1.6.2  bouyer is_zero_d:
   22592  1.1.6.2  bouyer 	mov.b		&ZERO, %d0
   22593  1.1.6.2  bouyer 	rts
   22594  1.1.6.2  bouyer is_denorm_d:
   22595  1.1.6.2  bouyer 	mov.b		&DENORM, %d0
   22596  1.1.6.2  bouyer 	rts
   22597  1.1.6.2  bouyer inf_or_nan_d:
   22598  1.1.6.2  bouyer 	and.l		&0x000fffff, %d1
   22599  1.1.6.2  bouyer 	bne		is_nan_d
   22600  1.1.6.2  bouyer 	tst.l		4+FTEMP(%a0)
   22601  1.1.6.2  bouyer 	bne		is_nan_d
   22602  1.1.6.2  bouyer is_inf_d:
   22603  1.1.6.2  bouyer 	mov.b		&INF, %d0
   22604  1.1.6.2  bouyer 	rts
   22605  1.1.6.2  bouyer is_nan_d:
   22606  1.1.6.2  bouyer 	btst		&19, %d1
   22607  1.1.6.2  bouyer 	bne		is_qnan_d
   22608  1.1.6.2  bouyer is_snan_d:
   22609  1.1.6.2  bouyer 	mov.b		&SNAN, %d0
   22610  1.1.6.2  bouyer 	rts
   22611  1.1.6.2  bouyer is_qnan_d:
   22612  1.1.6.2  bouyer 	mov.b		&QNAN, %d0
   22613  1.1.6.2  bouyer 	rts
   22614  1.1.6.2  bouyer 
   22615  1.1.6.2  bouyer #########################################################################
   22616  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22617  1.1.6.2  bouyer # 	set_tag_s(): return the optype of the input sgl fp number	#
   22618  1.1.6.2  bouyer #									#
   22619  1.1.6.2  bouyer # XREF ****************************************************************	#
   22620  1.1.6.2  bouyer #	None								#
   22621  1.1.6.2  bouyer #									#
   22622  1.1.6.2  bouyer # INPUT ***************************************************************	#
   22623  1.1.6.2  bouyer #	a0 = pointer to single precision operand			#
   22624  1.1.6.2  bouyer # 									#
   22625  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   22626  1.1.6.2  bouyer #	d0 = value of type tag						#
   22627  1.1.6.2  bouyer # 		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
   22628  1.1.6.2  bouyer #									#
   22629  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   22630  1.1.6.2  bouyer #	Simply test the exponent, j-bit, and mantissa values to 	#
   22631  1.1.6.2  bouyer # determine the type of operand.					#
   22632  1.1.6.2  bouyer #									#
   22633  1.1.6.2  bouyer #########################################################################
   22634  1.1.6.2  bouyer 
   22635  1.1.6.2  bouyer 	global		set_tag_s
   22636  1.1.6.2  bouyer set_tag_s:
   22637  1.1.6.2  bouyer 	mov.l		FTEMP(%a0), %d0
   22638  1.1.6.2  bouyer 	mov.l		%d0, %d1
   22639  1.1.6.2  bouyer 
   22640  1.1.6.2  bouyer 	andi.l		&0x7f800000, %d0
   22641  1.1.6.2  bouyer 	beq.b		zero_or_denorm_s
   22642  1.1.6.2  bouyer 
   22643  1.1.6.2  bouyer 	cmpi.l		%d0, &0x7f800000
   22644  1.1.6.2  bouyer 	beq.b		inf_or_nan_s
   22645  1.1.6.2  bouyer 
   22646  1.1.6.2  bouyer is_norm_s:
   22647  1.1.6.2  bouyer 	mov.b		&NORM, %d0
   22648  1.1.6.2  bouyer 	rts
   22649  1.1.6.2  bouyer zero_or_denorm_s:
   22650  1.1.6.2  bouyer 	and.l		&0x007fffff, %d1
   22651  1.1.6.2  bouyer 	bne		is_denorm_s
   22652  1.1.6.2  bouyer is_zero_s:
   22653  1.1.6.2  bouyer 	mov.b		&ZERO, %d0
   22654  1.1.6.2  bouyer 	rts
   22655  1.1.6.2  bouyer is_denorm_s:
   22656  1.1.6.2  bouyer 	mov.b		&DENORM, %d0
   22657  1.1.6.2  bouyer 	rts
   22658  1.1.6.2  bouyer inf_or_nan_s:
   22659  1.1.6.2  bouyer 	and.l		&0x007fffff, %d1
   22660  1.1.6.2  bouyer 	bne		is_nan_s
   22661  1.1.6.2  bouyer is_inf_s:
   22662  1.1.6.2  bouyer 	mov.b		&INF, %d0
   22663  1.1.6.2  bouyer 	rts
   22664  1.1.6.2  bouyer is_nan_s:
   22665  1.1.6.2  bouyer 	btst		&22, %d1
   22666  1.1.6.2  bouyer 	bne		is_qnan_s
   22667  1.1.6.2  bouyer is_snan_s:
   22668  1.1.6.2  bouyer 	mov.b		&SNAN, %d0
   22669  1.1.6.2  bouyer 	rts
   22670  1.1.6.2  bouyer is_qnan_s:
   22671  1.1.6.2  bouyer 	mov.b		&QNAN, %d0
   22672  1.1.6.2  bouyer 	rts
   22673  1.1.6.2  bouyer 
   22674  1.1.6.2  bouyer #########################################################################
   22675  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22676  1.1.6.2  bouyer # 	unf_res(): routine to produce default underflow result of a 	#
   22677  1.1.6.2  bouyer #	 	   scaled extended precision number; this is used by 	#
   22678  1.1.6.2  bouyer #		   fadd/fdiv/fmul/etc. emulation routines.		#
   22679  1.1.6.2  bouyer # 	unf_res4(): same as above but for fsglmul/fsgldiv which use	#
   22680  1.1.6.2  bouyer #		    single round prec and extended prec mode.		#
   22681  1.1.6.2  bouyer #									#
   22682  1.1.6.2  bouyer # XREF ****************************************************************	#
   22683  1.1.6.2  bouyer #	_denorm() - denormalize according to scale factor		#
   22684  1.1.6.2  bouyer # 	_round() - round denormalized number according to rnd prec	#
   22685  1.1.6.2  bouyer #									#
   22686  1.1.6.2  bouyer # INPUT ***************************************************************	#
   22687  1.1.6.2  bouyer #	a0 = pointer to extended precison operand			#
   22688  1.1.6.2  bouyer #	d0 = scale factor						#
   22689  1.1.6.2  bouyer #	d1 = rounding precision/mode					#
   22690  1.1.6.2  bouyer #									#
   22691  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   22692  1.1.6.2  bouyer #	a0 = pointer to default underflow result in extended precision	#
   22693  1.1.6.2  bouyer #	d0.b = result FPSR_cc which caller may or may not want to save	#
   22694  1.1.6.2  bouyer #									#
   22695  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   22696  1.1.6.2  bouyer # 	Convert the input operand to "internal format" which means the	#
   22697  1.1.6.2  bouyer # exponent is extended to 16 bits and the sign is stored in the unused	#
   22698  1.1.6.2  bouyer # portion of the extended precison operand. Denormalize the number	#
   22699  1.1.6.2  bouyer # according to the scale factor passed in d0. Then, round the 		#
   22700  1.1.6.2  bouyer # denormalized result.							#
   22701  1.1.6.2  bouyer # 	Set the FPSR_exc bits as appropriate but return the cc bits in	#
   22702  1.1.6.2  bouyer # d0 in case the caller doesn't want to save them (as is the case for	#
   22703  1.1.6.2  bouyer # fmove out).								#
   22704  1.1.6.2  bouyer # 	unf_res4() for fsglmul/fsgldiv forces the denorm to extended	#
   22705  1.1.6.2  bouyer # precision and the rounding mode to single.				#
   22706  1.1.6.2  bouyer #									#
   22707  1.1.6.2  bouyer #########################################################################
   22708  1.1.6.2  bouyer 	global		unf_res
   22709  1.1.6.2  bouyer unf_res:
   22710  1.1.6.2  bouyer 	mov.l		%d1, -(%sp)		# save rnd prec,mode on stack
   22711  1.1.6.2  bouyer 
   22712  1.1.6.2  bouyer 	btst		&0x7, FTEMP_EX(%a0)	# make "internal" format
   22713  1.1.6.2  bouyer 	sne		FTEMP_SGN(%a0)
   22714  1.1.6.2  bouyer 
   22715  1.1.6.2  bouyer 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
   22716  1.1.6.2  bouyer 	and.w		&0x7fff, %d1
   22717  1.1.6.2  bouyer 	sub.w		%d0, %d1
   22718  1.1.6.2  bouyer 	mov.w		%d1, FTEMP_EX(%a0)	# insert 16 bit exponent
   22719  1.1.6.2  bouyer 
   22720  1.1.6.2  bouyer 	mov.l		%a0, -(%sp)		# save operand ptr during calls
   22721  1.1.6.2  bouyer 
   22722  1.1.6.2  bouyer 	mov.l		0x4(%sp),%d0		# pass rnd prec.
   22723  1.1.6.2  bouyer 	andi.w		&0x00c0,%d0
   22724  1.1.6.2  bouyer 	lsr.w		&0x4,%d0
   22725  1.1.6.2  bouyer 	bsr.l		_denorm			# denorm result
   22726  1.1.6.2  bouyer 
   22727  1.1.6.2  bouyer 	mov.l		(%sp),%a0
   22728  1.1.6.2  bouyer 	mov.w		0x6(%sp),%d1		# load prec:mode into %d1
   22729  1.1.6.2  bouyer 	andi.w		&0xc0,%d1		# extract rnd prec
   22730  1.1.6.2  bouyer 	lsr.w		&0x4,%d1
   22731  1.1.6.2  bouyer 	swap		%d1
   22732  1.1.6.2  bouyer 	mov.w		0x6(%sp),%d1
   22733  1.1.6.2  bouyer 	andi.w		&0x30,%d1
   22734  1.1.6.2  bouyer 	lsr.w		&0x4,%d1
   22735  1.1.6.2  bouyer 	bsr.l		_round			# round the denorm
   22736  1.1.6.2  bouyer 
   22737  1.1.6.2  bouyer 	mov.l		(%sp)+, %a0
   22738  1.1.6.2  bouyer 
   22739  1.1.6.2  bouyer # result is now rounded properly. convert back to normal format
   22740  1.1.6.2  bouyer 	bclr		&0x7, FTEMP_EX(%a0)	# clear sgn first; may have residue
   22741  1.1.6.2  bouyer 	tst.b		FTEMP_SGN(%a0)		# is "internal result" sign set?
   22742  1.1.6.2  bouyer 	beq.b		unf_res_chkifzero	# no; result is positive
   22743  1.1.6.2  bouyer 	bset		&0x7, FTEMP_EX(%a0)	# set result sgn
   22744  1.1.6.2  bouyer 	clr.b		FTEMP_SGN(%a0)		# clear temp sign
   22745  1.1.6.2  bouyer 
   22746  1.1.6.2  bouyer # the number may have become zero after rounding. set ccodes accordingly.
   22747  1.1.6.2  bouyer unf_res_chkifzero:
   22748  1.1.6.2  bouyer 	clr.l		%d0
   22749  1.1.6.2  bouyer 	tst.l		FTEMP_HI(%a0)		# is value now a zero?
   22750  1.1.6.2  bouyer 	bne.b		unf_res_cont		# no
   22751  1.1.6.2  bouyer 	tst.l		FTEMP_LO(%a0)
   22752  1.1.6.2  bouyer 	bne.b		unf_res_cont		# no
   22753  1.1.6.2  bouyer #	bset		&z_bit, FPSR_CC(%a6)	# yes; set zero ccode bit
   22754  1.1.6.2  bouyer 	bset		&z_bit, %d0		# yes; set zero ccode bit
   22755  1.1.6.2  bouyer 
   22756  1.1.6.2  bouyer unf_res_cont:
   22757  1.1.6.2  bouyer 
   22758  1.1.6.2  bouyer #
   22759  1.1.6.2  bouyer # can inex1 also be set along with unfl and inex2???
   22760  1.1.6.2  bouyer #
   22761  1.1.6.2  bouyer # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
   22762  1.1.6.2  bouyer #
   22763  1.1.6.2  bouyer 	btst		&inex2_bit, FPSR_EXCEPT(%a6) # is INEX2 set?
   22764  1.1.6.2  bouyer 	beq.b		unf_res_end		# no
   22765  1.1.6.2  bouyer 	bset		&aunfl_bit, FPSR_AEXCEPT(%a6) # yes; set aunfl
   22766  1.1.6.2  bouyer 
   22767  1.1.6.2  bouyer unf_res_end:
   22768  1.1.6.2  bouyer 	add.l		&0x4, %sp		# clear stack
   22769  1.1.6.2  bouyer 	rts
   22770  1.1.6.2  bouyer 
   22771  1.1.6.2  bouyer # unf_res() for fsglmul() and fsgldiv().
   22772  1.1.6.2  bouyer 	global		unf_res4
   22773  1.1.6.2  bouyer unf_res4:
   22774  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# save rnd prec,mode on stack
   22775  1.1.6.2  bouyer 
   22776  1.1.6.2  bouyer 	btst		&0x7,FTEMP_EX(%a0)	# make "internal" format
   22777  1.1.6.2  bouyer 	sne		FTEMP_SGN(%a0)
   22778  1.1.6.2  bouyer 
   22779  1.1.6.2  bouyer 	mov.w		FTEMP_EX(%a0),%d1	# extract exponent
   22780  1.1.6.2  bouyer 	and.w		&0x7fff,%d1
   22781  1.1.6.2  bouyer 	sub.w		%d0,%d1
   22782  1.1.6.2  bouyer 	mov.w		%d1,FTEMP_EX(%a0)	# insert 16 bit exponent
   22783  1.1.6.2  bouyer 
   22784  1.1.6.2  bouyer 	mov.l		%a0,-(%sp)		# save operand ptr during calls
   22785  1.1.6.2  bouyer 
   22786  1.1.6.2  bouyer 	clr.l		%d0			# force rnd prec = ext
   22787  1.1.6.2  bouyer 	bsr.l		_denorm			# denorm result
   22788  1.1.6.2  bouyer 
   22789  1.1.6.2  bouyer 	mov.l		(%sp),%a0
   22790  1.1.6.2  bouyer 	mov.w		&s_mode,%d1		# force rnd prec = sgl
   22791  1.1.6.2  bouyer 	swap		%d1
   22792  1.1.6.2  bouyer 	mov.w		0x6(%sp),%d1		# load rnd mode
   22793  1.1.6.2  bouyer 	andi.w		&0x30,%d1		# extract rnd prec
   22794  1.1.6.2  bouyer 	lsr.w		&0x4,%d1
   22795  1.1.6.2  bouyer 	bsr.l		_round			# round the denorm
   22796  1.1.6.2  bouyer 
   22797  1.1.6.2  bouyer 	mov.l		(%sp)+,%a0
   22798  1.1.6.2  bouyer 
   22799  1.1.6.2  bouyer # result is now rounded properly. convert back to normal format
   22800  1.1.6.2  bouyer 	bclr		&0x7,FTEMP_EX(%a0)	# clear sgn first; may have residue
   22801  1.1.6.2  bouyer 	tst.b		FTEMP_SGN(%a0)		# is "internal result" sign set?
   22802  1.1.6.2  bouyer 	beq.b		unf_res4_chkifzero	# no; result is positive
   22803  1.1.6.2  bouyer 	bset		&0x7,FTEMP_EX(%a0)	# set result sgn
   22804  1.1.6.2  bouyer 	clr.b		FTEMP_SGN(%a0)		# clear temp sign
   22805  1.1.6.2  bouyer 
   22806  1.1.6.2  bouyer # the number may have become zero after rounding. set ccodes accordingly.
   22807  1.1.6.2  bouyer unf_res4_chkifzero:
   22808  1.1.6.2  bouyer 	clr.l		%d0
   22809  1.1.6.2  bouyer 	tst.l		FTEMP_HI(%a0)		# is value now a zero?
   22810  1.1.6.2  bouyer 	bne.b		unf_res4_cont		# no
   22811  1.1.6.2  bouyer 	tst.l		FTEMP_LO(%a0)
   22812  1.1.6.2  bouyer 	bne.b		unf_res4_cont		# no
   22813  1.1.6.2  bouyer #	bset		&z_bit,FPSR_CC(%a6)	# yes; set zero ccode bit
   22814  1.1.6.2  bouyer 	bset		&z_bit,%d0		# yes; set zero ccode bit
   22815  1.1.6.2  bouyer 
   22816  1.1.6.2  bouyer unf_res4_cont:
   22817  1.1.6.2  bouyer 
   22818  1.1.6.2  bouyer #
   22819  1.1.6.2  bouyer # can inex1 also be set along with unfl and inex2???
   22820  1.1.6.2  bouyer #
   22821  1.1.6.2  bouyer # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
   22822  1.1.6.2  bouyer #
   22823  1.1.6.2  bouyer 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
   22824  1.1.6.2  bouyer 	beq.b		unf_res4_end		# no
   22825  1.1.6.2  bouyer 	bset		&aunfl_bit,FPSR_AEXCEPT(%a6) # yes; set aunfl
   22826  1.1.6.2  bouyer 
   22827  1.1.6.2  bouyer unf_res4_end:
   22828  1.1.6.2  bouyer 	add.l		&0x4,%sp		# clear stack
   22829  1.1.6.2  bouyer 	rts
   22830  1.1.6.2  bouyer 
   22831  1.1.6.2  bouyer #########################################################################
   22832  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22833  1.1.6.2  bouyer #	ovf_res(): routine to produce the default overflow result of	#
   22834  1.1.6.2  bouyer #		   an overflowing number.				#
   22835  1.1.6.2  bouyer #	ovf_res2(): same as above but the rnd mode/prec are passed	#
   22836  1.1.6.2  bouyer #		    differently.					#
   22837  1.1.6.2  bouyer #									#
   22838  1.1.6.2  bouyer # XREF ****************************************************************	#
   22839  1.1.6.2  bouyer #	none								#
   22840  1.1.6.2  bouyer #									#
   22841  1.1.6.2  bouyer # INPUT ***************************************************************	#
   22842  1.1.6.2  bouyer #	d1.b 	= '-1' => (-); '0' => (+)				#
   22843  1.1.6.2  bouyer #   ovf_res():								#
   22844  1.1.6.2  bouyer #	d0 	= rnd mode/prec						#
   22845  1.1.6.2  bouyer #   ovf_res2():								#
   22846  1.1.6.2  bouyer #	hi(d0) 	= rnd prec						#
   22847  1.1.6.2  bouyer #	lo(d0)	= rnd mode						#
   22848  1.1.6.2  bouyer #									#
   22849  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   22850  1.1.6.2  bouyer #	a0   	= points to extended precision result			#
   22851  1.1.6.2  bouyer #	d0.b 	= condition code bits					#
   22852  1.1.6.2  bouyer #									#
   22853  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   22854  1.1.6.2  bouyer #	The default overflow result can be determined by the sign of	#
   22855  1.1.6.2  bouyer # the result and the rounding mode/prec in effect. These bits are	#
   22856  1.1.6.2  bouyer # concatenated together to create an index into the default result 	#
   22857  1.1.6.2  bouyer # table. A pointer to the correct result is returned in a0. The		#
   22858  1.1.6.2  bouyer # resulting condition codes are returned in d0 in case the caller 	#
   22859  1.1.6.2  bouyer # doesn't want FPSR_cc altered (as is the case for fmove out).		#
   22860  1.1.6.2  bouyer #									#
   22861  1.1.6.2  bouyer #########################################################################
   22862  1.1.6.2  bouyer 
   22863  1.1.6.2  bouyer 	global		ovf_res
   22864  1.1.6.2  bouyer ovf_res:
   22865  1.1.6.2  bouyer 	andi.w		&0x10,%d1		# keep result sign
   22866  1.1.6.2  bouyer 	lsr.b		&0x4,%d0		# shift prec/mode
   22867  1.1.6.2  bouyer 	or.b		%d0,%d1			# concat the two
   22868  1.1.6.2  bouyer 	mov.w		%d1,%d0			# make a copy
   22869  1.1.6.2  bouyer 	lsl.b		&0x1,%d1		# multiply d1 by 2
   22870  1.1.6.2  bouyer 	bra.b		ovf_res_load
   22871  1.1.6.2  bouyer 
   22872  1.1.6.2  bouyer 	global		ovf_res2
   22873  1.1.6.2  bouyer ovf_res2:
   22874  1.1.6.2  bouyer 	and.w		&0x10, %d1		# keep result sign
   22875  1.1.6.2  bouyer 	or.b		%d0, %d1		# insert rnd mode
   22876  1.1.6.2  bouyer 	swap		%d0
   22877  1.1.6.2  bouyer 	or.b		%d0, %d1		# insert rnd prec
   22878  1.1.6.2  bouyer 	mov.w		%d1, %d0		# make a copy
   22879  1.1.6.2  bouyer 	lsl.b		&0x1, %d1		# shift left by 1
   22880  1.1.6.2  bouyer 
   22881  1.1.6.2  bouyer #
   22882  1.1.6.2  bouyer # use the rounding mode, precision, and result sign as in index into the
   22883  1.1.6.2  bouyer # two tables below to fetch the default result and the result ccodes.
   22884  1.1.6.2  bouyer #
   22885  1.1.6.2  bouyer ovf_res_load:
   22886  1.1.6.2  bouyer 	mov.b		(tbl_ovfl_cc.b,%pc,%d0.w*1), %d0 # fetch result ccodes
   22887  1.1.6.2  bouyer 	lea		(tbl_ovfl_result.b,%pc,%d1.w*8), %a0 # return result ptr
   22888  1.1.6.2  bouyer 
   22889  1.1.6.2  bouyer 	rts
   22890  1.1.6.2  bouyer 
   22891  1.1.6.2  bouyer tbl_ovfl_cc:
   22892  1.1.6.2  bouyer 	byte		0x2, 0x0, 0x0, 0x2
   22893  1.1.6.2  bouyer 	byte		0x2, 0x0, 0x0, 0x2
   22894  1.1.6.2  bouyer 	byte		0x2, 0x0, 0x0, 0x2
   22895  1.1.6.2  bouyer 	byte		0x0, 0x0, 0x0, 0x0
   22896  1.1.6.2  bouyer 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
   22897  1.1.6.2  bouyer 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
   22898  1.1.6.2  bouyer 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
   22899  1.1.6.2  bouyer 
   22900  1.1.6.2  bouyer tbl_ovfl_result:
   22901  1.1.6.2  bouyer 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
   22902  1.1.6.2  bouyer 	long		0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RZ
   22903  1.1.6.2  bouyer 	long		0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RM
   22904  1.1.6.2  bouyer 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
   22905  1.1.6.2  bouyer 
   22906  1.1.6.2  bouyer 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
   22907  1.1.6.2  bouyer 	long		0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RZ
   22908  1.1.6.2  bouyer 	long		0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RM
   22909  1.1.6.2  bouyer 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
   22910  1.1.6.2  bouyer 
   22911  1.1.6.2  bouyer 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
   22912  1.1.6.2  bouyer 	long		0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RZ
   22913  1.1.6.2  bouyer 	long		0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RM
   22914  1.1.6.2  bouyer 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
   22915  1.1.6.2  bouyer 
   22916  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22917  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22918  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22919  1.1.6.2  bouyer 	long		0x00000000,0x00000000,0x00000000,0x00000000
   22920  1.1.6.2  bouyer 
   22921  1.1.6.2  bouyer 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
   22922  1.1.6.2  bouyer 	long		0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RZ
   22923  1.1.6.2  bouyer 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
   22924  1.1.6.2  bouyer 	long		0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RP
   22925  1.1.6.2  bouyer 
   22926  1.1.6.2  bouyer 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
   22927  1.1.6.2  bouyer 	long		0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RZ
   22928  1.1.6.2  bouyer 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
   22929  1.1.6.2  bouyer 	long		0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RP
   22930  1.1.6.2  bouyer 
   22931  1.1.6.2  bouyer 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
   22932  1.1.6.2  bouyer 	long		0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RZ
   22933  1.1.6.2  bouyer 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
   22934  1.1.6.2  bouyer 	long		0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RP
   22935  1.1.6.2  bouyer 
   22936  1.1.6.2  bouyer #########################################################################
   22937  1.1.6.2  bouyer # XDEF ****************************************************************	#
   22938  1.1.6.2  bouyer #	get_packed(): fetch a packed operand from memory and then	#
   22939  1.1.6.2  bouyer #		      convert it to a floating-point binary number.	#
   22940  1.1.6.2  bouyer #									#
   22941  1.1.6.2  bouyer # XREF ****************************************************************	#
   22942  1.1.6.2  bouyer #	_dcalc_ea() - calculate the correct <ea>			#
   22943  1.1.6.2  bouyer #	_mem_read() - fetch the packed operand from memory		#
   22944  1.1.6.2  bouyer #	facc_in_x() - the fetch failed so jump to special exit code	#
   22945  1.1.6.2  bouyer #	decbin()    - convert packed to binary extended precision	#
   22946  1.1.6.2  bouyer #									#
   22947  1.1.6.2  bouyer # INPUT ***************************************************************	#
   22948  1.1.6.2  bouyer #	None								#
   22949  1.1.6.2  bouyer # 									#
   22950  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   22951  1.1.6.2  bouyer #	If no failure on _mem_read():					#
   22952  1.1.6.2  bouyer # 	FP_SRC(a6) = packed operand now as a binary FP number		#
   22953  1.1.6.2  bouyer #									#
   22954  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   22955  1.1.6.2  bouyer #	Get the correct <ea> whihc is the value on the exception stack 	#
   22956  1.1.6.2  bouyer # frame w/ maybe a correction factor if the <ea> is -(an) or (an)+.	#
   22957  1.1.6.2  bouyer # Then, fetch the operand from memory. If the fetch fails, exit		#
   22958  1.1.6.2  bouyer # through facc_in_x().							#
   22959  1.1.6.2  bouyer #	If the packed operand is a ZERO,NAN, or INF, convert it to	#
   22960  1.1.6.2  bouyer # its binary representation here. Else, call decbin() which will 	#
   22961  1.1.6.2  bouyer # convert the packed value to an extended precision binary value.	#
   22962  1.1.6.2  bouyer #									#
   22963  1.1.6.2  bouyer #########################################################################
   22964  1.1.6.2  bouyer 
   22965  1.1.6.2  bouyer # the stacked <ea> for packed is correct except for -(An).
   22966  1.1.6.2  bouyer # the base reg must be updated for both -(An) and (An)+.
   22967  1.1.6.2  bouyer 	global		get_packed
   22968  1.1.6.2  bouyer get_packed:
   22969  1.1.6.2  bouyer 	mov.l		&0xc,%d0		# packed is 12 bytes
   22970  1.1.6.2  bouyer 	bsr.l		_dcalc_ea		# fetch <ea>; correct An
   22971  1.1.6.2  bouyer 
   22972  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a1		# pass: ptr to super dst
   22973  1.1.6.2  bouyer 	mov.l		&0xc,%d0		# pass: 12 bytes
   22974  1.1.6.2  bouyer 	bsr.l		_dmem_read		# read packed operand
   22975  1.1.6.2  bouyer 
   22976  1.1.6.2  bouyer 	tst.l		%d1			# did dfetch fail?
   22977  1.1.6.2  bouyer 	bne.l		facc_in_x		# yes
   22978  1.1.6.2  bouyer 
   22979  1.1.6.2  bouyer # The packed operand is an INF or a NAN if the exponent field is all ones.
   22980  1.1.6.2  bouyer 	bfextu		FP_SRC(%a6){&1:&15},%d0	# get exp
   22981  1.1.6.2  bouyer 	cmpi.w		%d0,&0x7fff		# INF or NAN?
   22982  1.1.6.2  bouyer 	bne.b		gp_try_zero		# no
   22983  1.1.6.2  bouyer 	rts					# operand is an INF or NAN
   22984  1.1.6.2  bouyer 
   22985  1.1.6.2  bouyer # The packed operand is a zero if the mantissa is all zero, else it's
   22986  1.1.6.2  bouyer # a normal packed op.
   22987  1.1.6.2  bouyer gp_try_zero:
   22988  1.1.6.2  bouyer 	mov.b		3+FP_SRC(%a6),%d0	# get byte 4
   22989  1.1.6.2  bouyer 	andi.b		&0x0f,%d0		# clear all but last nybble
   22990  1.1.6.2  bouyer 	bne.b		gp_not_spec		# not a zero
   22991  1.1.6.2  bouyer 	tst.l		FP_SRC_HI(%a6)		# is lw 2 zero?
   22992  1.1.6.2  bouyer 	bne.b		gp_not_spec		# not a zero
   22993  1.1.6.2  bouyer 	tst.l		FP_SRC_LO(%a6)		# is lw 3 zero?
   22994  1.1.6.2  bouyer 	bne.b		gp_not_spec		# not a zero
   22995  1.1.6.2  bouyer 	rts					# operand is a ZERO
   22996  1.1.6.2  bouyer gp_not_spec:
   22997  1.1.6.2  bouyer 	lea		FP_SRC(%a6),%a0		# pass: ptr to packed op
   22998  1.1.6.2  bouyer 	bsr.l		decbin			# convert to extended
   22999  1.1.6.2  bouyer 	fmovm.x		&0x80,FP_SRC(%a6)	# make this the srcop
   23000  1.1.6.2  bouyer 	rts
   23001  1.1.6.2  bouyer 
   23002  1.1.6.2  bouyer #########################################################################
   23003  1.1.6.2  bouyer # decbin(): Converts normalized packed bcd value pointed to by register	#
   23004  1.1.6.2  bouyer #	    a0 to extended-precision value in fp0.			#
   23005  1.1.6.2  bouyer #									#
   23006  1.1.6.2  bouyer # INPUT ***************************************************************	#
   23007  1.1.6.2  bouyer #	a0 = pointer to normalized packed bcd value			#
   23008  1.1.6.2  bouyer #									#
   23009  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   23010  1.1.6.2  bouyer #	fp0 = exact fp representation of the packed bcd value.		#
   23011  1.1.6.2  bouyer #									#
   23012  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   23013  1.1.6.2  bouyer #	Expected is a normal bcd (i.e. non-exceptional; all inf, zero,	#
   23014  1.1.6.2  bouyer #	and NaN operands are dispatched without entering this routine)	#
   23015  1.1.6.2  bouyer #	value in 68881/882 format at location (a0).			#
   23016  1.1.6.2  bouyer #									#
   23017  1.1.6.2  bouyer #	A1. Convert the bcd exponent to binary by successive adds and 	#
   23018  1.1.6.2  bouyer #	muls. Set the sign according to SE. Subtract 16 to compensate	#
   23019  1.1.6.2  bouyer #	for the mantissa which is to be interpreted as 17 integer	#
   23020  1.1.6.2  bouyer #	digits, rather than 1 integer and 16 fraction digits.		#
   23021  1.1.6.2  bouyer #	Note: this operation can never overflow.			#
   23022  1.1.6.2  bouyer #									#
   23023  1.1.6.2  bouyer #	A2. Convert the bcd mantissa to binary by successive		#
   23024  1.1.6.2  bouyer #	adds and muls in FP0. Set the sign according to SM.		#
   23025  1.1.6.2  bouyer #	The mantissa digits will be converted with the decimal point	#
   23026  1.1.6.2  bouyer #	assumed following the least-significant digit.			#
   23027  1.1.6.2  bouyer #	Note: this operation can never overflow.			#
   23028  1.1.6.2  bouyer #									#
   23029  1.1.6.2  bouyer #	A3. Count the number of leading/trailing zeros in the		#
   23030  1.1.6.2  bouyer #	bcd string.  If SE is positive, count the leading zeros;	#
   23031  1.1.6.2  bouyer #	if negative, count the trailing zeros.  Set the adjusted	#
   23032  1.1.6.2  bouyer #	exponent equal to the exponent from A1 and the zero count	#
   23033  1.1.6.2  bouyer #	added if SM = 1 and subtracted if SM = 0.  Scale the		#
   23034  1.1.6.2  bouyer #	mantissa the equivalent of forcing in the bcd value:		#
   23035  1.1.6.2  bouyer #									#
   23036  1.1.6.2  bouyer #	SM = 0	a non-zero digit in the integer position		#
   23037  1.1.6.2  bouyer #	SM = 1	a non-zero digit in Mant0, lsd of the fraction		#
   23038  1.1.6.2  bouyer #									#
   23039  1.1.6.2  bouyer #	this will insure that any value, regardless of its		#
   23040  1.1.6.2  bouyer #	representation (ex. 0.1E2, 1E1, 10E0, 100E-1), is converted	#
   23041  1.1.6.2  bouyer #	consistently.							#
   23042  1.1.6.2  bouyer #									#
   23043  1.1.6.2  bouyer #	A4. Calculate the factor 10^exp in FP1 using a table of		#
   23044  1.1.6.2  bouyer #	10^(2^n) values.  To reduce the error in forming factors	#
   23045  1.1.6.2  bouyer #	greater than 10^27, a directed rounding scheme is used with	#
   23046  1.1.6.2  bouyer #	tables rounded to RN, RM, and RP, according to the table	#
   23047  1.1.6.2  bouyer #	in the comments of the pwrten section.				#
   23048  1.1.6.2  bouyer #									#
   23049  1.1.6.2  bouyer #	A5. Form the final binary number by scaling the mantissa by	#
   23050  1.1.6.2  bouyer #	the exponent factor.  This is done by multiplying the		#
   23051  1.1.6.2  bouyer #	mantissa in FP0 by the factor in FP1 if the adjusted		#
   23052  1.1.6.2  bouyer #	exponent sign is positive, and dividing FP0 by FP1 if		#
   23053  1.1.6.2  bouyer #	it is negative.							#
   23054  1.1.6.2  bouyer #									#
   23055  1.1.6.2  bouyer #	Clean up and return. Check if the final mul or div was inexact.	#
   23056  1.1.6.2  bouyer #	If so, set INEX1 in USER_FPSR.					#
   23057  1.1.6.2  bouyer #									#
   23058  1.1.6.2  bouyer #########################################################################
   23059  1.1.6.2  bouyer 
   23060  1.1.6.2  bouyer #
   23061  1.1.6.2  bouyer #	PTENRN, PTENRM, and PTENRP are arrays of powers of 10 rounded
   23062  1.1.6.2  bouyer #	to nearest, minus, and plus, respectively.  The tables include
   23063  1.1.6.2  bouyer #	10**{1,2,4,8,16,32,64,128,256,512,1024,2048,4096}.  No rounding
   23064  1.1.6.2  bouyer #	is required until the power is greater than 27, however, all
   23065  1.1.6.2  bouyer #	tables include the first 5 for ease of indexing.
   23066  1.1.6.2  bouyer #
   23067  1.1.6.2  bouyer RTABLE:
   23068  1.1.6.2  bouyer 	byte		0,0,0,0
   23069  1.1.6.2  bouyer 	byte		2,3,2,3
   23070  1.1.6.2  bouyer 	byte		2,3,3,2
   23071  1.1.6.2  bouyer 	byte		3,2,2,3
   23072  1.1.6.2  bouyer 
   23073  1.1.6.2  bouyer 	set		FNIBS,7
   23074  1.1.6.2  bouyer 	set		FSTRT,0
   23075  1.1.6.2  bouyer 
   23076  1.1.6.2  bouyer 	set		ESTRT,4
   23077  1.1.6.2  bouyer 	set		EDIGITS,2
   23078  1.1.6.2  bouyer 
   23079  1.1.6.2  bouyer 	global		decbin
   23080  1.1.6.2  bouyer decbin:
   23081  1.1.6.2  bouyer 	mov.l		0x0(%a0),FP_SCR0_EX(%a6) # make a copy of input
   23082  1.1.6.2  bouyer 	mov.l		0x4(%a0),FP_SCR0_HI(%a6) # so we don't alter it
   23083  1.1.6.2  bouyer 	mov.l		0x8(%a0),FP_SCR0_LO(%a6)
   23084  1.1.6.2  bouyer 
   23085  1.1.6.2  bouyer 	lea		FP_SCR0(%a6),%a0
   23086  1.1.6.2  bouyer 
   23087  1.1.6.2  bouyer 	movm.l		&0x3c00,-(%sp)		# save d2-d5
   23088  1.1.6.2  bouyer 	fmovm.x		&0x1,-(%sp)		# save fp1
   23089  1.1.6.2  bouyer #
   23090  1.1.6.2  bouyer # Calculate exponent:
   23091  1.1.6.2  bouyer #  1. Copy bcd value in memory for use as a working copy.
   23092  1.1.6.2  bouyer #  2. Calculate absolute value of exponent in d1 by mul and add.
   23093  1.1.6.2  bouyer #  3. Correct for exponent sign.
   23094  1.1.6.2  bouyer #  4. Subtract 16 to compensate for interpreting the mant as all integer digits.
   23095  1.1.6.2  bouyer #     (i.e., all digits assumed left of the decimal point.)
   23096  1.1.6.2  bouyer #
   23097  1.1.6.2  bouyer # Register usage:
   23098  1.1.6.2  bouyer #
   23099  1.1.6.2  bouyer #  calc_e:
   23100  1.1.6.2  bouyer #	(*)  d0: temp digit storage
   23101  1.1.6.2  bouyer #	(*)  d1: accumulator for binary exponent
   23102  1.1.6.2  bouyer #	(*)  d2: digit count
   23103  1.1.6.2  bouyer #	(*)  d3: offset pointer
   23104  1.1.6.2  bouyer #	( )  d4: first word of bcd
   23105  1.1.6.2  bouyer #	( )  a0: pointer to working bcd value
   23106  1.1.6.2  bouyer #	( )  a6: pointer to original bcd value
   23107  1.1.6.2  bouyer #	(*)  FP_SCR1: working copy of original bcd value
   23108  1.1.6.2  bouyer #	(*)  L_SCR1: copy of original exponent word
   23109  1.1.6.2  bouyer #
   23110  1.1.6.2  bouyer calc_e:
   23111  1.1.6.2  bouyer 	mov.l		&EDIGITS,%d2		# # of nibbles (digits) in fraction part
   23112  1.1.6.2  bouyer 	mov.l		&ESTRT,%d3		# counter to pick up digits
   23113  1.1.6.2  bouyer 	mov.l		(%a0),%d4		# get first word of bcd
   23114  1.1.6.2  bouyer 	clr.l		%d1			# zero d1 for accumulator
   23115  1.1.6.2  bouyer e_gd:
   23116  1.1.6.2  bouyer 	mulu.l		&0xa,%d1		# mul partial product by one digit place
   23117  1.1.6.2  bouyer 	bfextu		%d4{%d3:&4},%d0		# get the digit and zero extend into d0
   23118  1.1.6.2  bouyer 	add.l		%d0,%d1			# d1 = d1 + d0
   23119  1.1.6.2  bouyer 	addq.b		&4,%d3			# advance d3 to the next digit
   23120  1.1.6.2  bouyer 	dbf.w		%d2,e_gd		# if we have used all 3 digits, exit loop
   23121  1.1.6.2  bouyer 	btst		&30,%d4			# get SE
   23122  1.1.6.2  bouyer 	beq.b		e_pos			# don't negate if pos
   23123  1.1.6.2  bouyer 	neg.l		%d1			# negate before subtracting
   23124  1.1.6.2  bouyer e_pos:
   23125  1.1.6.2  bouyer 	sub.l		&16,%d1			# sub to compensate for shift of mant
   23126  1.1.6.2  bouyer 	bge.b		e_save			# if still pos, do not neg
   23127  1.1.6.2  bouyer 	neg.l		%d1			# now negative, make pos and set SE
   23128  1.1.6.2  bouyer 	or.l		&0x40000000,%d4		# set SE in d4,
   23129  1.1.6.2  bouyer 	or.l		&0x40000000,(%a0)	# and in working bcd
   23130  1.1.6.2  bouyer e_save:
   23131  1.1.6.2  bouyer 	mov.l		%d1,-(%sp)		# save exp on stack
   23132  1.1.6.2  bouyer #
   23133  1.1.6.2  bouyer #
   23134  1.1.6.2  bouyer # Calculate mantissa:
   23135  1.1.6.2  bouyer #  1. Calculate absolute value of mantissa in fp0 by mul and add.
   23136  1.1.6.2  bouyer #  2. Correct for mantissa sign.
   23137  1.1.6.2  bouyer #     (i.e., all digits assumed left of the decimal point.)
   23138  1.1.6.2  bouyer #
   23139  1.1.6.2  bouyer # Register usage:
   23140  1.1.6.2  bouyer #
   23141  1.1.6.2  bouyer #  calc_m:
   23142  1.1.6.2  bouyer #	(*)  d0: temp digit storage
   23143  1.1.6.2  bouyer #	(*)  d1: lword counter
   23144  1.1.6.2  bouyer #	(*)  d2: digit count
   23145  1.1.6.2  bouyer #	(*)  d3: offset pointer
   23146  1.1.6.2  bouyer #	( )  d4: words 2 and 3 of bcd
   23147  1.1.6.2  bouyer #	( )  a0: pointer to working bcd value
   23148  1.1.6.2  bouyer #	( )  a6: pointer to original bcd value
   23149  1.1.6.2  bouyer #	(*) fp0: mantissa accumulator
   23150  1.1.6.2  bouyer #	( )  FP_SCR1: working copy of original bcd value
   23151  1.1.6.2  bouyer #	( )  L_SCR1: copy of original exponent word
   23152  1.1.6.2  bouyer #
   23153  1.1.6.2  bouyer calc_m:
   23154  1.1.6.2  bouyer 	mov.l		&1,%d1			# word counter, init to 1
   23155  1.1.6.2  bouyer 	fmov.s		&0x00000000,%fp0	# accumulator
   23156  1.1.6.2  bouyer #
   23157  1.1.6.2  bouyer #
   23158  1.1.6.2  bouyer #  Since the packed number has a long word between the first & second parts,
   23159  1.1.6.2  bouyer #  get the integer digit then skip down & get the rest of the
   23160  1.1.6.2  bouyer #  mantissa.  We will unroll the loop once.
   23161  1.1.6.2  bouyer #
   23162  1.1.6.2  bouyer 	bfextu		(%a0){&28:&4},%d0	# integer part is ls digit in long word
   23163  1.1.6.2  bouyer 	fadd.b		%d0,%fp0		# add digit to sum in fp0
   23164  1.1.6.2  bouyer #
   23165  1.1.6.2  bouyer #
   23166  1.1.6.2  bouyer #  Get the rest of the mantissa.
   23167  1.1.6.2  bouyer #
   23168  1.1.6.2  bouyer loadlw:
   23169  1.1.6.2  bouyer 	mov.l		(%a0,%d1.L*4),%d4	# load mantissa lonqword into d4
   23170  1.1.6.2  bouyer 	mov.l		&FSTRT,%d3		# counter to pick up digits
   23171  1.1.6.2  bouyer 	mov.l		&FNIBS,%d2		# reset number of digits per a0 ptr
   23172  1.1.6.2  bouyer md2b:
   23173  1.1.6.2  bouyer 	fmul.s		&0x41200000,%fp0	# fp0 = fp0 * 10
   23174  1.1.6.2  bouyer 	bfextu		%d4{%d3:&4},%d0		# get the digit and zero extend
   23175  1.1.6.2  bouyer 	fadd.b		%d0,%fp0		# fp0 = fp0 + digit
   23176  1.1.6.2  bouyer #
   23177  1.1.6.2  bouyer #
   23178  1.1.6.2  bouyer #  If all the digits (8) in that long word have been converted (d2=0),
   23179  1.1.6.2  bouyer #  then inc d1 (=2) to point to the next long word and reset d3 to 0
   23180  1.1.6.2  bouyer #  to initialize the digit offset, and set d2 to 7 for the digit count;
   23181  1.1.6.2  bouyer #  else continue with this long word.
   23182  1.1.6.2  bouyer #
   23183  1.1.6.2  bouyer 	addq.b		&4,%d3			# advance d3 to the next digit
   23184  1.1.6.2  bouyer 	dbf.w		%d2,md2b		# check for last digit in this lw
   23185  1.1.6.2  bouyer nextlw:
   23186  1.1.6.2  bouyer 	addq.l		&1,%d1			# inc lw pointer in mantissa
   23187  1.1.6.2  bouyer 	cmp.l		%d1,&2			# test for last lw
   23188  1.1.6.2  bouyer 	ble.b		loadlw			# if not, get last one
   23189  1.1.6.2  bouyer #
   23190  1.1.6.2  bouyer #  Check the sign of the mant and make the value in fp0 the same sign.
   23191  1.1.6.2  bouyer #
   23192  1.1.6.2  bouyer m_sign:
   23193  1.1.6.2  bouyer 	btst		&31,(%a0)		# test sign of the mantissa
   23194  1.1.6.2  bouyer 	beq.b		ap_st_z			# if clear, go to append/strip zeros
   23195  1.1.6.2  bouyer 	fneg.x		%fp0			# if set, negate fp0
   23196  1.1.6.2  bouyer #
   23197  1.1.6.2  bouyer # Append/strip zeros:
   23198  1.1.6.2  bouyer #
   23199  1.1.6.2  bouyer #  For adjusted exponents which have an absolute value greater than 27*,
   23200  1.1.6.2  bouyer #  this routine calculates the amount needed to normalize the mantissa
   23201  1.1.6.2  bouyer #  for the adjusted exponent.  That number is subtracted from the exp
   23202  1.1.6.2  bouyer #  if the exp was positive, and added if it was negative.  The purpose
   23203  1.1.6.2  bouyer #  of this is to reduce the value of the exponent and the possibility
   23204  1.1.6.2  bouyer #  of error in calculation of pwrten.
   23205  1.1.6.2  bouyer #
   23206  1.1.6.2  bouyer #  1. Branch on the sign of the adjusted exponent.
   23207  1.1.6.2  bouyer #  2p.(positive exp)
   23208  1.1.6.2  bouyer #   2. Check M16 and the digits in lwords 2 and 3 in decending order.
   23209  1.1.6.2  bouyer #   3. Add one for each zero encountered until a non-zero digit.
   23210  1.1.6.2  bouyer #   4. Subtract the count from the exp.
   23211  1.1.6.2  bouyer #   5. Check if the exp has crossed zero in #3 above; make the exp abs
   23212  1.1.6.2  bouyer #	   and set SE.
   23213  1.1.6.2  bouyer #	6. Multiply the mantissa by 10**count.
   23214  1.1.6.2  bouyer #  2n.(negative exp)
   23215  1.1.6.2  bouyer #   2. Check the digits in lwords 3 and 2 in decending order.
   23216  1.1.6.2  bouyer #   3. Add one for each zero encountered until a non-zero digit.
   23217  1.1.6.2  bouyer #   4. Add the count to the exp.
   23218  1.1.6.2  bouyer #   5. Check if the exp has crossed zero in #3 above; clear SE.
   23219  1.1.6.2  bouyer #   6. Divide the mantissa by 10**count.
   23220  1.1.6.2  bouyer #
   23221  1.1.6.2  bouyer #  *Why 27?  If the adjusted exponent is within -28 < expA < 28, than
   23222  1.1.6.2  bouyer #   any adjustment due to append/strip zeros will drive the resultane
   23223  1.1.6.2  bouyer #   exponent towards zero.  Since all pwrten constants with a power
   23224  1.1.6.2  bouyer #   of 27 or less are exact, there is no need to use this routine to
   23225  1.1.6.2  bouyer #   attempt to lessen the resultant exponent.
   23226  1.1.6.2  bouyer #
   23227  1.1.6.2  bouyer # Register usage:
   23228  1.1.6.2  bouyer #
   23229  1.1.6.2  bouyer #  ap_st_z:
   23230  1.1.6.2  bouyer #	(*)  d0: temp digit storage
   23231  1.1.6.2  bouyer #	(*)  d1: zero count
   23232  1.1.6.2  bouyer #	(*)  d2: digit count
   23233  1.1.6.2  bouyer #	(*)  d3: offset pointer
   23234  1.1.6.2  bouyer #	( )  d4: first word of bcd
   23235  1.1.6.2  bouyer #	(*)  d5: lword counter
   23236  1.1.6.2  bouyer #	( )  a0: pointer to working bcd value
   23237  1.1.6.2  bouyer #	( )  FP_SCR1: working copy of original bcd value
   23238  1.1.6.2  bouyer #	( )  L_SCR1: copy of original exponent word
   23239  1.1.6.2  bouyer #
   23240  1.1.6.2  bouyer #
   23241  1.1.6.2  bouyer # First check the absolute value of the exponent to see if this
   23242  1.1.6.2  bouyer # routine is necessary.  If so, then check the sign of the exponent
   23243  1.1.6.2  bouyer # and do append (+) or strip (-) zeros accordingly.
   23244  1.1.6.2  bouyer # This section handles a positive adjusted exponent.
   23245  1.1.6.2  bouyer #
   23246  1.1.6.2  bouyer ap_st_z:
   23247  1.1.6.2  bouyer 	mov.l		(%sp),%d1		# load expA for range test
   23248  1.1.6.2  bouyer 	cmp.l		%d1,&27			# test is with 27
   23249  1.1.6.2  bouyer 	ble.w		pwrten			# if abs(expA) <28, skip ap/st zeros
   23250  1.1.6.2  bouyer 	btst		&30,(%a0)		# check sign of exp
   23251  1.1.6.2  bouyer 	bne.b		ap_st_n			# if neg, go to neg side
   23252  1.1.6.2  bouyer 	clr.l		%d1			# zero count reg
   23253  1.1.6.2  bouyer 	mov.l		(%a0),%d4		# load lword 1 to d4
   23254  1.1.6.2  bouyer 	bfextu		%d4{&28:&4},%d0		# get M16 in d0
   23255  1.1.6.2  bouyer 	bne.b		ap_p_fx			# if M16 is non-zero, go fix exp
   23256  1.1.6.2  bouyer 	addq.l		&1,%d1			# inc zero count
   23257  1.1.6.2  bouyer 	mov.l		&1,%d5			# init lword counter
   23258  1.1.6.2  bouyer 	mov.l		(%a0,%d5.L*4),%d4	# get lword 2 to d4
   23259  1.1.6.2  bouyer 	bne.b		ap_p_cl			# if lw 2 is zero, skip it
   23260  1.1.6.2  bouyer 	addq.l		&8,%d1			# and inc count by 8
   23261  1.1.6.2  bouyer 	addq.l		&1,%d5			# inc lword counter
   23262  1.1.6.2  bouyer 	mov.l		(%a0,%d5.L*4),%d4	# get lword 3 to d4
   23263  1.1.6.2  bouyer ap_p_cl:
   23264  1.1.6.2  bouyer 	clr.l		%d3			# init offset reg
   23265  1.1.6.2  bouyer 	mov.l		&7,%d2			# init digit counter
   23266  1.1.6.2  bouyer ap_p_gd:
   23267  1.1.6.2  bouyer 	bfextu		%d4{%d3:&4},%d0		# get digit
   23268  1.1.6.2  bouyer 	bne.b		ap_p_fx			# if non-zero, go to fix exp
   23269  1.1.6.2  bouyer 	addq.l		&4,%d3			# point to next digit
   23270  1.1.6.2  bouyer 	addq.l		&1,%d1			# inc digit counter
   23271  1.1.6.2  bouyer 	dbf.w		%d2,ap_p_gd		# get next digit
   23272  1.1.6.2  bouyer ap_p_fx:
   23273  1.1.6.2  bouyer 	mov.l		%d1,%d0			# copy counter to d2
   23274  1.1.6.2  bouyer 	mov.l		(%sp),%d1		# get adjusted exp from memory
   23275  1.1.6.2  bouyer 	sub.l		%d0,%d1			# subtract count from exp
   23276  1.1.6.2  bouyer 	bge.b		ap_p_fm			# if still pos, go to pwrten
   23277  1.1.6.2  bouyer 	neg.l		%d1			# now its neg; get abs
   23278  1.1.6.2  bouyer 	mov.l		(%a0),%d4		# load lword 1 to d4
   23279  1.1.6.2  bouyer 	or.l		&0x40000000,%d4		# and set SE in d4
   23280  1.1.6.2  bouyer 	or.l		&0x40000000,(%a0)	# and in memory
   23281  1.1.6.2  bouyer #
   23282  1.1.6.2  bouyer # Calculate the mantissa multiplier to compensate for the striping of
   23283  1.1.6.2  bouyer # zeros from the mantissa.
   23284  1.1.6.2  bouyer #
   23285  1.1.6.2  bouyer ap_p_fm:
   23286  1.1.6.2  bouyer 	lea.l		PTENRN(%pc),%a1		# get address of power-of-ten table
   23287  1.1.6.2  bouyer 	clr.l		%d3			# init table index
   23288  1.1.6.2  bouyer 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
   23289  1.1.6.2  bouyer 	mov.l		&3,%d2			# init d2 to count bits in counter
   23290  1.1.6.2  bouyer ap_p_el:
   23291  1.1.6.2  bouyer 	asr.l		&1,%d0			# shift lsb into carry
   23292  1.1.6.2  bouyer 	bcc.b		ap_p_en			# if 1, mul fp1 by pwrten factor
   23293  1.1.6.2  bouyer 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
   23294  1.1.6.2  bouyer ap_p_en:
   23295  1.1.6.2  bouyer 	add.l		&12,%d3			# inc d3 to next rtable entry
   23296  1.1.6.2  bouyer 	tst.l		%d0			# check if d0 is zero
   23297  1.1.6.2  bouyer 	bne.b		ap_p_el			# if not, get next bit
   23298  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0		# mul mantissa by 10**(no_bits_shifted)
   23299  1.1.6.2  bouyer 	bra.b		pwrten			# go calc pwrten
   23300  1.1.6.2  bouyer #
   23301  1.1.6.2  bouyer # This section handles a negative adjusted exponent.
   23302  1.1.6.2  bouyer #
   23303  1.1.6.2  bouyer ap_st_n:
   23304  1.1.6.2  bouyer 	clr.l		%d1			# clr counter
   23305  1.1.6.2  bouyer 	mov.l		&2,%d5			# set up d5 to point to lword 3
   23306  1.1.6.2  bouyer 	mov.l		(%a0,%d5.L*4),%d4	# get lword 3
   23307  1.1.6.2  bouyer 	bne.b		ap_n_cl			# if not zero, check digits
   23308  1.1.6.2  bouyer 	sub.l		&1,%d5			# dec d5 to point to lword 2
   23309  1.1.6.2  bouyer 	addq.l		&8,%d1			# inc counter by 8
   23310  1.1.6.2  bouyer 	mov.l		(%a0,%d5.L*4),%d4	# get lword 2
   23311  1.1.6.2  bouyer ap_n_cl:
   23312  1.1.6.2  bouyer 	mov.l		&28,%d3			# point to last digit
   23313  1.1.6.2  bouyer 	mov.l		&7,%d2			# init digit counter
   23314  1.1.6.2  bouyer ap_n_gd:
   23315  1.1.6.2  bouyer 	bfextu		%d4{%d3:&4},%d0		# get digit
   23316  1.1.6.2  bouyer 	bne.b		ap_n_fx			# if non-zero, go to exp fix
   23317  1.1.6.2  bouyer 	subq.l		&4,%d3			# point to previous digit
   23318  1.1.6.2  bouyer 	addq.l		&1,%d1			# inc digit counter
   23319  1.1.6.2  bouyer 	dbf.w		%d2,ap_n_gd		# get next digit
   23320  1.1.6.2  bouyer ap_n_fx:
   23321  1.1.6.2  bouyer 	mov.l		%d1,%d0			# copy counter to d0
   23322  1.1.6.2  bouyer 	mov.l		(%sp),%d1		# get adjusted exp from memory
   23323  1.1.6.2  bouyer 	sub.l		%d0,%d1			# subtract count from exp
   23324  1.1.6.2  bouyer 	bgt.b		ap_n_fm			# if still pos, go fix mantissa
   23325  1.1.6.2  bouyer 	neg.l		%d1			# take abs of exp and clr SE
   23326  1.1.6.2  bouyer 	mov.l		(%a0),%d4		# load lword 1 to d4
   23327  1.1.6.2  bouyer 	and.l		&0xbfffffff,%d4		# and clr SE in d4
   23328  1.1.6.2  bouyer 	and.l		&0xbfffffff,(%a0)	# and in memory
   23329  1.1.6.2  bouyer #
   23330  1.1.6.2  bouyer # Calculate the mantissa multiplier to compensate for the appending of
   23331  1.1.6.2  bouyer # zeros to the mantissa.
   23332  1.1.6.2  bouyer #
   23333  1.1.6.2  bouyer ap_n_fm:
   23334  1.1.6.2  bouyer 	lea.l		PTENRN(%pc),%a1		# get address of power-of-ten table
   23335  1.1.6.2  bouyer 	clr.l		%d3			# init table index
   23336  1.1.6.2  bouyer 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
   23337  1.1.6.2  bouyer 	mov.l		&3,%d2			# init d2 to count bits in counter
   23338  1.1.6.2  bouyer ap_n_el:
   23339  1.1.6.2  bouyer 	asr.l		&1,%d0			# shift lsb into carry
   23340  1.1.6.2  bouyer 	bcc.b		ap_n_en			# if 1, mul fp1 by pwrten factor
   23341  1.1.6.2  bouyer 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
   23342  1.1.6.2  bouyer ap_n_en:
   23343  1.1.6.2  bouyer 	add.l		&12,%d3			# inc d3 to next rtable entry
   23344  1.1.6.2  bouyer 	tst.l		%d0			# check if d0 is zero
   23345  1.1.6.2  bouyer 	bne.b		ap_n_el			# if not, get next bit
   23346  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# div mantissa by 10**(no_bits_shifted)
   23347  1.1.6.2  bouyer #
   23348  1.1.6.2  bouyer #
   23349  1.1.6.2  bouyer # Calculate power-of-ten factor from adjusted and shifted exponent.
   23350  1.1.6.2  bouyer #
   23351  1.1.6.2  bouyer # Register usage:
   23352  1.1.6.2  bouyer #
   23353  1.1.6.2  bouyer #  pwrten:
   23354  1.1.6.2  bouyer #	(*)  d0: temp
   23355  1.1.6.2  bouyer #	( )  d1: exponent
   23356  1.1.6.2  bouyer #	(*)  d2: {FPCR[6:5],SM,SE} as index in RTABLE; temp
   23357  1.1.6.2  bouyer #	(*)  d3: FPCR work copy
   23358  1.1.6.2  bouyer #	( )  d4: first word of bcd
   23359  1.1.6.2  bouyer #	(*)  a1: RTABLE pointer
   23360  1.1.6.2  bouyer #  calc_p:
   23361  1.1.6.2  bouyer #	(*)  d0: temp
   23362  1.1.6.2  bouyer #	( )  d1: exponent
   23363  1.1.6.2  bouyer #	(*)  d3: PWRTxx table index
   23364  1.1.6.2  bouyer #	( )  a0: pointer to working copy of bcd
   23365  1.1.6.2  bouyer #	(*)  a1: PWRTxx pointer
   23366  1.1.6.2  bouyer #	(*) fp1: power-of-ten accumulator
   23367  1.1.6.2  bouyer #
   23368  1.1.6.2  bouyer # Pwrten calculates the exponent factor in the selected rounding mode
   23369  1.1.6.2  bouyer # according to the following table:
   23370  1.1.6.2  bouyer #
   23371  1.1.6.2  bouyer #	Sign of Mant  Sign of Exp  Rounding Mode  PWRTEN Rounding Mode
   23372  1.1.6.2  bouyer #
   23373  1.1.6.2  bouyer #	ANY	  ANY	RN	RN
   23374  1.1.6.2  bouyer #
   23375  1.1.6.2  bouyer #	 +	   +	RP	RP
   23376  1.1.6.2  bouyer #	 -	   +	RP	RM
   23377  1.1.6.2  bouyer #	 +	   -	RP	RM
   23378  1.1.6.2  bouyer #	 -	   -	RP	RP
   23379  1.1.6.2  bouyer #
   23380  1.1.6.2  bouyer #	 +	   +	RM	RM
   23381  1.1.6.2  bouyer #	 -	   +	RM	RP
   23382  1.1.6.2  bouyer #	 +	   -	RM	RP
   23383  1.1.6.2  bouyer #	 -	   -	RM	RM
   23384  1.1.6.2  bouyer #
   23385  1.1.6.2  bouyer #	 +	   +	RZ	RM
   23386  1.1.6.2  bouyer #	 -	   +	RZ	RM
   23387  1.1.6.2  bouyer #	 +	   -	RZ	RP
   23388  1.1.6.2  bouyer #	 -	   -	RZ	RP
   23389  1.1.6.2  bouyer #
   23390  1.1.6.2  bouyer #
   23391  1.1.6.2  bouyer pwrten:
   23392  1.1.6.2  bouyer 	mov.l		USER_FPCR(%a6),%d3	# get user's FPCR
   23393  1.1.6.2  bouyer 	bfextu		%d3{&26:&2},%d2		# isolate rounding mode bits
   23394  1.1.6.2  bouyer 	mov.l		(%a0),%d4		# reload 1st bcd word to d4
   23395  1.1.6.2  bouyer 	asl.l		&2,%d2			# format d2 to be
   23396  1.1.6.2  bouyer 	bfextu		%d4{&0:&2},%d0		# {FPCR[6],FPCR[5],SM,SE}
   23397  1.1.6.2  bouyer 	add.l		%d0,%d2			# in d2 as index into RTABLE
   23398  1.1.6.2  bouyer 	lea.l		RTABLE(%pc),%a1		# load rtable base
   23399  1.1.6.2  bouyer 	mov.b		(%a1,%d2),%d0		# load new rounding bits from table
   23400  1.1.6.2  bouyer 	clr.l		%d3			# clear d3 to force no exc and extended
   23401  1.1.6.2  bouyer 	bfins		%d0,%d3{&26:&2}		# stuff new rounding bits in FPCR
   23402  1.1.6.2  bouyer 	fmov.l		%d3,%fpcr		# write new FPCR
   23403  1.1.6.2  bouyer 	asr.l		&1,%d0			# write correct PTENxx table
   23404  1.1.6.2  bouyer 	bcc.b		not_rp			# to a1
   23405  1.1.6.2  bouyer 	lea.l		PTENRP(%pc),%a1		# it is RP
   23406  1.1.6.2  bouyer 	bra.b		calc_p			# go to init section
   23407  1.1.6.2  bouyer not_rp:
   23408  1.1.6.2  bouyer 	asr.l		&1,%d0			# keep checking
   23409  1.1.6.2  bouyer 	bcc.b		not_rm
   23410  1.1.6.2  bouyer 	lea.l		PTENRM(%pc),%a1		# it is RM
   23411  1.1.6.2  bouyer 	bra.b		calc_p			# go to init section
   23412  1.1.6.2  bouyer not_rm:
   23413  1.1.6.2  bouyer 	lea.l		PTENRN(%pc),%a1		# it is RN
   23414  1.1.6.2  bouyer calc_p:
   23415  1.1.6.2  bouyer 	mov.l		%d1,%d0			# copy exp to d0;use d0
   23416  1.1.6.2  bouyer 	bpl.b		no_neg			# if exp is negative,
   23417  1.1.6.2  bouyer 	neg.l		%d0			# invert it
   23418  1.1.6.2  bouyer 	or.l		&0x40000000,(%a0)	# and set SE bit
   23419  1.1.6.2  bouyer no_neg:
   23420  1.1.6.2  bouyer 	clr.l		%d3			# table index
   23421  1.1.6.2  bouyer 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
   23422  1.1.6.2  bouyer e_loop:
   23423  1.1.6.2  bouyer 	asr.l		&1,%d0			# shift next bit into carry
   23424  1.1.6.2  bouyer 	bcc.b		e_next			# if zero, skip the mul
   23425  1.1.6.2  bouyer 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
   23426  1.1.6.2  bouyer e_next:
   23427  1.1.6.2  bouyer 	add.l		&12,%d3			# inc d3 to next rtable entry
   23428  1.1.6.2  bouyer 	tst.l		%d0			# check if d0 is zero
   23429  1.1.6.2  bouyer 	bne.b		e_loop			# not zero, continue shifting
   23430  1.1.6.2  bouyer #
   23431  1.1.6.2  bouyer #
   23432  1.1.6.2  bouyer #  Check the sign of the adjusted exp and make the value in fp0 the
   23433  1.1.6.2  bouyer #  same sign. If the exp was pos then multiply fp1*fp0;
   23434  1.1.6.2  bouyer #  else divide fp0/fp1.
   23435  1.1.6.2  bouyer #
   23436  1.1.6.2  bouyer # Register Usage:
   23437  1.1.6.2  bouyer #  norm:
   23438  1.1.6.2  bouyer #	( )  a0: pointer to working bcd value
   23439  1.1.6.2  bouyer #	(*) fp0: mantissa accumulator
   23440  1.1.6.2  bouyer #	( ) fp1: scaling factor - 10**(abs(exp))
   23441  1.1.6.2  bouyer #
   23442  1.1.6.2  bouyer pnorm:
   23443  1.1.6.2  bouyer 	btst		&30,(%a0)		# test the sign of the exponent
   23444  1.1.6.2  bouyer 	beq.b		mul			# if clear, go to multiply
   23445  1.1.6.2  bouyer div:
   23446  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0		# exp is negative, so divide mant by exp
   23447  1.1.6.2  bouyer 	bra.b		end_dec
   23448  1.1.6.2  bouyer mul:
   23449  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0		# exp is positive, so multiply by exp
   23450  1.1.6.2  bouyer #
   23451  1.1.6.2  bouyer #
   23452  1.1.6.2  bouyer # Clean up and return with result in fp0.
   23453  1.1.6.2  bouyer #
   23454  1.1.6.2  bouyer # If the final mul/div in decbin incurred an inex exception,
   23455  1.1.6.2  bouyer # it will be inex2, but will be reported as inex1 by get_op.
   23456  1.1.6.2  bouyer #
   23457  1.1.6.2  bouyer end_dec:
   23458  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0		# get status register
   23459  1.1.6.2  bouyer 	bclr		&inex2_bit+8,%d0	# test for inex2 and clear it
   23460  1.1.6.2  bouyer 	beq.b		no_exc			# skip this if no exc
   23461  1.1.6.2  bouyer 	ori.w		&inx1a_mask,2+USER_FPSR(%a6) # set INEX1/AINEX
   23462  1.1.6.2  bouyer no_exc:
   23463  1.1.6.2  bouyer 	add.l		&0x4,%sp		# clear 1 lw param
   23464  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x40		# restore fp1
   23465  1.1.6.2  bouyer 	movm.l		(%sp)+,&0x3c		# restore d2-d5
   23466  1.1.6.2  bouyer 	fmov.l		&0x0,%fpcr
   23467  1.1.6.2  bouyer 	fmov.l		&0x0,%fpsr
   23468  1.1.6.2  bouyer 	rts
   23469  1.1.6.2  bouyer 
   23470  1.1.6.2  bouyer #########################################################################
   23471  1.1.6.2  bouyer # bindec(): Converts an input in extended precision format to bcd format#
   23472  1.1.6.2  bouyer #									#
   23473  1.1.6.2  bouyer # INPUT ***************************************************************	#
   23474  1.1.6.2  bouyer #	a0 = pointer to the input extended precision value in memory.	#
   23475  1.1.6.2  bouyer #	     the input may be either normalized, unnormalized, or 	#
   23476  1.1.6.2  bouyer #	     denormalized.						#
   23477  1.1.6.2  bouyer #	d0 = contains the k-factor sign-extended to 32-bits. 		#
   23478  1.1.6.2  bouyer #									#
   23479  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   23480  1.1.6.2  bouyer #	FP_SCR0(a6) = bcd format result on the stack.			#
   23481  1.1.6.2  bouyer #									#
   23482  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   23483  1.1.6.2  bouyer #									#
   23484  1.1.6.2  bouyer #	A1.	Set RM and size ext;  Set SIGMA = sign of input.  	#
   23485  1.1.6.2  bouyer #		The k-factor is saved for use in d7. Clear the		#
   23486  1.1.6.2  bouyer #		BINDEC_FLG for separating normalized/denormalized	#
   23487  1.1.6.2  bouyer #		input.  If input is unnormalized or denormalized,	#
   23488  1.1.6.2  bouyer #		normalize it.						#
   23489  1.1.6.2  bouyer #									#
   23490  1.1.6.2  bouyer #	A2.	Set X = abs(input).					#
   23491  1.1.6.2  bouyer #									#
   23492  1.1.6.2  bouyer #	A3.	Compute ILOG.						#
   23493  1.1.6.2  bouyer #		ILOG is the log base 10 of the input value.  It is	#
   23494  1.1.6.2  bouyer #		approximated by adding e + 0.f when the original 	#
   23495  1.1.6.2  bouyer #		value is viewed as 2^^e * 1.f in extended precision.  	#
   23496  1.1.6.2  bouyer #		This value is stored in d6.				#
   23497  1.1.6.2  bouyer #									#
   23498  1.1.6.2  bouyer #	A4.	Clr INEX bit.						#
   23499  1.1.6.2  bouyer #		The operation in A3 above may have set INEX2.  		#
   23500  1.1.6.2  bouyer #									#
   23501  1.1.6.2  bouyer #	A5.	Set ICTR = 0;						#
   23502  1.1.6.2  bouyer #		ICTR is a flag used in A13.  It must be set before the 	#
   23503  1.1.6.2  bouyer #		loop entry A6.						#
   23504  1.1.6.2  bouyer #									#
   23505  1.1.6.2  bouyer #	A6.	Calculate LEN.						#
   23506  1.1.6.2  bouyer #		LEN is the number of digits to be displayed.  The	#
   23507  1.1.6.2  bouyer #		k-factor can dictate either the total number of digits,	#
   23508  1.1.6.2  bouyer #		if it is a positive number, or the number of digits	#
   23509  1.1.6.2  bouyer #		after the decimal point which are to be included as	#
   23510  1.1.6.2  bouyer #		significant.  See the 68882 manual for examples.	#
   23511  1.1.6.2  bouyer #		If LEN is computed to be greater than 17, set OPERR in	#
   23512  1.1.6.2  bouyer #		USER_FPSR.  LEN is stored in d4.			#
   23513  1.1.6.2  bouyer #									#
   23514  1.1.6.2  bouyer #	A7.	Calculate SCALE.					#
   23515  1.1.6.2  bouyer #		SCALE is equal to 10^ISCALE, where ISCALE is the number	#
   23516  1.1.6.2  bouyer #		of decimal places needed to insure LEN integer digits	#
   23517  1.1.6.2  bouyer #		in the output before conversion to bcd. LAMBDA is the	#
   23518  1.1.6.2  bouyer #		sign of ISCALE, used in A9. Fp1 contains		#
   23519  1.1.6.2  bouyer #		10^^(abs(ISCALE)) using a rounding mode which is a	#
   23520  1.1.6.2  bouyer #		function of the original rounding mode and the signs	#
   23521  1.1.6.2  bouyer #		of ISCALE and X.  A table is given in the code.		#
   23522  1.1.6.2  bouyer #									#
   23523  1.1.6.2  bouyer #	A8.	Clr INEX; Force RZ.					#
   23524  1.1.6.2  bouyer #		The operation in A3 above may have set INEX2.  		#
   23525  1.1.6.2  bouyer #		RZ mode is forced for the scaling operation to insure	#
   23526  1.1.6.2  bouyer #		only one rounding error.  The grs bits are collected in #
   23527  1.1.6.2  bouyer #		the INEX flag for use in A10.				#
   23528  1.1.6.2  bouyer #									#
   23529  1.1.6.2  bouyer #	A9.	Scale X -> Y.						#
   23530  1.1.6.2  bouyer #		The mantissa is scaled to the desired number of		#
   23531  1.1.6.2  bouyer #		significant digits.  The excess digits are collected	#
   23532  1.1.6.2  bouyer #		in INEX2.						#
   23533  1.1.6.2  bouyer #									#
   23534  1.1.6.2  bouyer #	A10.	Or in INEX.						#
   23535  1.1.6.2  bouyer #		If INEX is set, round error occured.  This is		#
   23536  1.1.6.2  bouyer #		compensated for by 'or-ing' in the INEX2 flag to	#
   23537  1.1.6.2  bouyer #		the lsb of Y.						#
   23538  1.1.6.2  bouyer #									#
   23539  1.1.6.2  bouyer #	A11.	Restore original FPCR; set size ext.			#
   23540  1.1.6.2  bouyer #		Perform FINT operation in the user's rounding mode.	#
   23541  1.1.6.2  bouyer #		Keep the size to extended.				#
   23542  1.1.6.2  bouyer #									#
   23543  1.1.6.2  bouyer #	A12.	Calculate YINT = FINT(Y) according to user's rounding	#
   23544  1.1.6.2  bouyer #		mode.  The FPSP routine sintd0 is used.  The output	#
   23545  1.1.6.2  bouyer #		is in fp0.						#
   23546  1.1.6.2  bouyer #									#
   23547  1.1.6.2  bouyer #	A13.	Check for LEN digits.					#
   23548  1.1.6.2  bouyer #		If the int operation results in more than LEN digits,	#
   23549  1.1.6.2  bouyer #		or less than LEN -1 digits, adjust ILOG and repeat from	#
   23550  1.1.6.2  bouyer #		A6.  This test occurs only on the first pass.  If the	#
   23551  1.1.6.2  bouyer #		result is exactly 10^LEN, decrement ILOG and divide	#
   23552  1.1.6.2  bouyer #		the mantissa by 10.					#
   23553  1.1.6.2  bouyer #									#
   23554  1.1.6.2  bouyer #	A14.	Convert the mantissa to bcd.				#
   23555  1.1.6.2  bouyer #		The binstr routine is used to convert the LEN digit 	#
   23556  1.1.6.2  bouyer #		mantissa to bcd in memory.  The input to binstr is	#
   23557  1.1.6.2  bouyer #		to be a fraction; i.e. (mantissa)/10^LEN and adjusted	#
   23558  1.1.6.2  bouyer #		such that the decimal point is to the left of bit 63.	#
   23559  1.1.6.2  bouyer #		The bcd digits are stored in the correct position in 	#
   23560  1.1.6.2  bouyer #		the final string area in memory.			#
   23561  1.1.6.2  bouyer #									#
   23562  1.1.6.2  bouyer #	A15.	Convert the exponent to bcd.				#
   23563  1.1.6.2  bouyer #		As in A14 above, the exp is converted to bcd and the	#
   23564  1.1.6.2  bouyer #		digits are stored in the final string.			#
   23565  1.1.6.2  bouyer #		Test the length of the final exponent string.  If the	#
   23566  1.1.6.2  bouyer #		length is 4, set operr.					#
   23567  1.1.6.2  bouyer #									#
   23568  1.1.6.2  bouyer #	A16.	Write sign bits to final string.			#
   23569  1.1.6.2  bouyer #									#
   23570  1.1.6.2  bouyer #########################################################################
   23571  1.1.6.2  bouyer 
   23572  1.1.6.2  bouyer set	BINDEC_FLG,	EXC_TEMP	# DENORM flag
   23573  1.1.6.2  bouyer 
   23574  1.1.6.2  bouyer # Constants in extended precision
   23575  1.1.6.2  bouyer PLOG2:
   23576  1.1.6.2  bouyer 	long		0x3FFD0000,0x9A209A84,0xFBCFF798,0x00000000
   23577  1.1.6.2  bouyer PLOG2UP1:
   23578  1.1.6.2  bouyer 	long		0x3FFD0000,0x9A209A84,0xFBCFF799,0x00000000
   23579  1.1.6.2  bouyer 
   23580  1.1.6.2  bouyer # Constants in single precision
   23581  1.1.6.2  bouyer FONE:
   23582  1.1.6.2  bouyer 	long		0x3F800000,0x00000000,0x00000000,0x00000000
   23583  1.1.6.2  bouyer FTWO:
   23584  1.1.6.2  bouyer 	long		0x40000000,0x00000000,0x00000000,0x00000000
   23585  1.1.6.2  bouyer FTEN:
   23586  1.1.6.2  bouyer 	long		0x41200000,0x00000000,0x00000000,0x00000000
   23587  1.1.6.2  bouyer F4933:
   23588  1.1.6.2  bouyer 	long		0x459A2800,0x00000000,0x00000000,0x00000000
   23589  1.1.6.2  bouyer 
   23590  1.1.6.2  bouyer RBDTBL:
   23591  1.1.6.2  bouyer 	byte		0,0,0,0
   23592  1.1.6.2  bouyer 	byte		3,3,2,2
   23593  1.1.6.2  bouyer 	byte		3,2,2,3
   23594  1.1.6.2  bouyer 	byte		2,3,3,2
   23595  1.1.6.2  bouyer 
   23596  1.1.6.2  bouyer #	Implementation Notes:
   23597  1.1.6.2  bouyer #
   23598  1.1.6.2  bouyer #	The registers are used as follows:
   23599  1.1.6.2  bouyer #
   23600  1.1.6.2  bouyer #		d0: scratch; LEN input to binstr
   23601  1.1.6.2  bouyer #		d1: scratch
   23602  1.1.6.2  bouyer #		d2: upper 32-bits of mantissa for binstr
   23603  1.1.6.2  bouyer #		d3: scratch;lower 32-bits of mantissa for binstr
   23604  1.1.6.2  bouyer #		d4: LEN
   23605  1.1.6.2  bouyer #      		d5: LAMBDA/ICTR
   23606  1.1.6.2  bouyer #		d6: ILOG
   23607  1.1.6.2  bouyer #		d7: k-factor
   23608  1.1.6.2  bouyer #		a0: ptr for original operand/final result
   23609  1.1.6.2  bouyer #		a1: scratch pointer
   23610  1.1.6.2  bouyer #		a2: pointer to FP_X; abs(original value) in ext
   23611  1.1.6.2  bouyer #		fp0: scratch
   23612  1.1.6.2  bouyer #		fp1: scratch
   23613  1.1.6.2  bouyer #		fp2: scratch
   23614  1.1.6.2  bouyer #		F_SCR1:
   23615  1.1.6.2  bouyer #		F_SCR2:
   23616  1.1.6.2  bouyer #		L_SCR1:
   23617  1.1.6.2  bouyer #		L_SCR2:
   23618  1.1.6.2  bouyer 
   23619  1.1.6.2  bouyer 	global		bindec
   23620  1.1.6.2  bouyer bindec:
   23621  1.1.6.2  bouyer 	movm.l		&0x3f20,-(%sp)	#  {%d2-%d7/%a2}
   23622  1.1.6.2  bouyer 	fmovm.x		&0x7,-(%sp)	#  {%fp0-%fp2}
   23623  1.1.6.2  bouyer 
   23624  1.1.6.2  bouyer # A1. Set RM and size ext. Set SIGMA = sign input;
   23625  1.1.6.2  bouyer #     The k-factor is saved for use in d7.  Clear BINDEC_FLG for
   23626  1.1.6.2  bouyer #     separating  normalized/denormalized input.  If the input
   23627  1.1.6.2  bouyer #     is a denormalized number, set the BINDEC_FLG memory word
   23628  1.1.6.2  bouyer #     to signal denorm.  If the input is unnormalized, normalize
   23629  1.1.6.2  bouyer #     the input and test for denormalized result.
   23630  1.1.6.2  bouyer #
   23631  1.1.6.2  bouyer 	fmov.l		&rm_mode*0x10,%fpcr	# set RM and ext
   23632  1.1.6.2  bouyer 	mov.l		(%a0),L_SCR2(%a6)	# save exponent for sign check
   23633  1.1.6.2  bouyer 	mov.l		%d0,%d7		# move k-factor to d7
   23634  1.1.6.2  bouyer 
   23635  1.1.6.2  bouyer 	clr.b		BINDEC_FLG(%a6)	# clr norm/denorm flag
   23636  1.1.6.2  bouyer 	cmpi.b		STAG(%a6),&DENORM # is input a DENORM?
   23637  1.1.6.2  bouyer 	bne.w		A2_str		# no; input is a NORM
   23638  1.1.6.2  bouyer 
   23639  1.1.6.2  bouyer #
   23640  1.1.6.2  bouyer # Normalize the denorm
   23641  1.1.6.2  bouyer #
   23642  1.1.6.2  bouyer un_de_norm:
   23643  1.1.6.2  bouyer 	mov.w		(%a0),%d0
   23644  1.1.6.2  bouyer 	and.w		&0x7fff,%d0	# strip sign of normalized exp
   23645  1.1.6.2  bouyer 	mov.l		4(%a0),%d1
   23646  1.1.6.2  bouyer 	mov.l		8(%a0),%d2
   23647  1.1.6.2  bouyer norm_loop:
   23648  1.1.6.2  bouyer 	sub.w		&1,%d0
   23649  1.1.6.2  bouyer 	lsl.l		&1,%d2
   23650  1.1.6.2  bouyer 	roxl.l		&1,%d1
   23651  1.1.6.2  bouyer 	tst.l		%d1
   23652  1.1.6.2  bouyer 	bge.b		norm_loop
   23653  1.1.6.2  bouyer #
   23654  1.1.6.2  bouyer # Test if the normalized input is denormalized
   23655  1.1.6.2  bouyer #
   23656  1.1.6.2  bouyer 	tst.w		%d0
   23657  1.1.6.2  bouyer 	bgt.b		pos_exp		# if greater than zero, it is a norm
   23658  1.1.6.2  bouyer 	st		BINDEC_FLG(%a6)	# set flag for denorm
   23659  1.1.6.2  bouyer pos_exp:
   23660  1.1.6.2  bouyer 	and.w		&0x7fff,%d0	# strip sign of normalized exp
   23661  1.1.6.2  bouyer 	mov.w		%d0,(%a0)
   23662  1.1.6.2  bouyer 	mov.l		%d1,4(%a0)
   23663  1.1.6.2  bouyer 	mov.l		%d2,8(%a0)
   23664  1.1.6.2  bouyer 
   23665  1.1.6.2  bouyer # A2. Set X = abs(input).
   23666  1.1.6.2  bouyer #
   23667  1.1.6.2  bouyer A2_str:
   23668  1.1.6.2  bouyer 	mov.l		(%a0),FP_SCR1(%a6)	# move input to work space
   23669  1.1.6.2  bouyer 	mov.l		4(%a0),FP_SCR1+4(%a6)	# move input to work space
   23670  1.1.6.2  bouyer 	mov.l		8(%a0),FP_SCR1+8(%a6)	# move input to work space
   23671  1.1.6.2  bouyer 	and.l		&0x7fffffff,FP_SCR1(%a6)	# create abs(X)
   23672  1.1.6.2  bouyer 
   23673  1.1.6.2  bouyer # A3. Compute ILOG.
   23674  1.1.6.2  bouyer #     ILOG is the log base 10 of the input value.  It is approx-
   23675  1.1.6.2  bouyer #     imated by adding e + 0.f when the original value is viewed
   23676  1.1.6.2  bouyer #     as 2^^e * 1.f in extended precision.  This value is stored
   23677  1.1.6.2  bouyer #     in d6.
   23678  1.1.6.2  bouyer #
   23679  1.1.6.2  bouyer # Register usage:
   23680  1.1.6.2  bouyer #	Input/Output
   23681  1.1.6.2  bouyer #	d0: k-factor/exponent
   23682  1.1.6.2  bouyer #	d2: x/x
   23683  1.1.6.2  bouyer #	d3: x/x
   23684  1.1.6.2  bouyer #	d4: x/x
   23685  1.1.6.2  bouyer #	d5: x/x
   23686  1.1.6.2  bouyer #	d6: x/ILOG
   23687  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   23688  1.1.6.2  bouyer #	a0: ptr for original operand/final result
   23689  1.1.6.2  bouyer #	a1: x/x
   23690  1.1.6.2  bouyer #	a2: x/x
   23691  1.1.6.2  bouyer #	fp0: x/float(ILOG)
   23692  1.1.6.2  bouyer #	fp1: x/x
   23693  1.1.6.2  bouyer #	fp2: x/x
   23694  1.1.6.2  bouyer #	F_SCR1:x/x
   23695  1.1.6.2  bouyer #	F_SCR2:Abs(X)/Abs(X) with $3fff exponent
   23696  1.1.6.2  bouyer #	L_SCR1:x/x
   23697  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   23698  1.1.6.2  bouyer 
   23699  1.1.6.2  bouyer 	tst.b		BINDEC_FLG(%a6)	# check for denorm
   23700  1.1.6.2  bouyer 	beq.b		A3_cont		# if clr, continue with norm
   23701  1.1.6.2  bouyer 	mov.l		&-4933,%d6	# force ILOG = -4933
   23702  1.1.6.2  bouyer 	bra.b		A4_str
   23703  1.1.6.2  bouyer A3_cont:
   23704  1.1.6.2  bouyer 	mov.w		FP_SCR1(%a6),%d0	# move exp to d0
   23705  1.1.6.2  bouyer 	mov.w		&0x3fff,FP_SCR1(%a6)	# replace exponent with 0x3fff
   23706  1.1.6.2  bouyer 	fmov.x		FP_SCR1(%a6),%fp0	# now fp0 has 1.f
   23707  1.1.6.2  bouyer 	sub.w		&0x3fff,%d0	# strip off bias
   23708  1.1.6.2  bouyer 	fadd.w		%d0,%fp0	# add in exp
   23709  1.1.6.2  bouyer 	fsub.s		FONE(%pc),%fp0	# subtract off 1.0
   23710  1.1.6.2  bouyer 	fbge.w		pos_res		# if pos, branch
   23711  1.1.6.2  bouyer 	fmul.x		PLOG2UP1(%pc),%fp0	# if neg, mul by LOG2UP1
   23712  1.1.6.2  bouyer 	fmov.l		%fp0,%d6	# put ILOG in d6 as a lword
   23713  1.1.6.2  bouyer 	bra.b		A4_str		# go move out ILOG
   23714  1.1.6.2  bouyer pos_res:
   23715  1.1.6.2  bouyer 	fmul.x		PLOG2(%pc),%fp0	# if pos, mul by LOG2
   23716  1.1.6.2  bouyer 	fmov.l		%fp0,%d6	# put ILOG in d6 as a lword
   23717  1.1.6.2  bouyer 
   23718  1.1.6.2  bouyer 
   23719  1.1.6.2  bouyer # A4. Clr INEX bit.
   23720  1.1.6.2  bouyer #     The operation in A3 above may have set INEX2.
   23721  1.1.6.2  bouyer 
   23722  1.1.6.2  bouyer A4_str:
   23723  1.1.6.2  bouyer 	fmov.l		&0,%fpsr	# zero all of fpsr - nothing needed
   23724  1.1.6.2  bouyer 
   23725  1.1.6.2  bouyer 
   23726  1.1.6.2  bouyer # A5. Set ICTR = 0;
   23727  1.1.6.2  bouyer #     ICTR is a flag used in A13.  It must be set before the
   23728  1.1.6.2  bouyer #     loop entry A6. The lower word of d5 is used for ICTR.
   23729  1.1.6.2  bouyer 
   23730  1.1.6.2  bouyer 	clr.w		%d5		# clear ICTR
   23731  1.1.6.2  bouyer 
   23732  1.1.6.2  bouyer # A6. Calculate LEN.
   23733  1.1.6.2  bouyer #     LEN is the number of digits to be displayed.  The k-factor
   23734  1.1.6.2  bouyer #     can dictate either the total number of digits, if it is
   23735  1.1.6.2  bouyer #     a positive number, or the number of digits after the
   23736  1.1.6.2  bouyer #     original decimal point which are to be included as
   23737  1.1.6.2  bouyer #     significant.  See the 68882 manual for examples.
   23738  1.1.6.2  bouyer #     If LEN is computed to be greater than 17, set OPERR in
   23739  1.1.6.2  bouyer #     USER_FPSR.  LEN is stored in d4.
   23740  1.1.6.2  bouyer #
   23741  1.1.6.2  bouyer # Register usage:
   23742  1.1.6.2  bouyer #	Input/Output
   23743  1.1.6.2  bouyer #	d0: exponent/Unchanged
   23744  1.1.6.2  bouyer #	d2: x/x/scratch
   23745  1.1.6.2  bouyer #	d3: x/x
   23746  1.1.6.2  bouyer #	d4: exc picture/LEN
   23747  1.1.6.2  bouyer #	d5: ICTR/Unchanged
   23748  1.1.6.2  bouyer #	d6: ILOG/Unchanged
   23749  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   23750  1.1.6.2  bouyer #	a0: ptr for original operand/final result
   23751  1.1.6.2  bouyer #	a1: x/x
   23752  1.1.6.2  bouyer #	a2: x/x
   23753  1.1.6.2  bouyer #	fp0: float(ILOG)/Unchanged
   23754  1.1.6.2  bouyer #	fp1: x/x
   23755  1.1.6.2  bouyer #	fp2: x/x
   23756  1.1.6.2  bouyer #	F_SCR1:x/x
   23757  1.1.6.2  bouyer #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
   23758  1.1.6.2  bouyer #	L_SCR1:x/x
   23759  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   23760  1.1.6.2  bouyer 
   23761  1.1.6.2  bouyer A6_str:
   23762  1.1.6.2  bouyer 	tst.l		%d7		# branch on sign of k
   23763  1.1.6.2  bouyer 	ble.b		k_neg		# if k <= 0, LEN = ILOG + 1 - k
   23764  1.1.6.2  bouyer 	mov.l		%d7,%d4		# if k > 0, LEN = k
   23765  1.1.6.2  bouyer 	bra.b		len_ck		# skip to LEN check
   23766  1.1.6.2  bouyer k_neg:
   23767  1.1.6.2  bouyer 	mov.l		%d6,%d4		# first load ILOG to d4
   23768  1.1.6.2  bouyer 	sub.l		%d7,%d4		# subtract off k
   23769  1.1.6.2  bouyer 	addq.l		&1,%d4		# add in the 1
   23770  1.1.6.2  bouyer len_ck:
   23771  1.1.6.2  bouyer 	tst.l		%d4		# LEN check: branch on sign of LEN
   23772  1.1.6.2  bouyer 	ble.b		LEN_ng		# if neg, set LEN = 1
   23773  1.1.6.2  bouyer 	cmp.l		%d4,&17		# test if LEN > 17
   23774  1.1.6.2  bouyer 	ble.b		A7_str		# if not, forget it
   23775  1.1.6.2  bouyer 	mov.l		&17,%d4		# set max LEN = 17
   23776  1.1.6.2  bouyer 	tst.l		%d7		# if negative, never set OPERR
   23777  1.1.6.2  bouyer 	ble.b		A7_str		# if positive, continue
   23778  1.1.6.2  bouyer 	or.l		&opaop_mask,USER_FPSR(%a6)	# set OPERR & AIOP in USER_FPSR
   23779  1.1.6.2  bouyer 	bra.b		A7_str		# finished here
   23780  1.1.6.2  bouyer LEN_ng:
   23781  1.1.6.2  bouyer 	mov.l		&1,%d4		# min LEN is 1
   23782  1.1.6.2  bouyer 
   23783  1.1.6.2  bouyer 
   23784  1.1.6.2  bouyer # A7. Calculate SCALE.
   23785  1.1.6.2  bouyer #     SCALE is equal to 10^ISCALE, where ISCALE is the number
   23786  1.1.6.2  bouyer #     of decimal places needed to insure LEN integer digits
   23787  1.1.6.2  bouyer #     in the output before conversion to bcd. LAMBDA is the sign
   23788  1.1.6.2  bouyer #     of ISCALE, used in A9.  Fp1 contains 10^^(abs(ISCALE)) using
   23789  1.1.6.2  bouyer #     the rounding mode as given in the following table (see
   23790  1.1.6.2  bouyer #     Coonen, p. 7.23 as ref.; however, the SCALE variable is
   23791  1.1.6.2  bouyer #     of opposite sign in bindec.sa from Coonen).
   23792  1.1.6.2  bouyer #
   23793  1.1.6.2  bouyer #	Initial					USE
   23794  1.1.6.2  bouyer #	FPCR[6:5]	LAMBDA	SIGN(X)		FPCR[6:5]
   23795  1.1.6.2  bouyer #	----------------------------------------------
   23796  1.1.6.2  bouyer #	 RN	00	   0	   0		00/0	RN
   23797  1.1.6.2  bouyer #	 RN	00	   0	   1		00/0	RN
   23798  1.1.6.2  bouyer #	 RN	00	   1	   0		00/0	RN
   23799  1.1.6.2  bouyer #	 RN	00	   1	   1		00/0	RN
   23800  1.1.6.2  bouyer #	 RZ	01	   0	   0		11/3	RP
   23801  1.1.6.2  bouyer #	 RZ	01	   0	   1		11/3	RP
   23802  1.1.6.2  bouyer #	 RZ	01	   1	   0		10/2	RM
   23803  1.1.6.2  bouyer #	 RZ	01	   1	   1		10/2	RM
   23804  1.1.6.2  bouyer #	 RM	10	   0	   0		11/3	RP
   23805  1.1.6.2  bouyer #	 RM	10	   0	   1		10/2	RM
   23806  1.1.6.2  bouyer #	 RM	10	   1	   0		10/2	RM
   23807  1.1.6.2  bouyer #	 RM	10	   1	   1		11/3	RP
   23808  1.1.6.2  bouyer #	 RP	11	   0	   0		10/2	RM
   23809  1.1.6.2  bouyer #	 RP	11	   0	   1		11/3	RP
   23810  1.1.6.2  bouyer #	 RP	11	   1	   0		11/3	RP
   23811  1.1.6.2  bouyer #	 RP	11	   1	   1		10/2	RM
   23812  1.1.6.2  bouyer #
   23813  1.1.6.2  bouyer # Register usage:
   23814  1.1.6.2  bouyer #	Input/Output
   23815  1.1.6.2  bouyer #	d0: exponent/scratch - final is 0
   23816  1.1.6.2  bouyer #	d2: x/0 or 24 for A9
   23817  1.1.6.2  bouyer #	d3: x/scratch - offset ptr into PTENRM array
   23818  1.1.6.2  bouyer #	d4: LEN/Unchanged
   23819  1.1.6.2  bouyer #	d5: 0/ICTR:LAMBDA
   23820  1.1.6.2  bouyer #	d6: ILOG/ILOG or k if ((k<=0)&(ILOG<k))
   23821  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   23822  1.1.6.2  bouyer #	a0: ptr for original operand/final result
   23823  1.1.6.2  bouyer #	a1: x/ptr to PTENRM array
   23824  1.1.6.2  bouyer #	a2: x/x
   23825  1.1.6.2  bouyer #	fp0: float(ILOG)/Unchanged
   23826  1.1.6.2  bouyer #	fp1: x/10^ISCALE
   23827  1.1.6.2  bouyer #	fp2: x/x
   23828  1.1.6.2  bouyer #	F_SCR1:x/x
   23829  1.1.6.2  bouyer #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
   23830  1.1.6.2  bouyer #	L_SCR1:x/x
   23831  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   23832  1.1.6.2  bouyer 
   23833  1.1.6.2  bouyer A7_str:
   23834  1.1.6.2  bouyer 	tst.l		%d7		# test sign of k
   23835  1.1.6.2  bouyer 	bgt.b		k_pos		# if pos and > 0, skip this
   23836  1.1.6.2  bouyer 	cmp.l		%d7,%d6		# test k - ILOG
   23837  1.1.6.2  bouyer 	blt.b		k_pos		# if ILOG >= k, skip this
   23838  1.1.6.2  bouyer 	mov.l		%d7,%d6		# if ((k<0) & (ILOG < k)) ILOG = k
   23839  1.1.6.2  bouyer k_pos:
   23840  1.1.6.2  bouyer 	mov.l		%d6,%d0		# calc ILOG + 1 - LEN in d0
   23841  1.1.6.2  bouyer 	addq.l		&1,%d0		# add the 1
   23842  1.1.6.2  bouyer 	sub.l		%d4,%d0		# sub off LEN
   23843  1.1.6.2  bouyer 	swap		%d5		# use upper word of d5 for LAMBDA
   23844  1.1.6.2  bouyer 	clr.w		%d5		# set it zero initially
   23845  1.1.6.2  bouyer 	clr.w		%d2		# set up d2 for very small case
   23846  1.1.6.2  bouyer 	tst.l		%d0		# test sign of ISCALE
   23847  1.1.6.2  bouyer 	bge.b		iscale		# if pos, skip next inst
   23848  1.1.6.2  bouyer 	addq.w		&1,%d5		# if neg, set LAMBDA true
   23849  1.1.6.2  bouyer 	cmp.l		%d0,&0xffffecd4	# test iscale <= -4908
   23850  1.1.6.2  bouyer 	bgt.b		no_inf		# if false, skip rest
   23851  1.1.6.2  bouyer 	add.l		&24,%d0		# add in 24 to iscale
   23852  1.1.6.2  bouyer 	mov.l		&24,%d2		# put 24 in d2 for A9
   23853  1.1.6.2  bouyer no_inf:
   23854  1.1.6.2  bouyer 	neg.l		%d0		# and take abs of ISCALE
   23855  1.1.6.2  bouyer iscale:
   23856  1.1.6.2  bouyer 	fmov.s		FONE(%pc),%fp1	# init fp1 to 1
   23857  1.1.6.2  bouyer 	bfextu		USER_FPCR(%a6){&26:&2},%d1	# get initial rmode bits
   23858  1.1.6.2  bouyer 	lsl.w		&1,%d1		# put them in bits 2:1
   23859  1.1.6.2  bouyer 	add.w		%d5,%d1		# add in LAMBDA
   23860  1.1.6.2  bouyer 	lsl.w		&1,%d1		# put them in bits 3:1
   23861  1.1.6.2  bouyer 	tst.l		L_SCR2(%a6)	# test sign of original x
   23862  1.1.6.2  bouyer 	bge.b		x_pos		# if pos, don't set bit 0
   23863  1.1.6.2  bouyer 	addq.l		&1,%d1		# if neg, set bit 0
   23864  1.1.6.2  bouyer x_pos:
   23865  1.1.6.2  bouyer 	lea.l		RBDTBL(%pc),%a2	# load rbdtbl base
   23866  1.1.6.2  bouyer 	mov.b		(%a2,%d1),%d3	# load d3 with new rmode
   23867  1.1.6.2  bouyer 	lsl.l		&4,%d3		# put bits in proper position
   23868  1.1.6.2  bouyer 	fmov.l		%d3,%fpcr	# load bits into fpu
   23869  1.1.6.2  bouyer 	lsr.l		&4,%d3		# put bits in proper position
   23870  1.1.6.2  bouyer 	tst.b		%d3		# decode new rmode for pten table
   23871  1.1.6.2  bouyer 	bne.b		not_rn		# if zero, it is RN
   23872  1.1.6.2  bouyer 	lea.l		PTENRN(%pc),%a1	# load a1 with RN table base
   23873  1.1.6.2  bouyer 	bra.b		rmode		# exit decode
   23874  1.1.6.2  bouyer not_rn:
   23875  1.1.6.2  bouyer 	lsr.b		&1,%d3		# get lsb in carry
   23876  1.1.6.2  bouyer 	bcc.b		not_rp2		# if carry clear, it is RM
   23877  1.1.6.2  bouyer 	lea.l		PTENRP(%pc),%a1	# load a1 with RP table base
   23878  1.1.6.2  bouyer 	bra.b		rmode		# exit decode
   23879  1.1.6.2  bouyer not_rp2:
   23880  1.1.6.2  bouyer 	lea.l		PTENRM(%pc),%a1	# load a1 with RM table base
   23881  1.1.6.2  bouyer rmode:
   23882  1.1.6.2  bouyer 	clr.l		%d3		# clr table index
   23883  1.1.6.2  bouyer e_loop2:
   23884  1.1.6.2  bouyer 	lsr.l		&1,%d0		# shift next bit into carry
   23885  1.1.6.2  bouyer 	bcc.b		e_next2		# if zero, skip the mul
   23886  1.1.6.2  bouyer 	fmul.x		(%a1,%d3),%fp1	# mul by 10**(d3_bit_no)
   23887  1.1.6.2  bouyer e_next2:
   23888  1.1.6.2  bouyer 	add.l		&12,%d3		# inc d3 to next pwrten table entry
   23889  1.1.6.2  bouyer 	tst.l		%d0		# test if ISCALE is zero
   23890  1.1.6.2  bouyer 	bne.b		e_loop2		# if not, loop
   23891  1.1.6.2  bouyer 
   23892  1.1.6.2  bouyer # A8. Clr INEX; Force RZ.
   23893  1.1.6.2  bouyer #     The operation in A3 above may have set INEX2.
   23894  1.1.6.2  bouyer #     RZ mode is forced for the scaling operation to insure
   23895  1.1.6.2  bouyer #     only one rounding error.  The grs bits are collected in
   23896  1.1.6.2  bouyer #     the INEX flag for use in A10.
   23897  1.1.6.2  bouyer #
   23898  1.1.6.2  bouyer # Register usage:
   23899  1.1.6.2  bouyer #	Input/Output
   23900  1.1.6.2  bouyer 
   23901  1.1.6.2  bouyer 	fmov.l		&0,%fpsr	# clr INEX
   23902  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# set RZ rounding mode
   23903  1.1.6.2  bouyer 
   23904  1.1.6.2  bouyer # A9. Scale X -> Y.
   23905  1.1.6.2  bouyer #     The mantissa is scaled to the desired number of significant
   23906  1.1.6.2  bouyer #     digits.  The excess digits are collected in INEX2. If mul,
   23907  1.1.6.2  bouyer #     Check d2 for excess 10 exponential value.  If not zero,
   23908  1.1.6.2  bouyer #     the iscale value would have caused the pwrten calculation
   23909  1.1.6.2  bouyer #     to overflow.  Only a negative iscale can cause this, so
   23910  1.1.6.2  bouyer #     multiply by 10^(d2), which is now only allowed to be 24,
   23911  1.1.6.2  bouyer #     with a multiply by 10^8 and 10^16, which is exact since
   23912  1.1.6.2  bouyer #     10^24 is exact.  If the input was denormalized, we must
   23913  1.1.6.2  bouyer #     create a busy stack frame with the mul command and the
   23914  1.1.6.2  bouyer #     two operands, and allow the fpu to complete the multiply.
   23915  1.1.6.2  bouyer #
   23916  1.1.6.2  bouyer # Register usage:
   23917  1.1.6.2  bouyer #	Input/Output
   23918  1.1.6.2  bouyer #	d0: FPCR with RZ mode/Unchanged
   23919  1.1.6.2  bouyer #	d2: 0 or 24/unchanged
   23920  1.1.6.2  bouyer #	d3: x/x
   23921  1.1.6.2  bouyer #	d4: LEN/Unchanged
   23922  1.1.6.2  bouyer #	d5: ICTR:LAMBDA
   23923  1.1.6.2  bouyer #	d6: ILOG/Unchanged
   23924  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   23925  1.1.6.2  bouyer #	a0: ptr for original operand/final result
   23926  1.1.6.2  bouyer #	a1: ptr to PTENRM array/Unchanged
   23927  1.1.6.2  bouyer #	a2: x/x
   23928  1.1.6.2  bouyer #	fp0: float(ILOG)/X adjusted for SCALE (Y)
   23929  1.1.6.2  bouyer #	fp1: 10^ISCALE/Unchanged
   23930  1.1.6.2  bouyer #	fp2: x/x
   23931  1.1.6.2  bouyer #	F_SCR1:x/x
   23932  1.1.6.2  bouyer #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
   23933  1.1.6.2  bouyer #	L_SCR1:x/x
   23934  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   23935  1.1.6.2  bouyer 
   23936  1.1.6.2  bouyer A9_str:
   23937  1.1.6.2  bouyer 	fmov.x		(%a0),%fp0	# load X from memory
   23938  1.1.6.2  bouyer 	fabs.x		%fp0		# use abs(X)
   23939  1.1.6.2  bouyer 	tst.w		%d5		# LAMBDA is in lower word of d5
   23940  1.1.6.2  bouyer 	bne.b		sc_mul		# if neg (LAMBDA = 1), scale by mul
   23941  1.1.6.2  bouyer 	fdiv.x		%fp1,%fp0	# calculate X / SCALE -> Y to fp0
   23942  1.1.6.2  bouyer 	bra.w		A10_st		# branch to A10
   23943  1.1.6.2  bouyer 
   23944  1.1.6.2  bouyer sc_mul:
   23945  1.1.6.2  bouyer 	tst.b		BINDEC_FLG(%a6)	# check for denorm
   23946  1.1.6.2  bouyer 	beq.w		A9_norm		# if norm, continue with mul
   23947  1.1.6.2  bouyer 
   23948  1.1.6.2  bouyer # for DENORM, we must calculate:
   23949  1.1.6.2  bouyer #	fp0 = input_op * 10^ISCALE * 10^24
   23950  1.1.6.2  bouyer # since the input operand is a DENORM, we can't multiply it directly.
   23951  1.1.6.2  bouyer # so, we do the multiplication of the exponents and mantissas separately.
   23952  1.1.6.2  bouyer # in this way, we avoid underflow on intermediate stages of the
   23953  1.1.6.2  bouyer # multiplication and guarantee a result without exception.
   23954  1.1.6.2  bouyer 	fmovm.x		&0x2,-(%sp)	# save 10^ISCALE to stack
   23955  1.1.6.2  bouyer 
   23956  1.1.6.2  bouyer 	mov.w		(%sp),%d3	# grab exponent
   23957  1.1.6.2  bouyer 	andi.w		&0x7fff,%d3	# clear sign
   23958  1.1.6.2  bouyer 	ori.w		&0x8000,(%a0)	# make DENORM exp negative
   23959  1.1.6.2  bouyer 	add.w		(%a0),%d3	# add DENORM exp to 10^ISCALE exp
   23960  1.1.6.2  bouyer 	subi.w		&0x3fff,%d3	# subtract BIAS
   23961  1.1.6.2  bouyer 	add.w		36(%a1),%d3
   23962  1.1.6.2  bouyer 	subi.w		&0x3fff,%d3	# subtract BIAS
   23963  1.1.6.2  bouyer 	add.w		48(%a1),%d3
   23964  1.1.6.2  bouyer 	subi.w		&0x3fff,%d3	# subtract BIAS
   23965  1.1.6.2  bouyer 
   23966  1.1.6.2  bouyer 	bmi.w		sc_mul_err	# is result is DENORM, punt!!!
   23967  1.1.6.2  bouyer 
   23968  1.1.6.2  bouyer 	andi.w		&0x8000,(%sp)	# keep sign
   23969  1.1.6.2  bouyer 	or.w		%d3,(%sp)	# insert new exponent
   23970  1.1.6.2  bouyer 	andi.w		&0x7fff,(%a0)	# clear sign bit on DENORM again
   23971  1.1.6.2  bouyer 	mov.l		0x8(%a0),-(%sp) # put input op mantissa on stk
   23972  1.1.6.2  bouyer 	mov.l		0x4(%a0),-(%sp)
   23973  1.1.6.2  bouyer 	mov.l		&0x3fff0000,-(%sp) # force exp to zero
   23974  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0x80	# load normalized DENORM into fp0
   23975  1.1.6.2  bouyer 	fmul.x		(%sp)+,%fp0
   23976  1.1.6.2  bouyer 
   23977  1.1.6.2  bouyer #	fmul.x	36(%a1),%fp0	# multiply fp0 by 10^8
   23978  1.1.6.2  bouyer #	fmul.x	48(%a1),%fp0	# multiply fp0 by 10^16
   23979  1.1.6.2  bouyer 	mov.l		36+8(%a1),-(%sp) # get 10^8 mantissa
   23980  1.1.6.2  bouyer 	mov.l		36+4(%a1),-(%sp)
   23981  1.1.6.2  bouyer 	mov.l		&0x3fff0000,-(%sp) # force exp to zero
   23982  1.1.6.2  bouyer 	mov.l		48+8(%a1),-(%sp) # get 10^16 mantissa
   23983  1.1.6.2  bouyer 	mov.l		48+4(%a1),-(%sp)
   23984  1.1.6.2  bouyer 	mov.l		&0x3fff0000,-(%sp)# force exp to zero
   23985  1.1.6.2  bouyer 	fmul.x		(%sp)+,%fp0	# multiply fp0 by 10^8
   23986  1.1.6.2  bouyer 	fmul.x		(%sp)+,%fp0	# multiply fp0 by 10^16
   23987  1.1.6.2  bouyer 	bra.b		A10_st
   23988  1.1.6.2  bouyer 
   23989  1.1.6.2  bouyer sc_mul_err:
   23990  1.1.6.2  bouyer 	bra.b		sc_mul_err
   23991  1.1.6.2  bouyer 
   23992  1.1.6.2  bouyer A9_norm:
   23993  1.1.6.2  bouyer 	tst.w		%d2		# test for small exp case
   23994  1.1.6.2  bouyer 	beq.b		A9_con		# if zero, continue as normal
   23995  1.1.6.2  bouyer 	fmul.x		36(%a1),%fp0	# multiply fp0 by 10^8
   23996  1.1.6.2  bouyer 	fmul.x		48(%a1),%fp0	# multiply fp0 by 10^16
   23997  1.1.6.2  bouyer A9_con:
   23998  1.1.6.2  bouyer 	fmul.x		%fp1,%fp0	# calculate X * SCALE -> Y to fp0
   23999  1.1.6.2  bouyer 
   24000  1.1.6.2  bouyer # A10. Or in INEX.
   24001  1.1.6.2  bouyer #      If INEX is set, round error occured.  This is compensated
   24002  1.1.6.2  bouyer #      for by 'or-ing' in the INEX2 flag to the lsb of Y.
   24003  1.1.6.2  bouyer #
   24004  1.1.6.2  bouyer # Register usage:
   24005  1.1.6.2  bouyer #	Input/Output
   24006  1.1.6.2  bouyer #	d0: FPCR with RZ mode/FPSR with INEX2 isolated
   24007  1.1.6.2  bouyer #	d2: x/x
   24008  1.1.6.2  bouyer #	d3: x/x
   24009  1.1.6.2  bouyer #	d4: LEN/Unchanged
   24010  1.1.6.2  bouyer #	d5: ICTR:LAMBDA
   24011  1.1.6.2  bouyer #	d6: ILOG/Unchanged
   24012  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   24013  1.1.6.2  bouyer #	a0: ptr for original operand/final result
   24014  1.1.6.2  bouyer #	a1: ptr to PTENxx array/Unchanged
   24015  1.1.6.2  bouyer #	a2: x/ptr to FP_SCR1(a6)
   24016  1.1.6.2  bouyer #	fp0: Y/Y with lsb adjusted
   24017  1.1.6.2  bouyer #	fp1: 10^ISCALE/Unchanged
   24018  1.1.6.2  bouyer #	fp2: x/x
   24019  1.1.6.2  bouyer 
   24020  1.1.6.2  bouyer A10_st:
   24021  1.1.6.2  bouyer 	fmov.l		%fpsr,%d0	# get FPSR
   24022  1.1.6.2  bouyer 	fmov.x		%fp0,FP_SCR1(%a6)	# move Y to memory
   24023  1.1.6.2  bouyer 	lea.l		FP_SCR1(%a6),%a2	# load a2 with ptr to FP_SCR1
   24024  1.1.6.2  bouyer 	btst		&9,%d0		# check if INEX2 set
   24025  1.1.6.2  bouyer 	beq.b		A11_st		# if clear, skip rest
   24026  1.1.6.2  bouyer 	or.l		&1,8(%a2)	# or in 1 to lsb of mantissa
   24027  1.1.6.2  bouyer 	fmov.x		FP_SCR1(%a6),%fp0	# write adjusted Y back to fpu
   24028  1.1.6.2  bouyer 
   24029  1.1.6.2  bouyer 
   24030  1.1.6.2  bouyer # A11. Restore original FPCR; set size ext.
   24031  1.1.6.2  bouyer #      Perform FINT operation in the user's rounding mode.  Keep
   24032  1.1.6.2  bouyer #      the size to extended.  The sintdo entry point in the sint
   24033  1.1.6.2  bouyer #      routine expects the FPCR value to be in USER_FPCR for
   24034  1.1.6.2  bouyer #      mode and precision.  The original FPCR is saved in L_SCR1.
   24035  1.1.6.2  bouyer 
   24036  1.1.6.2  bouyer A11_st:
   24037  1.1.6.2  bouyer 	mov.l		USER_FPCR(%a6),L_SCR1(%a6)	# save it for later
   24038  1.1.6.2  bouyer 	and.l		&0x00000030,USER_FPCR(%a6)	# set size to ext,
   24039  1.1.6.2  bouyer #					;block exceptions
   24040  1.1.6.2  bouyer 
   24041  1.1.6.2  bouyer 
   24042  1.1.6.2  bouyer # A12. Calculate YINT = FINT(Y) according to user's rounding mode.
   24043  1.1.6.2  bouyer #      The FPSP routine sintd0 is used.  The output is in fp0.
   24044  1.1.6.2  bouyer #
   24045  1.1.6.2  bouyer # Register usage:
   24046  1.1.6.2  bouyer #	Input/Output
   24047  1.1.6.2  bouyer #	d0: FPSR with AINEX cleared/FPCR with size set to ext
   24048  1.1.6.2  bouyer #	d2: x/x/scratch
   24049  1.1.6.2  bouyer #	d3: x/x
   24050  1.1.6.2  bouyer #	d4: LEN/Unchanged
   24051  1.1.6.2  bouyer #	d5: ICTR:LAMBDA/Unchanged
   24052  1.1.6.2  bouyer #	d6: ILOG/Unchanged
   24053  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   24054  1.1.6.2  bouyer #	a0: ptr for original operand/src ptr for sintdo
   24055  1.1.6.2  bouyer #	a1: ptr to PTENxx array/Unchanged
   24056  1.1.6.2  bouyer #	a2: ptr to FP_SCR1(a6)/Unchanged
   24057  1.1.6.2  bouyer #	a6: temp pointer to FP_SCR1(a6) - orig value saved and restored
   24058  1.1.6.2  bouyer #	fp0: Y/YINT
   24059  1.1.6.2  bouyer #	fp1: 10^ISCALE/Unchanged
   24060  1.1.6.2  bouyer #	fp2: x/x
   24061  1.1.6.2  bouyer #	F_SCR1:x/x
   24062  1.1.6.2  bouyer #	F_SCR2:Y adjusted for inex/Y with original exponent
   24063  1.1.6.2  bouyer #	L_SCR1:x/original USER_FPCR
   24064  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   24065  1.1.6.2  bouyer 
   24066  1.1.6.2  bouyer A12_st:
   24067  1.1.6.2  bouyer 	movm.l	&0xc0c0,-(%sp)	# save regs used by sintd0	 {%d0-%d1/%a0-%a1}
   24068  1.1.6.2  bouyer 	mov.l	L_SCR1(%a6),-(%sp)
   24069  1.1.6.2  bouyer 	mov.l	L_SCR2(%a6),-(%sp)
   24070  1.1.6.2  bouyer 
   24071  1.1.6.2  bouyer 	lea.l		FP_SCR1(%a6),%a0	# a0 is ptr to FP_SCR1(a6)
   24072  1.1.6.2  bouyer 	fmov.x		%fp0,(%a0)	# move Y to memory at FP_SCR1(a6)
   24073  1.1.6.2  bouyer 	tst.l		L_SCR2(%a6)	# test sign of original operand
   24074  1.1.6.2  bouyer 	bge.b		do_fint12		# if pos, use Y
   24075  1.1.6.2  bouyer 	or.l		&0x80000000,(%a0)	# if neg, use -Y
   24076  1.1.6.2  bouyer do_fint12:
   24077  1.1.6.2  bouyer 	mov.l	USER_FPSR(%a6),-(%sp)
   24078  1.1.6.2  bouyer #	bsr	sintdo		# sint routine returns int in fp0
   24079  1.1.6.2  bouyer 
   24080  1.1.6.2  bouyer 	fmov.l	USER_FPCR(%a6),%fpcr
   24081  1.1.6.2  bouyer 	fmov.l	&0x0,%fpsr			# clear the AEXC bits!!!
   24082  1.1.6.2  bouyer ##	mov.l		USER_FPCR(%a6),%d0	# ext prec/keep rnd mode
   24083  1.1.6.2  bouyer ##	andi.l		&0x00000030,%d0
   24084  1.1.6.2  bouyer ##	fmov.l		%d0,%fpcr
   24085  1.1.6.2  bouyer 	fint.x		FP_SCR1(%a6),%fp0	# do fint()
   24086  1.1.6.2  bouyer 	fmov.l	%fpsr,%d0
   24087  1.1.6.2  bouyer 	or.w	%d0,FPSR_EXCEPT(%a6)
   24088  1.1.6.2  bouyer ##	fmov.l		&0x0,%fpcr
   24089  1.1.6.2  bouyer ##	fmov.l		%fpsr,%d0		# don't keep ccodes
   24090  1.1.6.2  bouyer ##	or.w		%d0,FPSR_EXCEPT(%a6)
   24091  1.1.6.2  bouyer 
   24092  1.1.6.2  bouyer 	mov.b	(%sp),USER_FPSR(%a6)
   24093  1.1.6.2  bouyer 	add.l	&4,%sp
   24094  1.1.6.2  bouyer 
   24095  1.1.6.2  bouyer 	mov.l	(%sp)+,L_SCR2(%a6)
   24096  1.1.6.2  bouyer 	mov.l	(%sp)+,L_SCR1(%a6)
   24097  1.1.6.2  bouyer 	movm.l	(%sp)+,&0x303	# restore regs used by sint	 {%d0-%d1/%a0-%a1}
   24098  1.1.6.2  bouyer 
   24099  1.1.6.2  bouyer 	mov.l	L_SCR2(%a6),FP_SCR1(%a6)	# restore original exponent
   24100  1.1.6.2  bouyer 	mov.l	L_SCR1(%a6),USER_FPCR(%a6)	# restore user's FPCR
   24101  1.1.6.2  bouyer 
   24102  1.1.6.2  bouyer # A13. Check for LEN digits.
   24103  1.1.6.2  bouyer #      If the int operation results in more than LEN digits,
   24104  1.1.6.2  bouyer #      or less than LEN -1 digits, adjust ILOG and repeat from
   24105  1.1.6.2  bouyer #      A6.  This test occurs only on the first pass.  If the
   24106  1.1.6.2  bouyer #      result is exactly 10^LEN, decrement ILOG and divide
   24107  1.1.6.2  bouyer #      the mantissa by 10.  The calculation of 10^LEN cannot
   24108  1.1.6.2  bouyer #      be inexact, since all powers of ten upto 10^27 are exact
   24109  1.1.6.2  bouyer #      in extended precision, so the use of a previous power-of-ten
   24110  1.1.6.2  bouyer #      table will introduce no error.
   24111  1.1.6.2  bouyer #
   24112  1.1.6.2  bouyer #
   24113  1.1.6.2  bouyer # Register usage:
   24114  1.1.6.2  bouyer #	Input/Output
   24115  1.1.6.2  bouyer #	d0: FPCR with size set to ext/scratch final = 0
   24116  1.1.6.2  bouyer #	d2: x/x
   24117  1.1.6.2  bouyer #	d3: x/scratch final = x
   24118  1.1.6.2  bouyer #	d4: LEN/LEN adjusted
   24119  1.1.6.2  bouyer #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24120  1.1.6.2  bouyer #	d6: ILOG/ILOG adjusted
   24121  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   24122  1.1.6.2  bouyer #	a0: pointer into memory for packed bcd string formation
   24123  1.1.6.2  bouyer #	a1: ptr to PTENxx array/Unchanged
   24124  1.1.6.2  bouyer #	a2: ptr to FP_SCR1(a6)/Unchanged
   24125  1.1.6.2  bouyer #	fp0: int portion of Y/abs(YINT) adjusted
   24126  1.1.6.2  bouyer #	fp1: 10^ISCALE/Unchanged
   24127  1.1.6.2  bouyer #	fp2: x/10^LEN
   24128  1.1.6.2  bouyer #	F_SCR1:x/x
   24129  1.1.6.2  bouyer #	F_SCR2:Y with original exponent/Unchanged
   24130  1.1.6.2  bouyer #	L_SCR1:original USER_FPCR/Unchanged
   24131  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   24132  1.1.6.2  bouyer 
   24133  1.1.6.2  bouyer A13_st:
   24134  1.1.6.2  bouyer 	swap		%d5		# put ICTR in lower word of d5
   24135  1.1.6.2  bouyer 	tst.w		%d5		# check if ICTR = 0
   24136  1.1.6.2  bouyer 	bne		not_zr		# if non-zero, go to second test
   24137  1.1.6.2  bouyer #
   24138  1.1.6.2  bouyer # Compute 10^(LEN-1)
   24139  1.1.6.2  bouyer #
   24140  1.1.6.2  bouyer 	fmov.s		FONE(%pc),%fp2	# init fp2 to 1.0
   24141  1.1.6.2  bouyer 	mov.l		%d4,%d0		# put LEN in d0
   24142  1.1.6.2  bouyer 	subq.l		&1,%d0		# d0 = LEN -1
   24143  1.1.6.2  bouyer 	clr.l		%d3		# clr table index
   24144  1.1.6.2  bouyer l_loop:
   24145  1.1.6.2  bouyer 	lsr.l		&1,%d0		# shift next bit into carry
   24146  1.1.6.2  bouyer 	bcc.b		l_next		# if zero, skip the mul
   24147  1.1.6.2  bouyer 	fmul.x		(%a1,%d3),%fp2	# mul by 10**(d3_bit_no)
   24148  1.1.6.2  bouyer l_next:
   24149  1.1.6.2  bouyer 	add.l		&12,%d3		# inc d3 to next pwrten table entry
   24150  1.1.6.2  bouyer 	tst.l		%d0		# test if LEN is zero
   24151  1.1.6.2  bouyer 	bne.b		l_loop		# if not, loop
   24152  1.1.6.2  bouyer #
   24153  1.1.6.2  bouyer # 10^LEN-1 is computed for this test and A14.  If the input was
   24154  1.1.6.2  bouyer # denormalized, check only the case in which YINT > 10^LEN.
   24155  1.1.6.2  bouyer #
   24156  1.1.6.2  bouyer 	tst.b		BINDEC_FLG(%a6)	# check if input was norm
   24157  1.1.6.2  bouyer 	beq.b		A13_con		# if norm, continue with checking
   24158  1.1.6.2  bouyer 	fabs.x		%fp0		# take abs of YINT
   24159  1.1.6.2  bouyer 	bra		test_2
   24160  1.1.6.2  bouyer #
   24161  1.1.6.2  bouyer # Compare abs(YINT) to 10^(LEN-1) and 10^LEN
   24162  1.1.6.2  bouyer #
   24163  1.1.6.2  bouyer A13_con:
   24164  1.1.6.2  bouyer 	fabs.x		%fp0		# take abs of YINT
   24165  1.1.6.2  bouyer 	fcmp.x		%fp0,%fp2	# compare abs(YINT) with 10^(LEN-1)
   24166  1.1.6.2  bouyer 	fbge.w		test_2		# if greater, do next test
   24167  1.1.6.2  bouyer 	subq.l		&1,%d6		# subtract 1 from ILOG
   24168  1.1.6.2  bouyer 	mov.w		&1,%d5		# set ICTR
   24169  1.1.6.2  bouyer 	fmov.l		&rm_mode*0x10,%fpcr	# set rmode to RM
   24170  1.1.6.2  bouyer 	fmul.s		FTEN(%pc),%fp2	# compute 10^LEN
   24171  1.1.6.2  bouyer 	bra.w		A6_str		# return to A6 and recompute YINT
   24172  1.1.6.2  bouyer test_2:
   24173  1.1.6.2  bouyer 	fmul.s		FTEN(%pc),%fp2	# compute 10^LEN
   24174  1.1.6.2  bouyer 	fcmp.x		%fp0,%fp2	# compare abs(YINT) with 10^LEN
   24175  1.1.6.2  bouyer 	fblt.w		A14_st		# if less, all is ok, go to A14
   24176  1.1.6.2  bouyer 	fbgt.w		fix_ex		# if greater, fix and redo
   24177  1.1.6.2  bouyer 	fdiv.s		FTEN(%pc),%fp0	# if equal, divide by 10
   24178  1.1.6.2  bouyer 	addq.l		&1,%d6		# and inc ILOG
   24179  1.1.6.2  bouyer 	bra.b		A14_st		# and continue elsewhere
   24180  1.1.6.2  bouyer fix_ex:
   24181  1.1.6.2  bouyer 	addq.l		&1,%d6		# increment ILOG by 1
   24182  1.1.6.2  bouyer 	mov.w		&1,%d5		# set ICTR
   24183  1.1.6.2  bouyer 	fmov.l		&rm_mode*0x10,%fpcr	# set rmode to RM
   24184  1.1.6.2  bouyer 	bra.w		A6_str		# return to A6 and recompute YINT
   24185  1.1.6.2  bouyer #
   24186  1.1.6.2  bouyer # Since ICTR <> 0, we have already been through one adjustment,
   24187  1.1.6.2  bouyer # and shouldn't have another; this is to check if abs(YINT) = 10^LEN
   24188  1.1.6.2  bouyer # 10^LEN is again computed using whatever table is in a1 since the
   24189  1.1.6.2  bouyer # value calculated cannot be inexact.
   24190  1.1.6.2  bouyer #
   24191  1.1.6.2  bouyer not_zr:
   24192  1.1.6.2  bouyer 	fmov.s		FONE(%pc),%fp2	# init fp2 to 1.0
   24193  1.1.6.2  bouyer 	mov.l		%d4,%d0		# put LEN in d0
   24194  1.1.6.2  bouyer 	clr.l		%d3		# clr table index
   24195  1.1.6.2  bouyer z_loop:
   24196  1.1.6.2  bouyer 	lsr.l		&1,%d0		# shift next bit into carry
   24197  1.1.6.2  bouyer 	bcc.b		z_next		# if zero, skip the mul
   24198  1.1.6.2  bouyer 	fmul.x		(%a1,%d3),%fp2	# mul by 10**(d3_bit_no)
   24199  1.1.6.2  bouyer z_next:
   24200  1.1.6.2  bouyer 	add.l		&12,%d3		# inc d3 to next pwrten table entry
   24201  1.1.6.2  bouyer 	tst.l		%d0		# test if LEN is zero
   24202  1.1.6.2  bouyer 	bne.b		z_loop		# if not, loop
   24203  1.1.6.2  bouyer 	fabs.x		%fp0		# get abs(YINT)
   24204  1.1.6.2  bouyer 	fcmp.x		%fp0,%fp2	# check if abs(YINT) = 10^LEN
   24205  1.1.6.2  bouyer 	fbneq.w		A14_st		# if not, skip this
   24206  1.1.6.2  bouyer 	fdiv.s		FTEN(%pc),%fp0	# divide abs(YINT) by 10
   24207  1.1.6.2  bouyer 	addq.l		&1,%d6		# and inc ILOG by 1
   24208  1.1.6.2  bouyer 	addq.l		&1,%d4		# and inc LEN
   24209  1.1.6.2  bouyer 	fmul.s		FTEN(%pc),%fp2	# if LEN++, the get 10^^LEN
   24210  1.1.6.2  bouyer 
   24211  1.1.6.2  bouyer # A14. Convert the mantissa to bcd.
   24212  1.1.6.2  bouyer #      The binstr routine is used to convert the LEN digit
   24213  1.1.6.2  bouyer #      mantissa to bcd in memory.  The input to binstr is
   24214  1.1.6.2  bouyer #      to be a fraction; i.e. (mantissa)/10^LEN and adjusted
   24215  1.1.6.2  bouyer #      such that the decimal point is to the left of bit 63.
   24216  1.1.6.2  bouyer #      The bcd digits are stored in the correct position in
   24217  1.1.6.2  bouyer #      the final string area in memory.
   24218  1.1.6.2  bouyer #
   24219  1.1.6.2  bouyer #
   24220  1.1.6.2  bouyer # Register usage:
   24221  1.1.6.2  bouyer #	Input/Output
   24222  1.1.6.2  bouyer #	d0: x/LEN call to binstr - final is 0
   24223  1.1.6.2  bouyer #	d1: x/0
   24224  1.1.6.2  bouyer #	d2: x/ms 32-bits of mant of abs(YINT)
   24225  1.1.6.2  bouyer #	d3: x/ls 32-bits of mant of abs(YINT)
   24226  1.1.6.2  bouyer #	d4: LEN/Unchanged
   24227  1.1.6.2  bouyer #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24228  1.1.6.2  bouyer #	d6: ILOG
   24229  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   24230  1.1.6.2  bouyer #	a0: pointer into memory for packed bcd string formation
   24231  1.1.6.2  bouyer #	    /ptr to first mantissa byte in result string
   24232  1.1.6.2  bouyer #	a1: ptr to PTENxx array/Unchanged
   24233  1.1.6.2  bouyer #	a2: ptr to FP_SCR1(a6)/Unchanged
   24234  1.1.6.2  bouyer #	fp0: int portion of Y/abs(YINT) adjusted
   24235  1.1.6.2  bouyer #	fp1: 10^ISCALE/Unchanged
   24236  1.1.6.2  bouyer #	fp2: 10^LEN/Unchanged
   24237  1.1.6.2  bouyer #	F_SCR1:x/Work area for final result
   24238  1.1.6.2  bouyer #	F_SCR2:Y with original exponent/Unchanged
   24239  1.1.6.2  bouyer #	L_SCR1:original USER_FPCR/Unchanged
   24240  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   24241  1.1.6.2  bouyer 
   24242  1.1.6.2  bouyer A14_st:
   24243  1.1.6.2  bouyer 	fmov.l		&rz_mode*0x10,%fpcr	# force rz for conversion
   24244  1.1.6.2  bouyer 	fdiv.x		%fp2,%fp0	# divide abs(YINT) by 10^LEN
   24245  1.1.6.2  bouyer 	lea.l		FP_SCR0(%a6),%a0
   24246  1.1.6.2  bouyer 	fmov.x		%fp0,(%a0)	# move abs(YINT)/10^LEN to memory
   24247  1.1.6.2  bouyer 	mov.l		4(%a0),%d2	# move 2nd word of FP_RES to d2
   24248  1.1.6.2  bouyer 	mov.l		8(%a0),%d3	# move 3rd word of FP_RES to d3
   24249  1.1.6.2  bouyer 	clr.l		4(%a0)		# zero word 2 of FP_RES
   24250  1.1.6.2  bouyer 	clr.l		8(%a0)		# zero word 3 of FP_RES
   24251  1.1.6.2  bouyer 	mov.l		(%a0),%d0	# move exponent to d0
   24252  1.1.6.2  bouyer 	swap		%d0		# put exponent in lower word
   24253  1.1.6.2  bouyer 	beq.b		no_sft		# if zero, don't shift
   24254  1.1.6.2  bouyer 	sub.l		&0x3ffd,%d0	# sub bias less 2 to make fract
   24255  1.1.6.2  bouyer 	tst.l		%d0		# check if > 1
   24256  1.1.6.2  bouyer 	bgt.b		no_sft		# if so, don't shift
   24257  1.1.6.2  bouyer 	neg.l		%d0		# make exp positive
   24258  1.1.6.2  bouyer m_loop:
   24259  1.1.6.2  bouyer 	lsr.l		&1,%d2		# shift d2:d3 right, add 0s
   24260  1.1.6.2  bouyer 	roxr.l		&1,%d3		# the number of places
   24261  1.1.6.2  bouyer 	dbf.w		%d0,m_loop	# given in d0
   24262  1.1.6.2  bouyer no_sft:
   24263  1.1.6.2  bouyer 	tst.l		%d2		# check for mantissa of zero
   24264  1.1.6.2  bouyer 	bne.b		no_zr		# if not, go on
   24265  1.1.6.2  bouyer 	tst.l		%d3		# continue zero check
   24266  1.1.6.2  bouyer 	beq.b		zer_m		# if zero, go directly to binstr
   24267  1.1.6.2  bouyer no_zr:
   24268  1.1.6.2  bouyer 	clr.l		%d1		# put zero in d1 for addx
   24269  1.1.6.2  bouyer 	add.l		&0x00000080,%d3	# inc at bit 7
   24270  1.1.6.2  bouyer 	addx.l		%d1,%d2		# continue inc
   24271  1.1.6.2  bouyer 	and.l		&0xffffff80,%d3	# strip off lsb not used by 882
   24272  1.1.6.2  bouyer zer_m:
   24273  1.1.6.2  bouyer 	mov.l		%d4,%d0		# put LEN in d0 for binstr call
   24274  1.1.6.2  bouyer 	addq.l		&3,%a0		# a0 points to M16 byte in result
   24275  1.1.6.2  bouyer 	bsr		binstr		# call binstr to convert mant
   24276  1.1.6.2  bouyer 
   24277  1.1.6.2  bouyer 
   24278  1.1.6.2  bouyer # A15. Convert the exponent to bcd.
   24279  1.1.6.2  bouyer #      As in A14 above, the exp is converted to bcd and the
   24280  1.1.6.2  bouyer #      digits are stored in the final string.
   24281  1.1.6.2  bouyer #
   24282  1.1.6.2  bouyer #      Digits are stored in L_SCR1(a6) on return from BINDEC as:
   24283  1.1.6.2  bouyer #
   24284  1.1.6.2  bouyer #  	 32               16 15                0
   24285  1.1.6.2  bouyer #	-----------------------------------------
   24286  1.1.6.2  bouyer #  	|  0 | e3 | e2 | e1 | e4 |  X |  X |  X |
   24287  1.1.6.2  bouyer #	-----------------------------------------
   24288  1.1.6.2  bouyer #
   24289  1.1.6.2  bouyer # And are moved into their proper places in FP_SCR0.  If digit e4
   24290  1.1.6.2  bouyer # is non-zero, OPERR is signaled.  In all cases, all 4 digits are
   24291  1.1.6.2  bouyer # written as specified in the 881/882 manual for packed decimal.
   24292  1.1.6.2  bouyer #
   24293  1.1.6.2  bouyer # Register usage:
   24294  1.1.6.2  bouyer #	Input/Output
   24295  1.1.6.2  bouyer #	d0: x/LEN call to binstr - final is 0
   24296  1.1.6.2  bouyer #	d1: x/scratch (0);shift count for final exponent packing
   24297  1.1.6.2  bouyer #	d2: x/ms 32-bits of exp fraction/scratch
   24298  1.1.6.2  bouyer #	d3: x/ls 32-bits of exp fraction
   24299  1.1.6.2  bouyer #	d4: LEN/Unchanged
   24300  1.1.6.2  bouyer #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24301  1.1.6.2  bouyer #	d6: ILOG
   24302  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   24303  1.1.6.2  bouyer #	a0: ptr to result string/ptr to L_SCR1(a6)
   24304  1.1.6.2  bouyer #	a1: ptr to PTENxx array/Unchanged
   24305  1.1.6.2  bouyer #	a2: ptr to FP_SCR1(a6)/Unchanged
   24306  1.1.6.2  bouyer #	fp0: abs(YINT) adjusted/float(ILOG)
   24307  1.1.6.2  bouyer #	fp1: 10^ISCALE/Unchanged
   24308  1.1.6.2  bouyer #	fp2: 10^LEN/Unchanged
   24309  1.1.6.2  bouyer #	F_SCR1:Work area for final result/BCD result
   24310  1.1.6.2  bouyer #	F_SCR2:Y with original exponent/ILOG/10^4
   24311  1.1.6.2  bouyer #	L_SCR1:original USER_FPCR/Exponent digits on return from binstr
   24312  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   24313  1.1.6.2  bouyer 
   24314  1.1.6.2  bouyer A15_st:
   24315  1.1.6.2  bouyer 	tst.b		BINDEC_FLG(%a6)	# check for denorm
   24316  1.1.6.2  bouyer 	beq.b		not_denorm
   24317  1.1.6.2  bouyer 	ftest.x		%fp0		# test for zero
   24318  1.1.6.2  bouyer 	fbeq.w		den_zero	# if zero, use k-factor or 4933
   24319  1.1.6.2  bouyer 	fmov.l		%d6,%fp0	# float ILOG
   24320  1.1.6.2  bouyer 	fabs.x		%fp0		# get abs of ILOG
   24321  1.1.6.2  bouyer 	bra.b		convrt
   24322  1.1.6.2  bouyer den_zero:
   24323  1.1.6.2  bouyer 	tst.l		%d7		# check sign of the k-factor
   24324  1.1.6.2  bouyer 	blt.b		use_ilog	# if negative, use ILOG
   24325  1.1.6.2  bouyer 	fmov.s		F4933(%pc),%fp0	# force exponent to 4933
   24326  1.1.6.2  bouyer 	bra.b		convrt		# do it
   24327  1.1.6.2  bouyer use_ilog:
   24328  1.1.6.2  bouyer 	fmov.l		%d6,%fp0	# float ILOG
   24329  1.1.6.2  bouyer 	fabs.x		%fp0		# get abs of ILOG
   24330  1.1.6.2  bouyer 	bra.b		convrt
   24331  1.1.6.2  bouyer not_denorm:
   24332  1.1.6.2  bouyer 	ftest.x		%fp0		# test for zero
   24333  1.1.6.2  bouyer 	fbneq.w		not_zero	# if zero, force exponent
   24334  1.1.6.2  bouyer 	fmov.s		FONE(%pc),%fp0	# force exponent to 1
   24335  1.1.6.2  bouyer 	bra.b		convrt		# do it
   24336  1.1.6.2  bouyer not_zero:
   24337  1.1.6.2  bouyer 	fmov.l		%d6,%fp0	# float ILOG
   24338  1.1.6.2  bouyer 	fabs.x		%fp0		# get abs of ILOG
   24339  1.1.6.2  bouyer convrt:
   24340  1.1.6.2  bouyer 	fdiv.x		24(%a1),%fp0	# compute ILOG/10^4
   24341  1.1.6.2  bouyer 	fmov.x		%fp0,FP_SCR1(%a6)	# store fp0 in memory
   24342  1.1.6.2  bouyer 	mov.l		4(%a2),%d2	# move word 2 to d2
   24343  1.1.6.2  bouyer 	mov.l		8(%a2),%d3	# move word 3 to d3
   24344  1.1.6.2  bouyer 	mov.w		(%a2),%d0	# move exp to d0
   24345  1.1.6.2  bouyer 	beq.b		x_loop_fin	# if zero, skip the shift
   24346  1.1.6.2  bouyer 	sub.w		&0x3ffd,%d0	# subtract off bias
   24347  1.1.6.2  bouyer 	neg.w		%d0		# make exp positive
   24348  1.1.6.2  bouyer x_loop:
   24349  1.1.6.2  bouyer 	lsr.l		&1,%d2		# shift d2:d3 right
   24350  1.1.6.2  bouyer 	roxr.l		&1,%d3		# the number of places
   24351  1.1.6.2  bouyer 	dbf.w		%d0,x_loop	# given in d0
   24352  1.1.6.2  bouyer x_loop_fin:
   24353  1.1.6.2  bouyer 	clr.l		%d1		# put zero in d1 for addx
   24354  1.1.6.2  bouyer 	add.l		&0x00000080,%d3	# inc at bit 6
   24355  1.1.6.2  bouyer 	addx.l		%d1,%d2		# continue inc
   24356  1.1.6.2  bouyer 	and.l		&0xffffff80,%d3	# strip off lsb not used by 882
   24357  1.1.6.2  bouyer 	mov.l		&4,%d0		# put 4 in d0 for binstr call
   24358  1.1.6.2  bouyer 	lea.l		L_SCR1(%a6),%a0	# a0 is ptr to L_SCR1 for exp digits
   24359  1.1.6.2  bouyer 	bsr		binstr		# call binstr to convert exp
   24360  1.1.6.2  bouyer 	mov.l		L_SCR1(%a6),%d0	# load L_SCR1 lword to d0
   24361  1.1.6.2  bouyer 	mov.l		&12,%d1		# use d1 for shift count
   24362  1.1.6.2  bouyer 	lsr.l		%d1,%d0		# shift d0 right by 12
   24363  1.1.6.2  bouyer 	bfins		%d0,FP_SCR0(%a6){&4:&12}	# put e3:e2:e1 in FP_SCR0
   24364  1.1.6.2  bouyer 	lsr.l		%d1,%d0		# shift d0 right by 12
   24365  1.1.6.2  bouyer 	bfins		%d0,FP_SCR0(%a6){&16:&4}	# put e4 in FP_SCR0
   24366  1.1.6.2  bouyer 	tst.b		%d0		# check if e4 is zero
   24367  1.1.6.2  bouyer 	beq.b		A16_st		# if zero, skip rest
   24368  1.1.6.2  bouyer 	or.l		&opaop_mask,USER_FPSR(%a6)	# set OPERR & AIOP in USER_FPSR
   24369  1.1.6.2  bouyer 
   24370  1.1.6.2  bouyer 
   24371  1.1.6.2  bouyer # A16. Write sign bits to final string.
   24372  1.1.6.2  bouyer #	   Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG).
   24373  1.1.6.2  bouyer #
   24374  1.1.6.2  bouyer # Register usage:
   24375  1.1.6.2  bouyer #	Input/Output
   24376  1.1.6.2  bouyer #	d0: x/scratch - final is x
   24377  1.1.6.2  bouyer #	d2: x/x
   24378  1.1.6.2  bouyer #	d3: x/x
   24379  1.1.6.2  bouyer #	d4: LEN/Unchanged
   24380  1.1.6.2  bouyer #	d5: ICTR:LAMBDA/LAMBDA:ICTR
   24381  1.1.6.2  bouyer #	d6: ILOG/ILOG adjusted
   24382  1.1.6.2  bouyer #	d7: k-factor/Unchanged
   24383  1.1.6.2  bouyer #	a0: ptr to L_SCR1(a6)/Unchanged
   24384  1.1.6.2  bouyer #	a1: ptr to PTENxx array/Unchanged
   24385  1.1.6.2  bouyer #	a2: ptr to FP_SCR1(a6)/Unchanged
   24386  1.1.6.2  bouyer #	fp0: float(ILOG)/Unchanged
   24387  1.1.6.2  bouyer #	fp1: 10^ISCALE/Unchanged
   24388  1.1.6.2  bouyer #	fp2: 10^LEN/Unchanged
   24389  1.1.6.2  bouyer #	F_SCR1:BCD result with correct signs
   24390  1.1.6.2  bouyer #	F_SCR2:ILOG/10^4
   24391  1.1.6.2  bouyer #	L_SCR1:Exponent digits on return from binstr
   24392  1.1.6.2  bouyer #	L_SCR2:first word of X packed/Unchanged
   24393  1.1.6.2  bouyer 
   24394  1.1.6.2  bouyer A16_st:
   24395  1.1.6.2  bouyer 	clr.l		%d0		# clr d0 for collection of signs
   24396  1.1.6.2  bouyer 	and.b		&0x0f,FP_SCR0(%a6)	# clear first nibble of FP_SCR0
   24397  1.1.6.2  bouyer 	tst.l		L_SCR2(%a6)	# check sign of original mantissa
   24398  1.1.6.2  bouyer 	bge.b		mant_p		# if pos, don't set SM
   24399  1.1.6.2  bouyer 	mov.l		&2,%d0		# move 2 in to d0 for SM
   24400  1.1.6.2  bouyer mant_p:
   24401  1.1.6.2  bouyer 	tst.l		%d6		# check sign of ILOG
   24402  1.1.6.2  bouyer 	bge.b		wr_sgn		# if pos, don't set SE
   24403  1.1.6.2  bouyer 	addq.l		&1,%d0		# set bit 0 in d0 for SE
   24404  1.1.6.2  bouyer wr_sgn:
   24405  1.1.6.2  bouyer 	bfins		%d0,FP_SCR0(%a6){&0:&2}	# insert SM and SE into FP_SCR0
   24406  1.1.6.2  bouyer 
   24407  1.1.6.2  bouyer # Clean up and restore all registers used.
   24408  1.1.6.2  bouyer 
   24409  1.1.6.2  bouyer 	fmov.l		&0,%fpsr	# clear possible inex2/ainex bits
   24410  1.1.6.2  bouyer 	fmovm.x		(%sp)+,&0xe0	#  {%fp0-%fp2}
   24411  1.1.6.2  bouyer 	movm.l		(%sp)+,&0x4fc	#  {%d2-%d7/%a2}
   24412  1.1.6.2  bouyer 	rts
   24413  1.1.6.2  bouyer 
   24414  1.1.6.2  bouyer 	global		PTENRN
   24415  1.1.6.2  bouyer PTENRN:
   24416  1.1.6.2  bouyer 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   24417  1.1.6.2  bouyer 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   24418  1.1.6.2  bouyer 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   24419  1.1.6.2  bouyer 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   24420  1.1.6.2  bouyer 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   24421  1.1.6.2  bouyer 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   24422  1.1.6.2  bouyer 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   24423  1.1.6.2  bouyer 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   24424  1.1.6.2  bouyer 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   24425  1.1.6.2  bouyer 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   24426  1.1.6.2  bouyer 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   24427  1.1.6.2  bouyer 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   24428  1.1.6.2  bouyer 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   24429  1.1.6.2  bouyer 
   24430  1.1.6.2  bouyer 	global		PTENRP
   24431  1.1.6.2  bouyer PTENRP:
   24432  1.1.6.2  bouyer 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   24433  1.1.6.2  bouyer 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   24434  1.1.6.2  bouyer 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   24435  1.1.6.2  bouyer 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   24436  1.1.6.2  bouyer 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   24437  1.1.6.2  bouyer 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
   24438  1.1.6.2  bouyer 	long		0x40D30000,0xC2781F49,0xFFCFA6D6	# 10 ^ 64
   24439  1.1.6.2  bouyer 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
   24440  1.1.6.2  bouyer 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
   24441  1.1.6.2  bouyer 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
   24442  1.1.6.2  bouyer 	long		0x4D480000,0xC9767586,0x81750C18	# 10 ^ 1024
   24443  1.1.6.2  bouyer 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
   24444  1.1.6.2  bouyer 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
   24445  1.1.6.2  bouyer 
   24446  1.1.6.2  bouyer 	global		PTENRM
   24447  1.1.6.2  bouyer PTENRM:
   24448  1.1.6.2  bouyer 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
   24449  1.1.6.2  bouyer 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
   24450  1.1.6.2  bouyer 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
   24451  1.1.6.2  bouyer 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
   24452  1.1.6.2  bouyer 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
   24453  1.1.6.2  bouyer 	long		0x40690000,0x9DC5ADA8,0x2B70B59D	# 10 ^ 32
   24454  1.1.6.2  bouyer 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
   24455  1.1.6.2  bouyer 	long		0x41A80000,0x93BA47C9,0x80E98CDF	# 10 ^ 128
   24456  1.1.6.2  bouyer 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8D	# 10 ^ 256
   24457  1.1.6.2  bouyer 	long		0x46A30000,0xE319A0AE,0xA60E91C6	# 10 ^ 512
   24458  1.1.6.2  bouyer 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
   24459  1.1.6.2  bouyer 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE4	# 10 ^ 2048
   24460  1.1.6.2  bouyer 	long		0x75250000,0xC4605202,0x8A20979A	# 10 ^ 4096
   24461  1.1.6.2  bouyer 
   24462  1.1.6.2  bouyer #########################################################################
   24463  1.1.6.2  bouyer # binstr(): Converts a 64-bit binary integer to bcd.			#
   24464  1.1.6.2  bouyer #									#
   24465  1.1.6.2  bouyer # INPUT *************************************************************** #
   24466  1.1.6.2  bouyer #	d2:d3 = 64-bit binary integer					#
   24467  1.1.6.2  bouyer #	d0    = desired length (LEN)					#
   24468  1.1.6.2  bouyer #	a0    = pointer to start in memory for bcd characters		#
   24469  1.1.6.2  bouyer #          	(This pointer must point to byte 4 of the first		#
   24470  1.1.6.2  bouyer #          	 lword of the packed decimal memory string.)		#
   24471  1.1.6.2  bouyer #									#
   24472  1.1.6.2  bouyer # OUTPUT ************************************************************** #
   24473  1.1.6.2  bouyer #	a0 = pointer to LEN bcd digits representing the 64-bit integer.	#
   24474  1.1.6.2  bouyer #									#
   24475  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   24476  1.1.6.2  bouyer #	The 64-bit binary is assumed to have a decimal point before	#
   24477  1.1.6.2  bouyer #	bit 63.  The fraction is multiplied by 10 using a mul by 2	#
   24478  1.1.6.2  bouyer #	shift and a mul by 8 shift.  The bits shifted out of the	#
   24479  1.1.6.2  bouyer #	msb form a decimal digit.  This process is iterated until	#
   24480  1.1.6.2  bouyer #	LEN digits are formed.						#
   24481  1.1.6.2  bouyer #									#
   24482  1.1.6.2  bouyer # A1. Init d7 to 1.  D7 is the byte digit counter, and if 1, the	#
   24483  1.1.6.2  bouyer #     digit formed will be assumed the least significant.  This is	#
   24484  1.1.6.2  bouyer #     to force the first byte formed to have a 0 in the upper 4 bits.	#
   24485  1.1.6.2  bouyer #									#
   24486  1.1.6.2  bouyer # A2. Beginning of the loop:						#
   24487  1.1.6.2  bouyer #     Copy the fraction in d2:d3 to d4:d5.				#
   24488  1.1.6.2  bouyer #									#
   24489  1.1.6.2  bouyer # A3. Multiply the fraction in d2:d3 by 8 using bit-field		#
   24490  1.1.6.2  bouyer #     extracts and shifts.  The three msbs from d2 will go into d1.	#
   24491  1.1.6.2  bouyer #									#
   24492  1.1.6.2  bouyer # A4. Multiply the fraction in d4:d5 by 2 using shifts.  The msb	#
   24493  1.1.6.2  bouyer #     will be collected by the carry.					#
   24494  1.1.6.2  bouyer #									#
   24495  1.1.6.2  bouyer # A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5	#
   24496  1.1.6.2  bouyer #     into d2:d3.  D1 will contain the bcd digit formed.		#
   24497  1.1.6.2  bouyer #									#
   24498  1.1.6.2  bouyer # A6. Test d7.  If zero, the digit formed is the ms digit.  If non-	#
   24499  1.1.6.2  bouyer #     zero, it is the ls digit.  Put the digit in its place in the	#
   24500  1.1.6.2  bouyer #     upper word of d0.  If it is the ls digit, write the word		#
   24501  1.1.6.2  bouyer #     from d0 to memory.						#
   24502  1.1.6.2  bouyer #									#
   24503  1.1.6.2  bouyer # A7. Decrement d6 (LEN counter) and repeat the loop until zero.	#
   24504  1.1.6.2  bouyer #									#
   24505  1.1.6.2  bouyer #########################################################################
   24506  1.1.6.2  bouyer 
   24507  1.1.6.2  bouyer #	Implementation Notes:
   24508  1.1.6.2  bouyer #
   24509  1.1.6.2  bouyer #	The registers are used as follows:
   24510  1.1.6.2  bouyer #
   24511  1.1.6.2  bouyer #		d0: LEN counter
   24512  1.1.6.2  bouyer #		d1: temp used to form the digit
   24513  1.1.6.2  bouyer #		d2: upper 32-bits of fraction for mul by 8
   24514  1.1.6.2  bouyer #		d3: lower 32-bits of fraction for mul by 8
   24515  1.1.6.2  bouyer #		d4: upper 32-bits of fraction for mul by 2
   24516  1.1.6.2  bouyer #		d5: lower 32-bits of fraction for mul by 2
   24517  1.1.6.2  bouyer #		d6: temp for bit-field extracts
   24518  1.1.6.2  bouyer #		d7: byte digit formation word;digit count {0,1}
   24519  1.1.6.2  bouyer #		a0: pointer into memory for packed bcd string formation
   24520  1.1.6.2  bouyer #
   24521  1.1.6.2  bouyer 
   24522  1.1.6.2  bouyer 	global		binstr
   24523  1.1.6.2  bouyer binstr:
   24524  1.1.6.2  bouyer 	movm.l		&0xff00,-(%sp)	#  {%d0-%d7}
   24525  1.1.6.2  bouyer 
   24526  1.1.6.2  bouyer #
   24527  1.1.6.2  bouyer # A1: Init d7
   24528  1.1.6.2  bouyer #
   24529  1.1.6.2  bouyer 	mov.l		&1,%d7		# init d7 for second digit
   24530  1.1.6.2  bouyer 	subq.l		&1,%d0		# for dbf d0 would have LEN+1 passes
   24531  1.1.6.2  bouyer #
   24532  1.1.6.2  bouyer # A2. Copy d2:d3 to d4:d5.  Start loop.
   24533  1.1.6.2  bouyer #
   24534  1.1.6.2  bouyer loop:
   24535  1.1.6.2  bouyer 	mov.l		%d2,%d4		# copy the fraction before muls
   24536  1.1.6.2  bouyer 	mov.l		%d3,%d5		# to d4:d5
   24537  1.1.6.2  bouyer #
   24538  1.1.6.2  bouyer # A3. Multiply d2:d3 by 8; extract msbs into d1.
   24539  1.1.6.2  bouyer #
   24540  1.1.6.2  bouyer 	bfextu		%d2{&0:&3},%d1	# copy 3 msbs of d2 into d1
   24541  1.1.6.2  bouyer 	asl.l		&3,%d2		# shift d2 left by 3 places
   24542  1.1.6.2  bouyer 	bfextu		%d3{&0:&3},%d6	# copy 3 msbs of d3 into d6
   24543  1.1.6.2  bouyer 	asl.l		&3,%d3		# shift d3 left by 3 places
   24544  1.1.6.2  bouyer 	or.l		%d6,%d2		# or in msbs from d3 into d2
   24545  1.1.6.2  bouyer #
   24546  1.1.6.2  bouyer # A4. Multiply d4:d5 by 2; add carry out to d1.
   24547  1.1.6.2  bouyer #
   24548  1.1.6.2  bouyer 	asl.l		&1,%d5		# mul d5 by 2
   24549  1.1.6.2  bouyer 	roxl.l		&1,%d4		# mul d4 by 2
   24550  1.1.6.2  bouyer 	swap		%d6		# put 0 in d6 lower word
   24551  1.1.6.2  bouyer 	addx.w		%d6,%d1		# add in extend from mul by 2
   24552  1.1.6.2  bouyer #
   24553  1.1.6.2  bouyer # A5. Add mul by 8 to mul by 2.  D1 contains the digit formed.
   24554  1.1.6.2  bouyer #
   24555  1.1.6.2  bouyer 	add.l		%d5,%d3		# add lower 32 bits
   24556  1.1.6.2  bouyer 	nop				# ERRATA FIX #13 (Rev. 1.2 6/6/90)
   24557  1.1.6.2  bouyer 	addx.l		%d4,%d2		# add with extend upper 32 bits
   24558  1.1.6.2  bouyer 	nop				# ERRATA FIX #13 (Rev. 1.2 6/6/90)
   24559  1.1.6.2  bouyer 	addx.w		%d6,%d1		# add in extend from add to d1
   24560  1.1.6.2  bouyer 	swap		%d6		# with d6 = 0; put 0 in upper word
   24561  1.1.6.2  bouyer #
   24562  1.1.6.2  bouyer # A6. Test d7 and branch.
   24563  1.1.6.2  bouyer #
   24564  1.1.6.2  bouyer 	tst.w		%d7		# if zero, store digit & to loop
   24565  1.1.6.2  bouyer 	beq.b		first_d		# if non-zero, form byte & write
   24566  1.1.6.2  bouyer sec_d:
   24567  1.1.6.2  bouyer 	swap		%d7		# bring first digit to word d7b
   24568  1.1.6.2  bouyer 	asl.w		&4,%d7		# first digit in upper 4 bits d7b
   24569  1.1.6.2  bouyer 	add.w		%d1,%d7		# add in ls digit to d7b
   24570  1.1.6.2  bouyer 	mov.b		%d7,(%a0)+	# store d7b byte in memory
   24571  1.1.6.2  bouyer 	swap		%d7		# put LEN counter in word d7a
   24572  1.1.6.2  bouyer 	clr.w		%d7		# set d7a to signal no digits done
   24573  1.1.6.2  bouyer 	dbf.w		%d0,loop	# do loop some more!
   24574  1.1.6.2  bouyer 	bra.b		end_bstr	# finished, so exit
   24575  1.1.6.2  bouyer first_d:
   24576  1.1.6.2  bouyer 	swap		%d7		# put digit word in d7b
   24577  1.1.6.2  bouyer 	mov.w		%d1,%d7		# put new digit in d7b
   24578  1.1.6.2  bouyer 	swap		%d7		# put LEN counter in word d7a
   24579  1.1.6.2  bouyer 	addq.w		&1,%d7		# set d7a to signal first digit done
   24580  1.1.6.2  bouyer 	dbf.w		%d0,loop	# do loop some more!
   24581  1.1.6.2  bouyer 	swap		%d7		# put last digit in string
   24582  1.1.6.2  bouyer 	lsl.w		&4,%d7		# move it to upper 4 bits
   24583  1.1.6.2  bouyer 	mov.b		%d7,(%a0)+	# store it in memory string
   24584  1.1.6.2  bouyer #
   24585  1.1.6.2  bouyer # Clean up and return with result in fp0.
   24586  1.1.6.2  bouyer #
   24587  1.1.6.2  bouyer end_bstr:
   24588  1.1.6.2  bouyer 	movm.l		(%sp)+,&0xff	#  {%d0-%d7}
   24589  1.1.6.2  bouyer 	rts
   24590  1.1.6.2  bouyer 
   24591  1.1.6.2  bouyer #########################################################################
   24592  1.1.6.2  bouyer # XDEF ****************************************************************	#
   24593  1.1.6.2  bouyer #	facc_in_b(): dmem_read_byte failed				#
   24594  1.1.6.2  bouyer #	facc_in_w(): dmem_read_word failed				#
   24595  1.1.6.2  bouyer #	facc_in_l(): dmem_read_long failed				#
   24596  1.1.6.2  bouyer #	facc_in_d(): dmem_read of dbl prec failed			#
   24597  1.1.6.2  bouyer #	facc_in_x(): dmem_read of ext prec failed			#
   24598  1.1.6.2  bouyer #									#
   24599  1.1.6.2  bouyer #	facc_out_b(): dmem_write_byte failed				#
   24600  1.1.6.2  bouyer #	facc_out_w(): dmem_write_word failed				#
   24601  1.1.6.2  bouyer #	facc_out_l(): dmem_write_long failed				#
   24602  1.1.6.2  bouyer #	facc_out_d(): dmem_write of dbl prec failed			#
   24603  1.1.6.2  bouyer #	facc_out_x(): dmem_write of ext prec failed			#
   24604  1.1.6.2  bouyer #									#
   24605  1.1.6.2  bouyer # XREF ****************************************************************	#
   24606  1.1.6.2  bouyer #	_real_access() - exit through access error handler		#
   24607  1.1.6.2  bouyer #									#
   24608  1.1.6.2  bouyer # INPUT ***************************************************************	#
   24609  1.1.6.2  bouyer #	None								#
   24610  1.1.6.2  bouyer # 									#
   24611  1.1.6.2  bouyer # OUTPUT **************************************************************	#
   24612  1.1.6.2  bouyer #	None								#
   24613  1.1.6.2  bouyer #									#
   24614  1.1.6.2  bouyer # ALGORITHM ***********************************************************	#
   24615  1.1.6.2  bouyer # 	Flow jumps here when an FP data fetch call gets an error 	#
   24616  1.1.6.2  bouyer # result. This means the operating system wants an access error frame	#
   24617  1.1.6.2  bouyer # made out of the current exception stack frame. 			#
   24618  1.1.6.2  bouyer #	So, we first call restore() which makes sure that any updated	#
   24619  1.1.6.2  bouyer # -(an)+ register gets returned to its pre-exception value and then	#
   24620  1.1.6.2  bouyer # we change the stack to an acess error stack frame.			#
   24621  1.1.6.2  bouyer #									#
   24622  1.1.6.2  bouyer #########################################################################
   24623  1.1.6.2  bouyer 
   24624  1.1.6.2  bouyer facc_in_b:
   24625  1.1.6.2  bouyer 	movq.l		&0x1,%d0			# one byte
   24626  1.1.6.2  bouyer 	bsr.w		restore				# fix An
   24627  1.1.6.2  bouyer 
   24628  1.1.6.2  bouyer 	mov.w		&0x0121,EXC_VOFF(%a6)		# set FSLW
   24629  1.1.6.2  bouyer 	bra.w		facc_finish
   24630  1.1.6.2  bouyer 
   24631  1.1.6.2  bouyer facc_in_w:
   24632  1.1.6.2  bouyer 	movq.l		&0x2,%d0			# two bytes
   24633  1.1.6.2  bouyer 	bsr.w		restore				# fix An
   24634  1.1.6.2  bouyer 
   24635  1.1.6.2  bouyer 	mov.w		&0x0141,EXC_VOFF(%a6)		# set FSLW
   24636  1.1.6.2  bouyer 	bra.b		facc_finish
   24637  1.1.6.2  bouyer 
   24638  1.1.6.2  bouyer facc_in_l:
   24639  1.1.6.2  bouyer 	movq.l		&0x4,%d0			# four bytes
   24640  1.1.6.2  bouyer 	bsr.w		restore				# fix An
   24641  1.1.6.2  bouyer 
   24642  1.1.6.2  bouyer 	mov.w		&0x0101,EXC_VOFF(%a6)		# set FSLW
   24643  1.1.6.2  bouyer 	bra.b		facc_finish
   24644  1.1.6.2  bouyer 
   24645  1.1.6.2  bouyer facc_in_d:
   24646  1.1.6.2  bouyer 	movq.l		&0x8,%d0			# eight bytes
   24647  1.1.6.2  bouyer 	bsr.w		restore				# fix An
   24648  1.1.6.2  bouyer 
   24649  1.1.6.2  bouyer 	mov.w		&0x0161,EXC_VOFF(%a6)		# set FSLW
   24650  1.1.6.2  bouyer 	bra.b		facc_finish
   24651  1.1.6.2  bouyer 
   24652  1.1.6.2  bouyer facc_in_x:
   24653  1.1.6.2  bouyer 	movq.l		&0xc,%d0			# twelve bytes
   24654  1.1.6.2  bouyer 	bsr.w		restore				# fix An
   24655  1.1.6.2  bouyer 
   24656  1.1.6.2  bouyer 	mov.w		&0x0161,EXC_VOFF(%a6)		# set FSLW
   24657  1.1.6.2  bouyer 	bra.b		facc_finish
   24658  1.1.6.2  bouyer 
   24659  1.1.6.2  bouyer ################################################################
   24660  1.1.6.2  bouyer 
   24661  1.1.6.2  bouyer facc_out_b:
   24662  1.1.6.2  bouyer 	movq.l		&0x1,%d0			# one byte
   24663  1.1.6.2  bouyer 	bsr.w		restore				# restore An
   24664  1.1.6.2  bouyer 
   24665  1.1.6.2  bouyer 	mov.w		&0x00a1,EXC_VOFF(%a6)		# set FSLW
   24666  1.1.6.2  bouyer 	bra.b		facc_finish
   24667  1.1.6.2  bouyer 
   24668  1.1.6.2  bouyer facc_out_w:
   24669  1.1.6.2  bouyer 	movq.l		&0x2,%d0			# two bytes
   24670  1.1.6.2  bouyer 	bsr.w		restore				# restore An
   24671  1.1.6.2  bouyer 
   24672  1.1.6.2  bouyer 	mov.w		&0x00c1,EXC_VOFF(%a6)		# set FSLW
   24673  1.1.6.2  bouyer 	bra.b		facc_finish
   24674  1.1.6.2  bouyer 
   24675  1.1.6.2  bouyer facc_out_l:
   24676  1.1.6.2  bouyer 	movq.l		&0x4,%d0			# four bytes
   24677  1.1.6.2  bouyer 	bsr.w		restore				# restore An
   24678  1.1.6.2  bouyer 
   24679  1.1.6.2  bouyer 	mov.w		&0x0081,EXC_VOFF(%a6)		# set FSLW
   24680  1.1.6.2  bouyer 	bra.b		facc_finish
   24681  1.1.6.2  bouyer 
   24682  1.1.6.2  bouyer facc_out_d:
   24683  1.1.6.2  bouyer 	movq.l		&0x8,%d0			# eight bytes
   24684  1.1.6.2  bouyer 	bsr.w		restore				# restore An
   24685  1.1.6.2  bouyer 
   24686  1.1.6.2  bouyer 	mov.w		&0x00e1,EXC_VOFF(%a6)		# set FSLW
   24687  1.1.6.2  bouyer 	bra.b		facc_finish
   24688  1.1.6.2  bouyer 
   24689  1.1.6.2  bouyer facc_out_x:
   24690  1.1.6.2  bouyer 	mov.l		&0xc,%d0			# twelve bytes
   24691  1.1.6.2  bouyer 	bsr.w		restore				# restore An
   24692  1.1.6.2  bouyer 
   24693  1.1.6.2  bouyer 	mov.w		&0x00e1,EXC_VOFF(%a6)		# set FSLW
   24694  1.1.6.2  bouyer 
   24695  1.1.6.2  bouyer # here's where we actually create the access error frame from the
   24696  1.1.6.2  bouyer # current exception stack frame.
   24697  1.1.6.2  bouyer facc_finish:
   24698  1.1.6.2  bouyer 	mov.l		USER_FPIAR(%a6),EXC_PC(%a6) # store current PC
   24699  1.1.6.2  bouyer 
   24700  1.1.6.2  bouyer 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
   24701  1.1.6.2  bouyer 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
   24702  1.1.6.2  bouyer 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
   24703  1.1.6.2  bouyer 
   24704  1.1.6.2  bouyer 	unlk		%a6
   24705  1.1.6.2  bouyer 
   24706  1.1.6.2  bouyer 	mov.l		(%sp),-(%sp)		# store SR, hi(PC)
   24707  1.1.6.2  bouyer 	mov.l		0x8(%sp),0x4(%sp)	# store lo(PC)
   24708  1.1.6.2  bouyer 	mov.l		0xc(%sp),0x8(%sp)	# store EA
   24709  1.1.6.2  bouyer 	mov.l		&0x00000001,0xc(%sp)	# store FSLW
   24710  1.1.6.2  bouyer 	mov.w		0x6(%sp),0xc(%sp)	# fix FSLW (size)
   24711  1.1.6.2  bouyer 	mov.w		&0x4008,0x6(%sp)	# store voff
   24712  1.1.6.2  bouyer 
   24713  1.1.6.2  bouyer 	btst		&0x5,(%sp)		# supervisor or user mode?
   24714  1.1.6.2  bouyer 	beq.b		facc_out2		# user
   24715  1.1.6.2  bouyer 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
   24716  1.1.6.2  bouyer 
   24717  1.1.6.2  bouyer facc_out2:
   24718  1.1.6.2  bouyer 	bra.l		_real_access
   24719  1.1.6.2  bouyer 
   24720  1.1.6.2  bouyer ##################################################################
   24721  1.1.6.2  bouyer 
   24722  1.1.6.2  bouyer # if the effective addressing mode was predecrement or postincrement,
   24723  1.1.6.2  bouyer # the emulation has already changed its value to the correct post-
   24724  1.1.6.2  bouyer # instruction value. but since we're exiting to the access error
   24725  1.1.6.2  bouyer # handler, then AN must be returned to its pre-instruction value.
   24726  1.1.6.2  bouyer # we do that here.
   24727  1.1.6.2  bouyer restore:
   24728  1.1.6.2  bouyer 	mov.b		EXC_OPWORD+0x1(%a6),%d1
   24729  1.1.6.2  bouyer 	andi.b		&0x38,%d1		# extract opmode
   24730  1.1.6.2  bouyer 	cmpi.b		%d1,&0x18		# postinc?
   24731  1.1.6.2  bouyer 	beq.w		rest_inc
   24732  1.1.6.2  bouyer 	cmpi.b		%d1,&0x20		# predec?
   24733  1.1.6.2  bouyer 	beq.w		rest_dec
   24734  1.1.6.2  bouyer 	rts
   24735  1.1.6.2  bouyer 
   24736  1.1.6.2  bouyer rest_inc:
   24737  1.1.6.2  bouyer 	mov.b		EXC_OPWORD+0x1(%a6),%d1
   24738  1.1.6.2  bouyer 	andi.w		&0x0007,%d1		# fetch An
   24739  1.1.6.2  bouyer 
   24740  1.1.6.2  bouyer 	mov.w		(tbl_rest_inc.b,%pc,%d1.w*2),%d1
   24741  1.1.6.2  bouyer 	jmp		(tbl_rest_inc.b,%pc,%d1.w*1)
   24742  1.1.6.2  bouyer 
   24743  1.1.6.2  bouyer tbl_rest_inc:
   24744  1.1.6.2  bouyer 	short		ri_a0 - tbl_rest_inc
   24745  1.1.6.2  bouyer 	short		ri_a1 - tbl_rest_inc
   24746  1.1.6.2  bouyer 	short		ri_a2 - tbl_rest_inc
   24747  1.1.6.2  bouyer 	short		ri_a3 - tbl_rest_inc
   24748  1.1.6.2  bouyer 	short		ri_a4 - tbl_rest_inc
   24749  1.1.6.2  bouyer 	short		ri_a5 - tbl_rest_inc
   24750  1.1.6.2  bouyer 	short		ri_a6 - tbl_rest_inc
   24751  1.1.6.2  bouyer 	short		ri_a7 - tbl_rest_inc
   24752  1.1.6.2  bouyer 
   24753  1.1.6.2  bouyer ri_a0:
   24754  1.1.6.2  bouyer 	sub.l		%d0,EXC_DREGS+0x8(%a6)	# fix stacked a0
   24755  1.1.6.2  bouyer 	rts
   24756  1.1.6.2  bouyer ri_a1:
   24757  1.1.6.2  bouyer 	sub.l		%d0,EXC_DREGS+0xc(%a6)	# fix stacked a1
   24758  1.1.6.2  bouyer 	rts
   24759  1.1.6.2  bouyer ri_a2:
   24760  1.1.6.2  bouyer 	sub.l		%d0,%a2			# fix a2
   24761  1.1.6.2  bouyer 	rts
   24762  1.1.6.2  bouyer ri_a3:
   24763  1.1.6.2  bouyer 	sub.l		%d0,%a3			# fix a3
   24764  1.1.6.2  bouyer 	rts
   24765  1.1.6.2  bouyer ri_a4:
   24766  1.1.6.2  bouyer 	sub.l		%d0,%a4			# fix a4
   24767  1.1.6.2  bouyer 	rts
   24768  1.1.6.2  bouyer ri_a5:
   24769  1.1.6.2  bouyer 	sub.l		%d0,%a5			# fix a5
   24770  1.1.6.2  bouyer 	rts
   24771  1.1.6.2  bouyer ri_a6:
   24772  1.1.6.2  bouyer 	sub.l		%d0,(%a6)		# fix stacked a6
   24773  1.1.6.2  bouyer 	rts
   24774  1.1.6.2  bouyer # if it's a fmove out instruction, we don't have to fix a7
   24775  1.1.6.2  bouyer # because we hadn't changed it yet. if it's an opclass two
   24776  1.1.6.2  bouyer # instruction (data moved in) and the exception was in supervisor
   24777  1.1.6.2  bouyer # mode, then also also wasn't updated. if it was user mode, then
   24778  1.1.6.2  bouyer # restore the correct a7 which is in the USP currently.
   24779  1.1.6.2  bouyer ri_a7:
   24780  1.1.6.2  bouyer 	cmpi.b		EXC_VOFF(%a6),&0x30	# move in or out?
   24781  1.1.6.2  bouyer 	bne.b		ri_a7_done		# out
   24782  1.1.6.2  bouyer 
   24783  1.1.6.2  bouyer 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
   24784  1.1.6.2  bouyer 	bne.b		ri_a7_done		# supervisor
   24785  1.1.6.2  bouyer 	movc		%usp,%a0		# restore USP
   24786  1.1.6.2  bouyer 	sub.l		%d0,%a0
   24787  1.1.6.2  bouyer 	movc		%a0,%usp
   24788  1.1.6.2  bouyer ri_a7_done:
   24789  1.1.6.2  bouyer 	rts
   24790  1.1.6.2  bouyer 
   24791  1.1.6.2  bouyer # need to invert adjustment value if the <ea> was predec
   24792  1.1.6.2  bouyer rest_dec:
   24793  1.1.6.2  bouyer 	neg.l		%d0
   24794  1.1.6.2  bouyer 	bra.b		rest_inc
   24795