Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     1) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     2) MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     3) M68000 Hi-Performance Microprocessor Division
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     4) M68060 Software Package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     5) Production Release P1.00 -- October 10, 1994
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     7) M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300     9) THE SOFTWARE is provided on an "AS IS" basis and without warranty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    10) To the maximum extent permitted by applicable law,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    11) MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    12) INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    13) and any warranty against infringement with regard to the SOFTWARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    14) (INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    16) To the maximum extent permitted by applicable law,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    17) IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    18) (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    19) BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    20) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    21) Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    23) You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    24) so long as this entire notice is retained without alteration in any modified and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    25) redistributed versions, and that such modified versions are clearly identified as such.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    26) No licenses are granted by implication, estoppel or otherwise under any patents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    27) or trademarks of Motorola, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    28) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    29) # freal.s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    30) #	This file is appended to the top of the 060FPSP package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    31) # and contains the entry points into the package. The user, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    32) # effect, branches to one of the branch table entries located
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    33) # after _060FPSP_TABLE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    34) #	Also, subroutine stubs exist in this file (_fpsp_done for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    35) # example) that are referenced by the FPSP package itself in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    36) # to call a given routine. The stub routine actually performs the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    37) # callout. The FPSP code does a "bsr" to the stub routine. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    38) # extra layer of hierarchy adds a slight performance penalty but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    39) # it makes the FPSP code easier to read and more mainatinable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    40) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    42) set	_off_bsun,	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    43) set	_off_snan,	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    44) set	_off_operr,	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    45) set	_off_ovfl,	0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    46) set	_off_unfl,	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    47) set	_off_dz,	0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    48) set	_off_inex,	0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    49) set	_off_fline,	0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    50) set	_off_fpu_dis,	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    51) set	_off_trap,	0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    52) set	_off_trace,	0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    53) set	_off_access,	0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    54) set	_off_done,	0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    56) set	_off_imr,	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    57) set	_off_dmr,	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    58) set	_off_dmw,	0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    59) set	_off_irw,	0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    60) set	_off_irl,	0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    61) set	_off_drb,	0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    62) set	_off_drw,	0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    63) set	_off_drl,	0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    64) set	_off_dwb,	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    65) set	_off_dww,	0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    66) set	_off_dwl,	0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    68) _060FPSP_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    70) ###############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    72) # Here's the table of ENTRY POINTS for those linking the package.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    73) 	bra.l		_fpsp_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    74) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    75) 	bra.l		_fpsp_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    76) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    77) 	bra.l		_fpsp_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    78) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    79) 	bra.l		_fpsp_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    80) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    81) 	bra.l		_fpsp_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    82) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    83) 	bra.l		_fpsp_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    84) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    85) 	bra.l		_fpsp_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    86) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    87) 	bra.l		_fpsp_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    88) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    89) 	bra.l		_fpsp_effadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    90) 	short		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    92) 	space		56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    94) ###############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    95) 	global		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    96) _fpsp_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    97) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    98) 	mov.l		(_060FPSP_TABLE-0x80+_off_done,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    99) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   100) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   101) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   103) 	global		_real_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   104) _real_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   105) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   106) 	mov.l		(_060FPSP_TABLE-0x80+_off_ovfl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   107) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   108) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   109) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   111) 	global		_real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   112) _real_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   113) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   114) 	mov.l		(_060FPSP_TABLE-0x80+_off_unfl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   115) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   116) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   117) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   119) 	global		_real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   120) _real_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   121) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   122) 	mov.l		(_060FPSP_TABLE-0x80+_off_inex,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   123) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   124) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   125) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   127) 	global		_real_bsun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   128) _real_bsun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   129) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   130) 	mov.l		(_060FPSP_TABLE-0x80+_off_bsun,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   131) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   132) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   133) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   135) 	global		_real_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   136) _real_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   137) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   138) 	mov.l		(_060FPSP_TABLE-0x80+_off_operr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   139) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   140) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   141) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   143) 	global		_real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   144) _real_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   145) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   146) 	mov.l		(_060FPSP_TABLE-0x80+_off_snan,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   147) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   148) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   149) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   151) 	global		_real_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   152) _real_dz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   153) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   154) 	mov.l		(_060FPSP_TABLE-0x80+_off_dz,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   155) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   156) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   157) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   159) 	global		_real_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   160) _real_fline:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   161) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   162) 	mov.l		(_060FPSP_TABLE-0x80+_off_fline,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   163) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   164) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   165) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   167) 	global		_real_fpu_disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   168) _real_fpu_disabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   169) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   170) 	mov.l		(_060FPSP_TABLE-0x80+_off_fpu_dis,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   171) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   172) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   173) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   175) 	global		_real_trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   176) _real_trap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   177) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   178) 	mov.l		(_060FPSP_TABLE-0x80+_off_trap,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   179) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   180) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   181) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   183) 	global		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   184) _real_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   185) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   186) 	mov.l		(_060FPSP_TABLE-0x80+_off_trace,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   187) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   188) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   189) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   191) 	global		_real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   192) _real_access:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   193) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   194) 	mov.l		(_060FPSP_TABLE-0x80+_off_access,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   195) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   196) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   197) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   199) #######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   201) 	global		_imem_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   202) _imem_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   203) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   204) 	mov.l		(_060FPSP_TABLE-0x80+_off_imr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   205) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   206) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   207) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   209) 	global		_dmem_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   210) _dmem_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   211) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   212) 	mov.l		(_060FPSP_TABLE-0x80+_off_dmr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   213) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   214) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   215) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   217) 	global		_dmem_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   218) _dmem_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   219) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   220) 	mov.l		(_060FPSP_TABLE-0x80+_off_dmw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   221) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   222) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   223) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   225) 	global		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   226) _imem_read_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   227) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   228) 	mov.l		(_060FPSP_TABLE-0x80+_off_irw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   229) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   230) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   231) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   233) 	global		_imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   234) _imem_read_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   235) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   236) 	mov.l		(_060FPSP_TABLE-0x80+_off_irl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   237) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   238) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   239) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   241) 	global		_dmem_read_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   242) _dmem_read_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   243) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   244) 	mov.l		(_060FPSP_TABLE-0x80+_off_drb,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   245) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   246) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   247) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   249) 	global		_dmem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   250) _dmem_read_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   251) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   252) 	mov.l		(_060FPSP_TABLE-0x80+_off_drw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   253) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   254) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   255) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   257) 	global		_dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   258) _dmem_read_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   259) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   260) 	mov.l		(_060FPSP_TABLE-0x80+_off_drl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   261) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   262) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   263) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   265) 	global		_dmem_write_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   266) _dmem_write_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   267) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   268) 	mov.l		(_060FPSP_TABLE-0x80+_off_dwb,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   269) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   270) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   271) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   273) 	global		_dmem_write_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   274) _dmem_write_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   275) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   276) 	mov.l		(_060FPSP_TABLE-0x80+_off_dww,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   277) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   278) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   279) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   281) 	global		_dmem_write_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   282) _dmem_write_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   283) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   284) 	mov.l		(_060FPSP_TABLE-0x80+_off_dwl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   285) 	pea.l		(_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   286) 	mov.l		0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   287) 	rtd		&0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   289) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   290) # This file contains a set of define statements for constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   291) # in order to promote readability within the corecode itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   292) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   294) set LOCAL_SIZE,		192			# stack frame size(bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   295) set LV,			-LOCAL_SIZE		# stack offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   297) set EXC_SR,		0x4			# stack status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   298) set EXC_PC,		0x6			# stack pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   299) set EXC_VOFF,		0xa			# stacked vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   300) set EXC_EA,		0xc			# stacked <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   302) set EXC_FP,		0x0			# frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   304) set EXC_AREGS,		-68			# offset of all address regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   305) set EXC_DREGS,		-100			# offset of all data regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   306) set EXC_FPREGS,		-36			# offset of all fp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   308) set EXC_A7,		EXC_AREGS+(7*4)		# offset of saved a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   309) set OLD_A7,		EXC_AREGS+(6*4)		# extra copy of saved a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   310) set EXC_A6,		EXC_AREGS+(6*4)		# offset of saved a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   311) set EXC_A5,		EXC_AREGS+(5*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   312) set EXC_A4,		EXC_AREGS+(4*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   313) set EXC_A3,		EXC_AREGS+(3*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   314) set EXC_A2,		EXC_AREGS+(2*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   315) set EXC_A1,		EXC_AREGS+(1*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   316) set EXC_A0,		EXC_AREGS+(0*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   317) set EXC_D7,		EXC_DREGS+(7*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   318) set EXC_D6,		EXC_DREGS+(6*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   319) set EXC_D5,		EXC_DREGS+(5*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   320) set EXC_D4,		EXC_DREGS+(4*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   321) set EXC_D3,		EXC_DREGS+(3*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   322) set EXC_D2,		EXC_DREGS+(2*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   323) set EXC_D1,		EXC_DREGS+(1*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   324) set EXC_D0,		EXC_DREGS+(0*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   326) set EXC_FP0,		EXC_FPREGS+(0*12)	# offset of saved fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   327) set EXC_FP1,		EXC_FPREGS+(1*12)	# offset of saved fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   328) set EXC_FP2,		EXC_FPREGS+(2*12)	# offset of saved fp2 (not used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   330) set FP_SCR1,		LV+80			# fp scratch 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   331) set FP_SCR1_EX,		FP_SCR1+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   332) set FP_SCR1_SGN,	FP_SCR1+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   333) set FP_SCR1_HI,		FP_SCR1+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   334) set FP_SCR1_LO,		FP_SCR1+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   336) set FP_SCR0,		LV+68			# fp scratch 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   337) set FP_SCR0_EX,		FP_SCR0+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   338) set FP_SCR0_SGN,	FP_SCR0+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   339) set FP_SCR0_HI,		FP_SCR0+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   340) set FP_SCR0_LO,		FP_SCR0+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   342) set FP_DST,		LV+56			# fp destination operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   343) set FP_DST_EX,		FP_DST+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   344) set FP_DST_SGN,		FP_DST+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   345) set FP_DST_HI,		FP_DST+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   346) set FP_DST_LO,		FP_DST+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   348) set FP_SRC,		LV+44			# fp source operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   349) set FP_SRC_EX,		FP_SRC+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   350) set FP_SRC_SGN,		FP_SRC+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   351) set FP_SRC_HI,		FP_SRC+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   352) set FP_SRC_LO,		FP_SRC+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   354) set USER_FPIAR,		LV+40			# FP instr address register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   356) set USER_FPSR,		LV+36			# FP status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   357) set FPSR_CC,		USER_FPSR+0		# FPSR condition codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   358) set FPSR_QBYTE,		USER_FPSR+1		# FPSR qoutient byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   359) set FPSR_EXCEPT,	USER_FPSR+2		# FPSR exception status byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   360) set FPSR_AEXCEPT,	USER_FPSR+3		# FPSR accrued exception byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   362) set USER_FPCR,		LV+32			# FP control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   363) set FPCR_ENABLE,	USER_FPCR+2		# FPCR exception enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   364) set FPCR_MODE,		USER_FPCR+3		# FPCR rounding mode control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   366) set L_SCR3,		LV+28			# integer scratch 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   367) set L_SCR2,		LV+24			# integer scratch 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   368) set L_SCR1,		LV+20			# integer scratch 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   370) set STORE_FLG,		LV+19			# flag: operand store (ie. not fcmp/ftst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   372) set EXC_TEMP2,		LV+24			# temporary space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   373) set EXC_TEMP,		LV+16			# temporary space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   375) set DTAG,		LV+15			# destination operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   376) set STAG,		LV+14			# source operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   378) set SPCOND_FLG,		LV+10			# flag: special case (see below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   380) set EXC_CC,		LV+8			# saved condition codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   381) set EXC_EXTWPTR,	LV+4			# saved current PC (active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   382) set EXC_EXTWORD,	LV+2			# saved extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   383) set EXC_CMDREG,		LV+2			# saved extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   384) set EXC_OPWORD,		LV+0			# saved operation word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   386) ################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   388) # Helpful macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   390) set FTEMP,		0			# offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   391) set FTEMP_EX,		0			# extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   392) set FTEMP_SGN,		2			# value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   393) set FTEMP_HI,		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   394) set FTEMP_LO,		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   395) set FTEMP_GRS,		12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   397) set LOCAL,		0			# offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   398) set LOCAL_EX,		0			# extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   399) set LOCAL_SGN,		2			# value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   400) set LOCAL_HI,		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   401) set LOCAL_LO,		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   402) set LOCAL_GRS,		12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   404) set DST,		0			# offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   405) set DST_EX,		0			# extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   406) set DST_HI,		4			# value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   407) set DST_LO,		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   409) set SRC,		0			# offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   410) set SRC_EX,		0			# extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   411) set SRC_HI,		4			# value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   412) set SRC_LO,		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   414) set SGL_LO,		0x3f81			# min sgl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   415) set SGL_HI,		0x407e			# max sgl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   416) set DBL_LO,		0x3c01			# min dbl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   417) set DBL_HI,		0x43fe			# max dbl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   418) set EXT_LO,		0x0			# min ext prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   419) set EXT_HI,		0x7ffe			# max ext prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   421) set EXT_BIAS,		0x3fff			# extended precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   422) set SGL_BIAS,		0x007f			# single precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   423) set DBL_BIAS,		0x03ff			# double precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   425) set NORM,		0x00			# operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   426) set ZERO,		0x01			# operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   427) set INF,		0x02			# operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   428) set QNAN,		0x03			# operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   429) set DENORM,		0x04			# operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   430) set SNAN,		0x05			# operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   431) set UNNORM,		0x06			# operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   433) ##################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   434) # FPSR/FPCR bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   435) ##################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   436) set neg_bit,		0x3			# negative result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   437) set z_bit,		0x2			# zero result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   438) set inf_bit,		0x1			# infinite result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   439) set nan_bit,		0x0			# NAN result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   441) set q_sn_bit,		0x7			# sign bit of quotient byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   443) set bsun_bit,		7			# branch on unordered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   444) set snan_bit,		6			# signalling NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   445) set operr_bit,		5			# operand error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   446) set ovfl_bit,		4			# overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   447) set unfl_bit,		3			# underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   448) set dz_bit,		2			# divide by zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   449) set inex2_bit,		1			# inexact result 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   450) set inex1_bit,		0			# inexact result 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   452) set aiop_bit,		7			# accrued inexact operation bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   453) set aovfl_bit,		6			# accrued overflow bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   454) set aunfl_bit,		5			# accrued underflow bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   455) set adz_bit,		4			# accrued dz bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   456) set ainex_bit,		3			# accrued inexact bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   458) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   459) # FPSR individual bit masks #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   460) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   461) set neg_mask,		0x08000000		# negative bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   462) set inf_mask,		0x02000000		# infinity bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   463) set z_mask,		0x04000000		# zero bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   464) set nan_mask,		0x01000000		# nan bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   466) set neg_bmask,		0x08			# negative bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   467) set inf_bmask,		0x02			# infinity bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   468) set z_bmask,		0x04			# zero bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   469) set nan_bmask,		0x01			# nan bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   471) set bsun_mask,		0x00008000		# bsun exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   472) set snan_mask,		0x00004000		# snan exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   473) set operr_mask,		0x00002000		# operr exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   474) set ovfl_mask,		0x00001000		# overflow exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   475) set unfl_mask,		0x00000800		# underflow exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   476) set dz_mask,		0x00000400		# dz exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   477) set inex2_mask,		0x00000200		# inex2 exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   478) set inex1_mask,		0x00000100		# inex1 exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   480) set aiop_mask,		0x00000080		# accrued illegal operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   481) set aovfl_mask,		0x00000040		# accrued overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   482) set aunfl_mask,		0x00000020		# accrued underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   483) set adz_mask,		0x00000010		# accrued divide by zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   484) set ainex_mask,		0x00000008		# accrued inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   486) ######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   487) # FPSR combinations used in the FPSP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   488) ######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   489) set dzinf_mask,		inf_mask+dz_mask+adz_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   490) set opnan_mask,		nan_mask+operr_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   491) set nzi_mask,		0x01ffffff		#clears N, Z, and I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   492) set unfinx_mask,	unfl_mask+inex2_mask+aunfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   493) set unf2inx_mask,	unfl_mask+inex2_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   494) set ovfinx_mask,	ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   495) set inx1a_mask,		inex1_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   496) set inx2a_mask,		inex2_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   497) set snaniop_mask,	nan_mask+snan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   498) set snaniop2_mask,	snan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   499) set naniop_mask,	nan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   500) set neginf_mask,	neg_mask+inf_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   501) set infaiop_mask,	inf_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   502) set negz_mask,		neg_mask+z_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   503) set opaop_mask,		operr_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   504) set unfl_inx_mask,	unfl_mask+aunfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   505) set ovfl_inx_mask,	ovfl_mask+aovfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   507) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   508) # misc. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   509) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   510) set rnd_stky_bit,	29			# stky bit pos in longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   512) set sign_bit,		0x7			# sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   513) set signan_bit,		0x6			# signalling nan bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   515) set sgl_thresh,		0x3f81			# minimum sgl exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   516) set dbl_thresh,		0x3c01			# minimum dbl exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   518) set x_mode,		0x0			# extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   519) set s_mode,		0x4			# single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   520) set d_mode,		0x8			# double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   522) set rn_mode,		0x0			# round-to-nearest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   523) set rz_mode,		0x1			# round-to-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   524) set rm_mode,		0x2			# round-tp-minus-infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   525) set rp_mode,		0x3			# round-to-plus-infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   527) set mantissalen,	64			# length of mantissa in bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   529) set BYTE,		1			# len(byte) == 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   530) set WORD,		2			# len(word) == 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   531) set LONG,		4			# len(longword) == 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   533) set BSUN_VEC,		0xc0			# bsun    vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   534) set INEX_VEC,		0xc4			# inexact vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   535) set DZ_VEC,		0xc8			# dz      vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   536) set UNFL_VEC,		0xcc			# unfl    vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   537) set OPERR_VEC,		0xd0			# operr   vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   538) set OVFL_VEC,		0xd4			# ovfl    vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   539) set SNAN_VEC,		0xd8			# snan    vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   541) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   542) # SPecial CONDition FLaGs #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   543) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   544) set ftrapcc_flg,	0x01			# flag bit: ftrapcc exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   545) set fbsun_flg,		0x02			# flag bit: bsun exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   546) set mia7_flg,		0x04			# flag bit: (a7)+ <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   547) set mda7_flg,		0x08			# flag bit: -(a7) <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   548) set fmovm_flg,		0x40			# flag bit: fmovm instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   549) set immed_flg,		0x80			# flag bit: &<data> <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   551) set ftrapcc_bit,	0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   552) set fbsun_bit,		0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   553) set mia7_bit,		0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   554) set mda7_bit,		0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   555) set immed_bit,		0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   557) ##################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   558) # TRANSCENDENTAL "LAST-OP" FLAGS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   559) ##################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   560) set FMUL_OP,		0x0			# fmul instr performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   561) set FDIV_OP,		0x1			# fdiv performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   562) set FADD_OP,		0x2			# fadd performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   563) set FMOV_OP,		0x3			# fmov performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   565) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   566) # CONSTANTS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   567) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   568) T1:	long		0x40C62D38,0xD3D64634	# 16381 LOG2 LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   569) T2:	long		0x3D6F90AE,0xB1E75CC7	# 16381 LOG2 TRAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   571) PI:	long		0x40000000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   572) PIBY2:	long		0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   574) TWOBYPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   575) 	long		0x3FE45F30,0x6DC9C883
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   577) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   578) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   579) #	_fpsp_ovfl(): 060FPSP entry point for FP Overflow exception.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   580) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   581) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   582) #	FP Overflow exception in an operating system.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   583) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   584) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   585) #	_imem_read_long() - read instruction longword			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   586) #	fix_skewed_ops() - adjust src operand in fsave frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   587) #	set_tag_x() - determine optype of src/dst operands		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   588) #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   589) #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   590) #	load_fpn2() - load dst operand from FP regfile			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   591) #	fout() - emulate an opclass 3 instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   592) #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   593) #	_fpsp_done() - "callout" for 060FPSP exit (all work done!)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   594) #	_real_ovfl() - "callout" for Overflow exception enabled code	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   595) #	_real_inex() - "callout" for Inexact exception enabled code	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   596) #	_real_trace() - "callout" for Trace exception code		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   597) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   598) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   599) #	- The system stack contains the FP Ovfl exception stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   600) #	- The fsave frame contains the source operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   601) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   602) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   603) #	Overflow Exception enabled:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   604) #	- The system stack is unchanged					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   605) #	- The fsave frame contains the adjusted src op for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   606) #	Overflow Exception disabled:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   607) #	- The system stack is unchanged					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   608) #	- The "exception present" flag in the fsave frame is cleared	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   609) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   610) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   611) #	On the 060, if an FP overflow is present as the result of any	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   612) # instruction, the 060 will take an overflow exception whether the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   613) # exception is enabled or disabled in the FPCR. For the disabled case,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   614) # This handler emulates the instruction to determine what the correct	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   615) # default result should be for the operation. This default result is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   616) # then stored in either the FP regfile, data regfile, or memory.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   617) # Finally, the handler exits through the "callout" _fpsp_done()		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   618) # denoting that no exceptional conditions exist within the machine.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   619) #	If the exception is enabled, then this handler must create the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   620) # exceptional operand and plave it in the fsave state frame, and store	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   621) # the default result (only if the instruction is opclass 3). For	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   622) # exceptions enabled, this handler must exit through the "callout"	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   623) # _real_ovfl() so that the operating system enabled overflow handler	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   624) # can handle this case.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   625) #	Two other conditions exist. First, if overflow was disabled	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   626) # but the inexact exception was enabled, this handler must exit		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   627) # through the "callout" _real_inex() regardless of whether the result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   628) # was inexact.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   629) #	Also, in the case of an opclass three instruction where		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   630) # overflow was disabled and the trace exception was enabled, this	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   631) # handler must exit through the "callout" _real_trace().		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   632) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   633) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   635) 	global		_fpsp_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   636) _fpsp_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   638) #$#	sub.l		&24,%sp			# make room for src/dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   640) 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   642) 	fsave		FP_SRC(%a6)		# grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   644) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   645) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   646) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   648) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   649) 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   650) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   651) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   652) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   653) 	mov.l		%d0,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   655) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   657) 	btst		&0x5,EXC_CMDREG(%a6)	# is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   658) 	bne.w		fovfl_out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   661) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   662) 	bsr.l		fix_skewed_ops		# fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   664) # since, I believe, only NORMs and DENORMs can come through here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   665) # maybe we can avoid the subroutine call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   666) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   667) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   668) 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   670) # bit five of the fp extension word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   671) # that can pass through fpsp_ovfl(). remember that fcmp, ftst, and fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   672) # will never take this exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   673) 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   674) 	beq.b		fovfl_extract		# monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   676) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   677) 	bsr.l		load_fpn2		# load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   679) 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   680) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   681) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   682) 	bne.b		fovfl_op2_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   683) 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   684) fovfl_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   685) 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   687) fovfl_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   689) #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   690) #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   691) #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   692) #$#	mov.l		FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   693) #$#	mov.l		FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   694) #$#	mov.l		FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   696) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   697) 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   699) 	mov.b		1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   700) 	andi.w		&0x007f,%d1		# extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   702) 	andi.l		&0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   704) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   705) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   707) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   708) 	lea		FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   710) # maybe we can make these entry points ONLY the OVFL entry points of each routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   711) 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   712) 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   714) # the operation has been emulated. the result is in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   715) # the EXOP, if an exception occurred, is in fp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   716) # we must save the default result regardless of whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   717) # traps are enabled or disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   718) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   719) 	bsr.l		store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   721) # the exceptional possibilities we have left ourselves with are ONLY overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   722) # and inexact. and, the inexact is such that overflow occurred and was disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   723) # but inexact was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   724) 	btst		&ovfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   725) 	bne.b		fovfl_ovfl_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   727) 	btst		&inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   728) 	bne.b		fovfl_inex_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   730) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   731) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   732) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   734) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   735) #$#	add.l		&24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   736) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   738) # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   739) # in fp1. now, simply jump to _real_ovfl()!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   740) fovfl_ovfl_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   741) 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP (fp1) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   743) 	mov.w		&0xe005,2+FP_SRC(%a6)	# save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   745) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   746) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   747) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   749) 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   751) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   753) 	bra.l		_real_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   755) # overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   756) # we must jump to real_inex().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   757) fovfl_inex_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   759) 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP (fp1) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   761) 	mov.b		&0xc4,1+EXC_VOFF(%a6)	# vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   762) 	mov.w		&0xe001,2+FP_SRC(%a6)	# save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   764) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   765) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   766) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   768) 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   770) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   772) 	bra.l		_real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   774) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   775) fovfl_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   778) #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   779) #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   780) #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   782) # the src operand is definitely a NORM(!), so tag it as such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   783) 	mov.b		&NORM,STAG(%a6)		# set src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   785) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   786) 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   788) 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   790) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   791) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   793) 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   795) 	bsr.l		fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   797) 	btst		&ovfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   798) 	bne.w		fovfl_ovfl_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   800) 	btst		&inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   801) 	bne.w		fovfl_inex_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   803) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   804) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   805) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   807) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   808) #$#	add.l		&24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   810) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   811) 	beq.l		_fpsp_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   813) 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   814) 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   815) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   817) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   818) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   819) #	_fpsp_unfl(): 060FPSP entry point for FP Underflow exception.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   820) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   821) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   822) #	FP Underflow exception in an operating system.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   823) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   824) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   825) #	_imem_read_long() - read instruction longword			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   826) #	fix_skewed_ops() - adjust src operand in fsave frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   827) #	set_tag_x() - determine optype of src/dst operands		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   828) #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   829) #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   830) #	load_fpn2() - load dst operand from FP regfile			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   831) #	fout() - emulate an opclass 3 instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   832) #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   833) #	_fpsp_done() - "callout" for 060FPSP exit (all work done!)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   834) #	_real_ovfl() - "callout" for Overflow exception enabled code	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   835) #	_real_inex() - "callout" for Inexact exception enabled code	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   836) #	_real_trace() - "callout" for Trace exception code		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   837) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   838) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   839) #	- The system stack contains the FP Unfl exception stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   840) #	- The fsave frame contains the source operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   841) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   842) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   843) #	Underflow Exception enabled:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   844) #	- The system stack is unchanged					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   845) #	- The fsave frame contains the adjusted src op for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   846) #	Underflow Exception disabled:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   847) #	- The system stack is unchanged					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   848) #	- The "exception present" flag in the fsave frame is cleared	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   849) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   850) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   851) #	On the 060, if an FP underflow is present as the result of any	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   852) # instruction, the 060 will take an underflow exception whether the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   853) # exception is enabled or disabled in the FPCR. For the disabled case,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   854) # This handler emulates the instruction to determine what the correct	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   855) # default result should be for the operation. This default result is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   856) # then stored in either the FP regfile, data regfile, or memory.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   857) # Finally, the handler exits through the "callout" _fpsp_done()		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   858) # denoting that no exceptional conditions exist within the machine.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   859) #	If the exception is enabled, then this handler must create the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   860) # exceptional operand and plave it in the fsave state frame, and store	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   861) # the default result (only if the instruction is opclass 3). For	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   862) # exceptions enabled, this handler must exit through the "callout"	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   863) # _real_unfl() so that the operating system enabled overflow handler	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   864) # can handle this case.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   865) #	Two other conditions exist. First, if underflow was disabled	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   866) # but the inexact exception was enabled and the result was inexact,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   867) # this handler must exit through the "callout" _real_inex().		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   868) # was inexact.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   869) #	Also, in the case of an opclass three instruction where		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   870) # underflow was disabled and the trace exception was enabled, this	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   871) # handler must exit through the "callout" _real_trace().		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   872) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   873) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   875) 	global		_fpsp_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   876) _fpsp_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   878) #$#	sub.l		&24,%sp			# make room for src/dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   880) 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   882) 	fsave		FP_SRC(%a6)		# grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   884) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   885) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   886) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   888) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   889) 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   890) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   891) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   892) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   893) 	mov.l		%d0,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   895) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   897) 	btst		&0x5,EXC_CMDREG(%a6)	# is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   898) 	bne.w		funfl_out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   901) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   902) 	bsr.l		fix_skewed_ops		# fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   904) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   905) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   906) 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   908) # bit five of the fp ext word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   909) # that can pass through fpsp_unfl(). remember that fcmp, and ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   910) # will never take this exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   911) 	btst		&0x5,1+EXC_CMDREG(%a6)	# is op monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   912) 	beq.b		funfl_extract		# monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   914) # now, what's left that's not dyadic is fsincos. we can distinguish it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   915) # from all dyadics by the '0110xxx pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   916) 	btst		&0x4,1+EXC_CMDREG(%a6)	# is op an fsincos?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   917) 	bne.b		funfl_extract		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   919) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   920) 	bsr.l		load_fpn2		# load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   922) 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   923) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   924) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   925) 	bne.b		funfl_op2_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   926) 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   927) funfl_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   928) 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   930) funfl_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   932) #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   933) #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   934) #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   935) #$#	mov.l		FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   936) #$#	mov.l		FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   937) #$#	mov.l		FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   939) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   940) 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   942) 	mov.b		1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   943) 	andi.w		&0x007f,%d1		# extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   945) 	andi.l		&0x00ff01ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   947) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   948) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   950) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   951) 	lea		FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   953) # maybe we can make these entry points ONLY the OVFL entry points of each routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   954) 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   955) 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   957) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   958) 	bsr.l		store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   960) # The `060 FPU multiplier hardware is such that if the result of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   961) # multiply operation is the smallest possible normalized number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   962) # (0x00000000_80000000_00000000), then the machine will take an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   963) # underflow exception. Since this is incorrect, we need to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   964) # if our emulation, after re-doing the operation, decided that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   965) # no underflow was called for. We do these checks only in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   966) # funfl_{unfl,inex}_on() because w/ both exceptions disabled, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   967) # special case will simply exit gracefully with the correct result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   969) # the exceptional possibilities we have left ourselves with are ONLY overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   970) # and inexact. and, the inexact is such that overflow occurred and was disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   971) # but inexact was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   972) 	btst		&unfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   973) 	bne.b		funfl_unfl_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   975) funfl_chkinex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   976) 	btst		&inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   977) 	bne.b		funfl_inex_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   979) funfl_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   980) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   981) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   982) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   984) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   985) #$#	add.l		&24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   986) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   988) # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   989) # in fp1 (don't forget to save fp0). what to do now?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   990) # well, we simply have to get to go to _real_unfl()!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   991) funfl_unfl_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   993) # The `060 FPU multiplier hardware is such that if the result of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   994) # multiply operation is the smallest possible normalized number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   995) # (0x00000000_80000000_00000000), then the machine will take an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   996) # underflow exception. Since this is incorrect, we check here to see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   997) # if our emulation, after re-doing the operation, decided that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   998) # no underflow was called for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   999) 	btst		&unfl_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1000) 	beq.w		funfl_chkinex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1002) funfl_unfl_on2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1003) 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP (fp1) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1005) 	mov.w		&0xe003,2+FP_SRC(%a6)	# save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1007) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1008) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1009) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1011) 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1013) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1015) 	bra.l		_real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1017) # underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1018) # we must jump to real_inex().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1019) funfl_inex_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1021) # The `060 FPU multiplier hardware is such that if the result of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1022) # multiply operation is the smallest possible normalized number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1023) # (0x00000000_80000000_00000000), then the machine will take an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1024) # underflow exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1025) # But, whether bogus or not, if inexact is enabled AND it occurred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1026) # then we have to branch to real_inex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1028) 	btst		&inex2_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1029) 	beq.w		funfl_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1031) funfl_inex_on2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1033) 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1035) 	mov.b		&0xc4,1+EXC_VOFF(%a6)	# vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1036) 	mov.w		&0xe001,2+FP_SRC(%a6)	# save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1038) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1039) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1040) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1042) 	frestore	FP_SRC(%a6)		# do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1044) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1046) 	bra.l		_real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1048) #######################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1049) funfl_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1052) #$#	mov.l		FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1053) #$#	mov.l		FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1054) #$#	mov.l		FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1056) # the src operand is definitely a NORM(!), so tag it as such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1057) 	mov.b		&NORM,STAG(%a6)		# set src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1059) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1060) 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1062) 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1064) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1065) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1067) 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1069) 	bsr.l		fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1071) 	btst		&unfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1072) 	bne.w		funfl_unfl_on2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1074) 	btst		&inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1075) 	bne.w		funfl_inex_on2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1077) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1078) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1079) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1081) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1082) #$#	add.l		&24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1084) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1085) 	beq.l		_fpsp_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1087) 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1088) 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1089) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1091) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1092) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1093) #	_fpsp_unsupp(): 060FPSP entry point for FP "Unimplemented	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1094) #		        Data Type" exception.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1095) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1096) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1097) #	FP Unimplemented Data Type exception in an operating system.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1098) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1099) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1100) #	_imem_read_{word,long}() - read instruction word/longword	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1101) #	fix_skewed_ops() - adjust src operand in fsave frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1102) #	set_tag_x() - determine optype of src/dst operands		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1103) #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1104) #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1105) #	load_fpn2() - load dst operand from FP regfile			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1106) #	load_fpn1() - load src operand from FP regfile			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1107) #	fout() - emulate an opclass 3 instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1108) #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1109) #	_real_inex() - "callout" to operating system inexact handler	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1110) #	_fpsp_done() - "callout" for exit; work all done		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1111) #	_real_trace() - "callout" for Trace enabled exception		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1112) #	funimp_skew() - adjust fsave src ops to "incorrect" value	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1113) #	_real_snan() - "callout" for SNAN exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1114) #	_real_operr() - "callout" for OPERR exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1115) #	_real_ovfl() - "callout" for OVFL exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1116) #	_real_unfl() - "callout" for UNFL exception			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1117) #	get_packed() - fetch packed operand from memory			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1118) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1119) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1120) #	- The system stack contains the "Unimp Data Type" stk frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1121) #	- The fsave frame contains the ssrc op (for UNNORM/DENORM)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1122) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1123) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1124) #	If Inexact exception (opclass 3):				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1125) #	- The system stack is changed to an Inexact exception stk frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1126) #	If SNAN exception (opclass 3):					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1127) #	- The system stack is changed to an SNAN exception stk frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1128) #	If OPERR exception (opclass 3):					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1129) #	- The system stack is changed to an OPERR exception stk frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1130) #	If OVFL exception (opclass 3):					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1131) #	- The system stack is changed to an OVFL exception stk frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1132) #	If UNFL exception (opclass 3):					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1133) #	- The system stack is changed to an UNFL exception stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1134) #	If Trace exception enabled:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1135) #	- The system stack is changed to a Trace exception stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1136) #	Else: (normal case)						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1137) #	- Correct result has been stored as appropriate			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1138) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1139) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1140) #	Two main instruction types can enter here: (1) DENORM or UNNORM	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1141) # unimplemented data types. These can be either opclass 0,2 or 3	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1142) # instructions, and (2) PACKED unimplemented data format instructions	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1143) # also of opclasses 0,2, or 3.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1144) #	For UNNORM/DENORM opclass 0 and 2, the handler fetches the src	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1145) # operand from the fsave state frame and the dst operand (if dyadic)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1146) # from the FP register file. The instruction is then emulated by	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1147) # choosing an emulation routine from a table of routines indexed by	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1148) # instruction type. Once the instruction has been emulated and result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1149) # saved, then we check to see if any enabled exceptions resulted from	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1150) # instruction emulation. If none, then we exit through the "callout"	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1151) # _fpsp_done(). If there is an enabled FP exception, then we insert	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1152) # this exception into the FPU in the fsave state frame and then exit	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1153) # through _fpsp_done().							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1154) #	PACKED opclass 0 and 2 is similar in how the instruction is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1155) # emulated and exceptions handled. The differences occur in how the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1156) # handler loads the packed op (by calling get_packed() routine) and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1157) # by the fact that a Trace exception could be pending for PACKED ops.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1158) # If a Trace exception is pending, then the current exception stack	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1159) # frame is changed to a Trace exception stack frame and an exit is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1160) # made through _real_trace().						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1161) #	For UNNORM/DENORM opclass 3, the actual move out to memory is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1162) # performed by calling the routine fout(). If no exception should occur	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1163) # as the result of emulation, then an exit either occurs through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1164) # _fpsp_done() or through _real_trace() if a Trace exception is pending	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1165) # (a Trace stack frame must be created here, too). If an FP exception	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1166) # should occur, then we must create an exception stack frame of that	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1167) # type and jump to either _real_snan(), _real_operr(), _real_inex(),	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1168) # _real_unfl(), or _real_ovfl() as appropriate. PACKED opclass 3	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1169) # emulation is performed in a similar manner.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1170) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1171) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1173) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1174) # (1) DENORM and UNNORM (unimplemented) data types:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1175) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1176) #				post-instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1177) #				*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1178) #				*      EA	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1179) #	 pre-instruction	*		*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1180) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1181) #	* 0x0 *  0x0dc  *	* 0x3 *  0x0dc  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1182) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1183) #	*     Next	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1184) #	*      PC	*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1185) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1186) #	*      SR	*	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1187) #	*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1188) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1189) # (2) PACKED format (unsupported) opclasses two and three:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1190) #	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1191) #	*      EA	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1192) #	*		*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1193) #	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1194) #	* 0x2 *  0x0dc	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1195) #	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1196) #	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1197) #	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1198) #	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1199) #	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1200) #	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1201) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1202) 	global		_fpsp_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1203) _fpsp_unsupp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1205) 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1207) 	fsave		FP_SRC(%a6)		# save fp state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1209) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1210) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1211) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1213) 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1214) 	bne.b		fu_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1215) fu_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1216) 	mov.l		%usp,%a0		# fetch user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1217) 	mov.l		%a0,EXC_A7(%a6)		# save on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1218) 	bra.b		fu_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1219) # if the exception is an opclass zero or two unimplemented data type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1220) # exception, then the a7' calculated here is wrong since it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1221) # stack an ea. however, we don't need an a7' for this case anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1222) fu_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1223) 	lea		0x4+EXC_EA(%a6),%a0	# load old a7'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1224) 	mov.l		%a0,EXC_A7(%a6)		# save on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1226) fu_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1228) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1229) # the FPIAR should be set correctly for ALL exceptions passing through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1230) # this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1231) 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1232) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1233) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1234) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1235) 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1237) ############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1239) 	clr.b		SPCOND_FLG(%a6)		# clear special condition flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1241) # Separate opclass three (fpn-to-mem) ops since they have a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1242) # stack frame and protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1243) 	btst		&0x5,EXC_CMDREG(%a6)	# is it an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1244) 	bne.w		fu_out			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1246) # Separate packed opclass two instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1247) 	bfextu		EXC_CMDREG(%a6){&0:&6},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1248) 	cmpi.b		%d0,&0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1249) 	beq.w		fu_in_pack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1252) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1253) # so, since the emulation routines re-create them anyways, zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1254) 	andi.l		&0x00ff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1256) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1257) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1259) # Opclass two w/ memory-to-fpn operation will have an incorrect extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1260) # precision format if the src format was single or double and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1261) # source data type was an INF, NAN, DENORM, or UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1262) 	lea		FP_SRC(%a6),%a0		# pass ptr to input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1263) 	bsr.l		fix_skewed_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1265) # we don't know whether the src operand or the dst operand (or both) is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1266) # UNNORM or DENORM. call the function that tags the operand type. if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1267) # input is an UNNORM, then convert it to a NORM, DENORM, or ZERO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1268) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1269) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1270) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1271) 	bne.b		fu_op2			# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1272) 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1274) fu_op2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1275) 	mov.b		%d0,STAG(%a6)		# save src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1277) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1279) # bit five of the fp extension word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1280) # at this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1281) 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1282) 	beq.b		fu_extract		# monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1283) 	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1284) 	beq.b		fu_extract		# yes, so it's monadic, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1286) 	bsr.l		load_fpn2		# load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1288) 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1289) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1290) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1291) 	bne.b		fu_op2_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1292) 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1293) fu_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1294) 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1296) fu_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1297) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1298) 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1300) 	bfextu		1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1302) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1303) 	lea		FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1305) 	mov.l		(tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1306) 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1308) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1309) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1310) #	BSUN	: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1311) #	SNAN	: all dyadic ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1312) #	OPERR	: fsqrt(-NORM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1313) #	OVFL	: all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1314) #	UNFL	: all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1315) #	DZ	: fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1316) #	INEX2	: all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1317) #	INEX1	: none (packed doesn't go through here)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1318) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1320) # we determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1321) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1322) 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1323) 	bne.b		fu_in_ena		# some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1325) fu_in_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1326) # fcmp and ftst do not store any result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1327) 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1328) 	andi.b		&0x38,%d0		# extract bits 3-5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1329) 	cmpi.b		%d0,&0x38		# is instr fcmp or ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1330) 	beq.b		fu_in_exit		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1332) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1333) 	bsr.l		store_fpreg		# store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1335) fu_in_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1337) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1338) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1339) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1341) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1343) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1345) fu_in_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1346) 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1347) 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1348) 	bne.b		fu_in_exc		# there is at least one set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1350) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1351) # No exceptions occurred that were also enabled. Now:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1352) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1353) #	if (OVFL && ovfl_disabled && inexact_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1354) #	    branch to _real_inex() (even if the result was exact!);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1355) #	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1356) #	    save the result in the proper fp reg (unless the op is fcmp or ftst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1357) #	    return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1358) #	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1359) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1360) 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1361) 	beq.b		fu_in_cont		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1363) fu_in_ovflchk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1364) 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1365) 	beq.b		fu_in_cont		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1366) 	bra.w		fu_in_exc_ovfl		# go insert overflow frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1368) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1369) # An exception occurred and that exception was enabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1370) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1371) #	shift enabled exception field into lo byte of d0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1372) #	if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1373) #	    ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1374) #		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1375) #		 * this is the case where we must call _real_inex() now or else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1376) #		 * there will be no other way to pass it the exceptional operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1377) #		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1378) #		call _real_inex();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1379) #	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1380) #		restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1381) #	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1382) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1383) fu_in_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1384) 	subi.l		&24,%d0			# fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1385) 	cmpi.b		%d0,&0x6		# is exception INEX? (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1386) 	bne.b		fu_in_exc_exit		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1388) # the enabled exception was inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1389) 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1390) 	bne.w		fu_in_exc_unfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1391) 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1392) 	bne.w		fu_in_exc_ovfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1394) # here, we insert the correct fsave status value into the fsave frame for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1395) # corresponding exception. the operand in the fsave frame should be the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1396) # src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1397) fu_in_exc_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1398) 	mov.l		%d0,-(%sp)		# save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1399) 	bsr.l		funimp_skew		# skew sgl or dbl inputs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1400) 	mov.l		(%sp)+,%d0		# restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1402) 	mov.w		(tbl_except.b,%pc,%d0.w*2),2+FP_SRC(%a6) # create exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1404) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1405) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1406) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1408) 	frestore	FP_SRC(%a6)		# restore src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1410) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1412) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1414) tbl_except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1415) 	short		0xe000,0xe006,0xe004,0xe005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1416) 	short		0xe003,0xe002,0xe001,0xe001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1418) fu_in_exc_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1419) 	mov.w		&0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1420) 	bra.b		fu_in_exc_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1421) fu_in_exc_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1422) 	mov.w		&0x03,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1423) 	bra.b		fu_in_exc_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1425) # If the input operand to this operation was opclass two and a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1426) # or double precision denorm, inf, or nan, the operand needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1427) # "corrected" in order to have the proper equivalent extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1428) # number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1429) 	global		fix_skewed_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1430) fix_skewed_ops:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1431) 	bfextu		EXC_CMDREG(%a6){&0:&6},%d0 # extract opclass,src fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1432) 	cmpi.b		%d0,&0x11		# is class = 2 & fmt = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1433) 	beq.b		fso_sgl			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1434) 	cmpi.b		%d0,&0x15		# is class = 2 & fmt = dbl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1435) 	beq.b		fso_dbl			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1436) 	rts					# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1438) fso_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1439) 	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1440) 	andi.w		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1441) 	cmpi.w		%d0,&0x3f80		# is |exp| == $3f80?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1442) 	beq.b		fso_sgl_dnrm_zero	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1443) 	cmpi.w		%d0,&0x407f		# no; is |exp| == $407f?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1444) 	beq.b		fso_infnan		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1445) 	rts					# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1447) fso_sgl_dnrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1448) 	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1449) 	beq.b		fso_zero		# it's a skewed zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1450) fso_sgl_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1451) # here, we count on norm not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1452) 	bsr.l		norm			# normalize mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1453) 	neg.w		%d0			# -shft amt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1454) 	addi.w		&0x3f81,%d0		# adjust new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1455) 	andi.w		&0x8000,LOCAL_EX(%a0)	# clear old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1456) 	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1457) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1459) fso_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1460) 	andi.w		&0x8000,LOCAL_EX(%a0)	# clear bogus exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1461) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1463) fso_infnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1464) 	andi.b		&0x7f,LOCAL_HI(%a0)	# clear j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1465) 	ori.w		&0x7fff,LOCAL_EX(%a0)	# make exponent = $7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1466) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1468) fso_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1469) 	mov.w		LOCAL_EX(%a0),%d0	# fetch src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1470) 	andi.w		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1471) 	cmpi.w		%d0,&0x3c00		# is |exp| == $3c00?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1472) 	beq.b		fso_dbl_dnrm_zero	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1473) 	cmpi.w		%d0,&0x43ff		# no; is |exp| == $43ff?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1474) 	beq.b		fso_infnan		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1475) 	rts					# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1477) fso_dbl_dnrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1478) 	andi.l		&0x7fffffff,LOCAL_HI(%a0) # clear j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1479) 	bne.b		fso_dbl_dnrm		# it's a skewed denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1480) 	tst.l		LOCAL_LO(%a0)		# is it a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1481) 	beq.b		fso_zero		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1482) fso_dbl_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1483) # here, we count on norm not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1484) 	bsr.l		norm			# normalize mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1485) 	neg.w		%d0			# -shft amt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1486) 	addi.w		&0x3c01,%d0		# adjust new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1487) 	andi.w		&0x8000,LOCAL_EX(%a0)	# clear old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1488) 	or.w		%d0,LOCAL_EX(%a0)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1489) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1491) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1493) # fmove out took an unimplemented data type exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1494) # the src operand is in FP_SRC. Call _fout() to write out the result and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1495) # to determine which exceptions, if any, to take.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1496) fu_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1498) # Separate packed move outs from the UNNORM and DENORM move outs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1499) 	bfextu		EXC_CMDREG(%a6){&3:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1500) 	cmpi.b		%d0,&0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1501) 	beq.w		fu_out_pack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1502) 	cmpi.b		%d0,&0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1503) 	beq.w		fu_out_pack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1506) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1507) # so, since the emulation routines re-create them anyways, zero exception field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1508) # fmove out doesn't affect ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1509) 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1511) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1512) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1514) # the src can ONLY be a DENORM or an UNNORM! so, don't make any big subroutine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1515) # call here. just figure out what it is...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1516) 	mov.w		FP_SRC_EX(%a6),%d0	# get exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1517) 	andi.w		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1518) 	beq.b		fu_out_denorm		# it's a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1520) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1521) 	bsr.l		unnorm_fix		# yes; fix it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1523) 	mov.b		%d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1525) 	bra.b		fu_out_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1526) fu_out_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1527) 	mov.b		&DENORM,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1528) fu_out_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1530) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1531) 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1533) 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1535) 	mov.l		(%a6),EXC_A6(%a6)	# in case a6 changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1536) 	bsr.l		fout			# call fmove out routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1538) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1539) #	BSUN	: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1540) #	SNAN	: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1541) #	OPERR	: fmove.{b,w,l} out of large UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1542) #	OVFL	: fmove.{s,d}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1543) #	UNFL	: fmove.{s,d,x}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1544) #	DZ	: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1545) #	INEX2	: all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1546) #	INEX1	: none (packed doesn't travel through here)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1548) # determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1549) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1550) 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1551) 	bne.w		fu_out_ena		# some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1553) fu_out_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1555) 	mov.l		EXC_A6(%a6),(%a6)	# in case a6 changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1557) # on extended precision opclass three instructions using pre-decrement or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1558) # post-increment addressing mode, the address register is not updated. is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1559) # address register was the stack pointer used from user mode, then let's update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1560) # it here. if it was used from supervisor mode, then we have to handle this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1561) # as a special case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1562) 	btst		&0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1563) 	bne.b		fu_out_done_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1565) 	mov.l		EXC_A7(%a6),%a0		# restore a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1566) 	mov.l		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1568) fu_out_done_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1569) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1570) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1571) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1573) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1575) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1576) 	bne.b		fu_out_trace		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1578) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1580) # is the ea mode pre-decrement of the stack pointer from supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1581) # ("fmov.x fpm,-(a7)") if so,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1582) fu_out_done_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1583) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1584) 	bne.b		fu_out_done_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1586) # the extended precision result is still in fp0. but, we need to save it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1587) # somewhere on the stack until we can copy it to its final resting place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1588) # here, we're counting on the top of the stack to be the old place-holders
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1589) # for fp0/fp1 which have already been restored. that way, we can write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1590) # over those destinations with the shifted stack frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1591) 	fmovm.x		&0x80,FP_SRC(%a6)	# put answer on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1593) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1594) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1595) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1597) 	mov.l		(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1599) 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1600) 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1602) # now, copy the result to the proper place on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1603) 	mov.l		LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1604) 	mov.l		LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1605) 	mov.l		LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1607) 	add.l		&LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1609) 	btst		&0x7,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1610) 	bne.b		fu_out_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1612) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1614) fu_out_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1615) 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1616) 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1617) 	bne.b		fu_out_exc		# there is at least one set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1619) # no exceptions were set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1620) # if a disabled overflow occurred and inexact was enabled but the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1621) # was exact, then a branch to _real_inex() is made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1622) 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1623) 	beq.w		fu_out_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1625) fu_out_ovflchk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1626) 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1627) 	beq.w		fu_out_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1628) 	bra.w		fu_inex			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1630) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1631) # The fp move out that took the "Unimplemented Data Type" exception was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1632) # being traced. Since the stack frames are similar, get the "current" PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1633) # from FPIAR and put it in the trace stack frame then jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1634) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1635) #		  UNSUPP FRAME		   TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1636) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1637) #		*      EA	*	*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1638) #		*		*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1639) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1640) #		* 0x3 *  0x0dc	*	* 0x2 *  0x024	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1641) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1642) #		*     Next	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1643) #		*      PC	*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1644) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1645) #		*      SR	*	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1646) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1647) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1648) fu_out_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1649) 	mov.w		&0x2024,0x6(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1650) 	fmov.l		%fpiar,0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1651) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1653) # an exception occurred and that exception was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1654) fu_out_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1655) 	subi.l		&24,%d0			# fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1657) # we don't mess with the existing fsave frame. just re-insert it and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1658) # jump to the "_real_{}()" handler...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1659) 	mov.w		(tbl_fu_out.b,%pc,%d0.w*2),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1660) 	jmp		(tbl_fu_out.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1662) 	swbeg		&0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1663) tbl_fu_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1664) 	short		tbl_fu_out	- tbl_fu_out	# BSUN can't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1665) 	short		tbl_fu_out	- tbl_fu_out	# SNAN can't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1666) 	short		fu_operr	- tbl_fu_out	# OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1667) 	short		fu_ovfl		- tbl_fu_out	# OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1668) 	short		fu_unfl		- tbl_fu_out	# UNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1669) 	short		tbl_fu_out	- tbl_fu_out	# DZ can't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1670) 	short		fu_inex		- tbl_fu_out	# INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1671) 	short		tbl_fu_out	- tbl_fu_out	# INEX1 won't make it here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1673) # for snan,operr,ovfl,unfl, src op is still in FP_SRC so just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1674) # frestore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1675) fu_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1676) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1677) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1678) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1680) 	mov.w		&0x30d8,EXC_VOFF(%a6)	# vector offset = 0xd8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1681) 	mov.w		&0xe006,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1683) 	frestore	FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1685) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1688) 	bra.l		_real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1690) fu_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1691) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1692) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1693) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1695) 	mov.w		&0x30d0,EXC_VOFF(%a6)	# vector offset = 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1696) 	mov.w		&0xe004,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1698) 	frestore	FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1700) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1703) 	bra.l		_real_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1705) fu_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1706) 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1708) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1709) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1710) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1712) 	mov.w		&0x30d4,EXC_VOFF(%a6)	# vector offset = 0xd4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1713) 	mov.w		&0xe005,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1715) 	frestore	FP_SRC(%a6)		# restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1717) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1719) 	bra.l		_real_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1721) # underflow can happen for extended precision. extended precision opclass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1722) # three instruction exceptions don't update the stack pointer. so, if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1723) # exception occurred from user mode, then simply update a7 and exit normally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1724) # if the exception occurred from supervisor mode, check if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1725) fu_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1726) 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1728) 	btst		&0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1729) 	bne.w		fu_unfl_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1731) 	mov.l		EXC_A7(%a6),%a0		# restore a7 whether we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1732) 	mov.l		%a0,%usp		# to or not...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1734) fu_unfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1735) 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1737) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1738) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1739) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1741) 	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1742) 	mov.w		&0xe003,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1744) 	frestore	FP_SRC(%a6)		# restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1746) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1748) 	bra.l		_real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1750) fu_unfl_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1751) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # was the <ea> mode -(sp)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1752) 	bne.b		fu_unfl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1754) # the extended precision result is still in fp0. but, we need to save it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1755) # somewhere on the stack until we can copy it to its final resting place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1756) # (where the exc frame is currently). make sure it's not at the top of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1757) # frame or it will get overwritten when the exc stack frame is shifted "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1758) 	fmovm.x		&0x80,FP_SRC(%a6)	# put answer on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1759) 	fmovm.x		&0x40,FP_DST(%a6)	# put EXOP on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1761) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1762) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1763) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1765) 	mov.w		&0x30cc,EXC_VOFF(%a6)	# vector offset = 0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1766) 	mov.w		&0xe003,2+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1768) 	frestore	FP_DST(%a6)		# restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1770) 	mov.l		(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1772) 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1773) 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1774) 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1776) # now, copy the result to the proper place on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1777) 	mov.l		LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1778) 	mov.l		LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1779) 	mov.l		LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1781) 	add.l		&LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1783) 	bra.l		_real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1785) # fmove in and out enter here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1786) fu_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1787) 	fmovm.x		&0x40,FP_SRC(%a6)	# save EXOP to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1789) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1790) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1791) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1793) 	mov.w		&0x30c4,EXC_VOFF(%a6)	# vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1794) 	mov.w		&0xe001,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1796) 	frestore	FP_SRC(%a6)		# restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1798) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1801) 	bra.l		_real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1803) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1804) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1805) fu_in_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1808) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1809) # so, since the emulation routines re-create them anyways, zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1810) 	andi.l		&0x0ff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1812) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1813) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1815) 	bsr.l		get_packed		# fetch packed src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1817) 	lea		FP_SRC(%a6),%a0		# pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1818) 	bsr.l		set_tag_x		# set src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1820) 	mov.b		%d0,STAG(%a6)		# save src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1822) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1824) # bit five of the fp extension word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1825) # at this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1826) 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1827) 	beq.b		fu_extract_p		# monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1828) 	cmpi.b		1+EXC_CMDREG(%a6),&0x3a	# is operation an ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1829) 	beq.b		fu_extract_p		# yes, so it's monadic, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1831) 	bsr.l		load_fpn2		# load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1833) 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1834) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1835) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1836) 	bne.b		fu_op2_done_p		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1837) 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1838) fu_op2_done_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1839) 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1841) fu_extract_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1842) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1843) 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1845) 	bfextu		1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1847) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1848) 	lea		FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1850) 	mov.l		(tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1851) 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1853) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1854) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1855) #	BSUN	: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1856) #	SNAN	: all dyadic ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1857) #	OPERR	: fsqrt(-NORM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1858) #	OVFL	: all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1859) #	UNFL	: all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1860) #	DZ	: fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1861) #	INEX2	: all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1862) #	INEX1	: all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1863) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1865) # we determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1866) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1867) 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1868) 	bne.w		fu_in_ena_p		# some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1870) fu_in_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1871) # fcmp and ftst do not store any result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1872) 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1873) 	andi.b		&0x38,%d0		# extract bits 3-5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1874) 	cmpi.b		%d0,&0x38		# is instr fcmp or ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1875) 	beq.b		fu_in_exit_p		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1877) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1878) 	bsr.l		store_fpreg		# store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1880) fu_in_exit_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1882) 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1883) 	bne.w		fu_in_exit_s_p		# supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1885) 	mov.l		EXC_A7(%a6),%a0		# update user a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1886) 	mov.l		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1888) fu_in_exit_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1889) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1890) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1891) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1893) 	unlk		%a6			# unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1895) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1896) 	bne.w		fu_trace_p		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1898) 	bra.l		_fpsp_done		# exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1900) # the exception occurred in supervisor mode. check to see if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1901) # addressing mode was (a7)+. if so, we'll need to shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1902) # stack frame "up".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1903) fu_in_exit_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1904) 	btst		&mia7_bit,SPCOND_FLG(%a6) # was ea mode (a7)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1905) 	beq.b		fu_in_exit_cont_p	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1907) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1908) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1909) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1911) 	unlk		%a6			# unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1913) # shift the stack frame "up". we don't really care about the <ea> field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1914) 	mov.l		0x4(%sp),0x10(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1915) 	mov.l		0x0(%sp),0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1916) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1918) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1919) 	bne.w		fu_trace_p		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1921) 	bra.l		_fpsp_done		# exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1923) fu_in_ena_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1924) 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled & set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1925) 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1926) 	bne.b		fu_in_exc_p		# at least one was set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1928) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1929) # No exceptions occurred that were also enabled. Now:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1930) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1931) #	if (OVFL && ovfl_disabled && inexact_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1932) #	    branch to _real_inex() (even if the result was exact!);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1933) #	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1934) #	    save the result in the proper fp reg (unless the op is fcmp or ftst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1935) #	    return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1936) #	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1937) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1938) 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1939) 	beq.w		fu_in_cont_p		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1941) fu_in_ovflchk_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1942) 	btst		&inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1943) 	beq.w		fu_in_cont_p		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1944) 	bra.w		fu_in_exc_ovfl_p	# do _real_inex() now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1946) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1947) # An exception occurred and that exception was enabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1948) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1949) #	shift enabled exception field into lo byte of d0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1950) #	if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1951) #	    ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1952) #		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1953) #		 * this is the case where we must call _real_inex() now or else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1954) #		 * there will be no other way to pass it the exceptional operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1955) #		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1956) #		call _real_inex();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1957) #	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1958) #		restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1959) #	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1960) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1961) fu_in_exc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1962) 	subi.l		&24,%d0			# fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1963) 	cmpi.b		%d0,&0x6		# is exception INEX? (6 or 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1964) 	blt.b		fu_in_exc_exit_p	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1966) # the enabled exception was inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1967) 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1968) 	bne.w		fu_in_exc_unfl_p	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1969) 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1970) 	bne.w		fu_in_exc_ovfl_p	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1972) # here, we insert the correct fsave status value into the fsave frame for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1973) # corresponding exception. the operand in the fsave frame should be the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1974) # src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1975) # as a reminder for future predicted pain and agony, we are passing in fsave the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1976) # "non-skewed" operand for cases of sgl and dbl src INFs,NANs, and DENORMs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1977) # this is INCORRECT for enabled SNAN which would give to the user the skewed SNAN!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1978) fu_in_exc_exit_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1979) 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1980) 	bne.w		fu_in_exc_exit_s_p	# supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1982) 	mov.l		EXC_A7(%a6),%a0		# update user a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1983) 	mov.l		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1985) fu_in_exc_exit_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1986) 	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1988) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1989) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1990) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1992) 	frestore	FP_SRC(%a6)		# restore src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1994) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1996) 	btst		&0x7,(%sp)		# is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1997) 	bne.w		fu_trace_p		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1999) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2001) tbl_except_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2002) 	short		0xe000,0xe006,0xe004,0xe005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2003) 	short		0xe003,0xe002,0xe001,0xe001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2005) fu_in_exc_ovfl_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2006) 	mov.w		&0x3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2007) 	bra.w		fu_in_exc_exit_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2009) fu_in_exc_unfl_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2010) 	mov.w		&0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2011) 	bra.w		fu_in_exc_exit_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2013) fu_in_exc_exit_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2014) 	btst		&mia7_bit,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2015) 	beq.b		fu_in_exc_exit_cont_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2017) 	mov.w		(tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2019) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2020) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2021) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2023) 	frestore	FP_SRC(%a6)		# restore src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2025) 	unlk		%a6			# unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2027) # shift stack frame "up". who cares about <ea> field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2028) 	mov.l		0x4(%sp),0x10(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2029) 	mov.l		0x0(%sp),0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2030) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2032) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2033) 	bne.b		fu_trace_p		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2035) 	bra.l		_fpsp_done		# exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2037) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2038) # The opclass two PACKED instruction that took an "Unimplemented Data Type"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2039) # exception was being traced. Make the "current" PC the FPIAR and put it in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2040) # trace stack frame then jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2041) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2042) #		  UNSUPP FRAME		   TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2043) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2044) #		*      EA	*	*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2045) #		*		*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2046) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2047) #		* 0x2 *	0x0dc	*	* 0x2 *  0x024	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2048) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2049) #		*     Next	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2050) #		*      PC	*	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2051) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2052) #		*      SR	*	*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2053) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2054) fu_trace_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2055) 	mov.w		&0x2024,0x6(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2056) 	fmov.l		%fpiar,0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2058) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2060) #########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2061) #########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2062) fu_out_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2065) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2066) # so, since the emulation routines re-create them anyways, zero exception field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2067) # fmove out doesn't affect ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2068) 	and.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2070) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2071) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2073) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2074) 	bsr.l		load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2076) # unlike other opclass 3, unimplemented data type exceptions, packed must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2077) # able to detect all operand types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2078) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2079) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2080) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2081) 	bne.b		fu_op2_p		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2082) 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2084) fu_op2_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2085) 	mov.b		%d0,STAG(%a6)		# save src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2087) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2088) 	mov.b		FPCR_MODE(%a6),%d0	# fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2090) 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2092) 	mov.l		(%a6),EXC_A6(%a6)	# in case a6 changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2093) 	bsr.l		fout			# call fmove out routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2095) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2096) #	BSUN	: no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2097) #	SNAN	: yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2098) #	OPERR	: if ((k_factor > +17) || (dec. exp exceeds 3 digits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2099) #	OVFL	: no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2100) #	UNFL	: no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2101) #	DZ	: no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2102) #	INEX2	: yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2103) #	INEX1	: no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2105) # determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2106) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2107) 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2108) 	bne.w		fu_out_ena_p		# some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2110) fu_out_exit_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2111) 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2113) 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2114) 	bne.b		fu_out_exit_s_p		# supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2116) 	mov.l		EXC_A7(%a6),%a0		# update user a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2117) 	mov.l		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2119) fu_out_exit_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2120) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2121) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2122) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2124) 	unlk		%a6			# unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2126) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2127) 	bne.w		fu_trace_p		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2129) 	bra.l		_fpsp_done		# exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2131) # the exception occurred in supervisor mode. check to see if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2132) # addressing mode was -(a7). if so, we'll need to shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2133) # stack frame "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2134) fu_out_exit_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2135) 	btst		&mda7_bit,SPCOND_FLG(%a6) # was ea mode -(a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2136) 	beq.b		fu_out_exit_cont_p	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2138) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2139) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2140) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2142) 	mov.l		(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2144) 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2145) 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2147) # now, copy the result to the proper place on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2148) 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2149) 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2150) 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2152) 	add.l		&LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2154) 	btst		&0x7,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2155) 	bne.w		fu_trace_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2157) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2159) fu_out_ena_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2160) 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2161) 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2162) 	beq.w		fu_out_exit_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2164) 	mov.l		EXC_A6(%a6),(%a6)	# restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2166) # an exception occurred and that exception was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2167) # the only exception possible on packed move out are INEX, OPERR, and SNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2168) fu_out_exc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2169) 	cmpi.b		%d0,&0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2170) 	bgt.w		fu_inex_p2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2171) 	beq.w		fu_operr_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2173) fu_snan_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2174) 	btst		&0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2175) 	bne.b		fu_snan_s_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2177) 	mov.l		EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2178) 	mov.l		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2179) 	bra.w		fu_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2181) fu_snan_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2182) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2183) 	bne.w		fu_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2185) # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2186) # the strategy is to move the exception frame "down" 12 bytes. then, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2187) # can store the default result where the exception frame was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2188) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2189) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2190) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2192) 	mov.w		&0x30d8,EXC_VOFF(%a6)	# vector offset = 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2193) 	mov.w		&0xe006,2+FP_SRC(%a6)	# set fsave status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2195) 	frestore	FP_SRC(%a6)		# restore src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2197) 	mov.l		(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2199) 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2200) 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2201) 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2203) # now, we copy the default result to its proper location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2204) 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2205) 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2206) 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2208) 	add.l		&LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2211) 	bra.l		_real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2213) fu_operr_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2214) 	btst		&0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2215) 	bne.w		fu_operr_p_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2217) 	mov.l		EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2218) 	mov.l		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2219) 	bra.w		fu_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2221) fu_operr_p_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2222) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2223) 	bne.w		fu_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2225) # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2226) # the strategy is to move the exception frame "down" 12 bytes. then, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2227) # can store the default result where the exception frame was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2228) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2229) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2230) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2232) 	mov.w		&0x30d0,EXC_VOFF(%a6)	# vector offset = 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2233) 	mov.w		&0xe004,2+FP_SRC(%a6)	# set fsave status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2235) 	frestore	FP_SRC(%a6)		# restore src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2237) 	mov.l		(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2239) 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2240) 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2241) 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2243) # now, we copy the default result to its proper location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2244) 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2245) 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2246) 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2248) 	add.l		&LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2251) 	bra.l		_real_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2253) fu_inex_p2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2254) 	btst		&0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2255) 	bne.w		fu_inex_s_p2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2257) 	mov.l		EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2258) 	mov.l		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2259) 	bra.w		fu_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2261) fu_inex_s_p2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2262) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2263) 	bne.w		fu_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2265) # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2266) # the strategy is to move the exception frame "down" 12 bytes. then, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2267) # can store the default result where the exception frame was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2268) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2269) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2270) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2272) 	mov.w		&0x30c4,EXC_VOFF(%a6)	# vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2273) 	mov.w		&0xe001,2+FP_SRC(%a6)	# set fsave status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2275) 	frestore	FP_SRC(%a6)		# restore src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2277) 	mov.l		(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2279) 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2280) 	mov.l		LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2281) 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2283) # now, we copy the default result to its proper location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2284) 	mov.l		LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2285) 	mov.l		LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2286) 	mov.l		LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2288) 	add.l		&LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2291) 	bra.l		_real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2293) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2295) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2296) # if we're stuffing a source operand back into an fsave frame then we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2297) # have to make sure that for single or double source operands that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2298) # format stuffed is as weird as the hardware usually makes it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2299) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2300) 	global		funimp_skew
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2301) funimp_skew:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2302) 	bfextu		EXC_EXTWORD(%a6){&3:&3},%d0 # extract src specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2303) 	cmpi.b		%d0,&0x1		# was src sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2304) 	beq.b		funimp_skew_sgl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2305) 	cmpi.b		%d0,&0x5		# was src dbl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2306) 	beq.b		funimp_skew_dbl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2307) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2309) funimp_skew_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2310) 	mov.w		FP_SRC_EX(%a6),%d0	# fetch DENORM exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2311) 	andi.w		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2312) 	beq.b		funimp_skew_sgl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2313) 	cmpi.w		%d0,&0x3f80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2314) 	bgt.b		funimp_skew_sgl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2315) 	neg.w		%d0			# make exponent negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2316) 	addi.w		&0x3f81,%d0		# find amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2317) 	mov.l		FP_SRC_HI(%a6),%d1	# fetch DENORM hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2318) 	lsr.l		%d0,%d1			# shift it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2319) 	bset		&31,%d1			# set j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2320) 	mov.l		%d1,FP_SRC_HI(%a6)	# insert new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2321) 	andi.w		&0x8000,FP_SRC_EX(%a6)	# clear old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2322) 	ori.w		&0x3f80,FP_SRC_EX(%a6)	# insert new "skewed" exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2323) funimp_skew_sgl_not:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2324) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2326) funimp_skew_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2327) 	mov.w		FP_SRC_EX(%a6),%d0	# fetch DENORM exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2328) 	andi.w		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2329) 	beq.b		funimp_skew_dbl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2330) 	cmpi.w		%d0,&0x3c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2331) 	bgt.b		funimp_skew_dbl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2333) 	tst.b		FP_SRC_EX(%a6)		# make "internal format"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2334) 	smi.b		0x2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2335) 	mov.w		%d0,FP_SRC_EX(%a6)	# insert exponent with cleared sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2336) 	clr.l		%d0			# clear g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2337) 	lea		FP_SRC(%a6),%a0		# pass ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2338) 	mov.w		&0x3c01,%d1		# pass denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2339) 	bsr.l		dnrm_lp			# denorm it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2340) 	mov.w		&0x3c00,%d0		# new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2341) 	tst.b		0x2+FP_SRC(%a6)		# is sign set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2342) 	beq.b		fss_dbl_denorm_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2343) 	bset		&15,%d0			# set sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2344) fss_dbl_denorm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2345) 	bset		&0x7,FP_SRC_HI(%a6)	# set j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2346) 	mov.w		%d0,FP_SRC_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2347) funimp_skew_dbl_not:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2348) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2350) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2351) 	global		_mem_write2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2352) _mem_write2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2353) 	btst		&0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2354) 	beq.l		_dmem_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2355) 	mov.l		0x0(%a0),FP_DST_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2356) 	mov.l		0x4(%a0),FP_DST_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2357) 	mov.l		0x8(%a0),FP_DST_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2358) 	clr.l		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2359) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2361) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2362) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2363) #	_fpsp_effadd(): 060FPSP entry point for FP "Unimplemented	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2364) #			effective address" exception.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2365) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2366) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2367) #	FP Unimplemented Effective Address exception in an operating	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2368) #	system.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2369) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2370) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2371) #	_imem_read_long() - read instruction longword			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2372) #	fix_skewed_ops() - adjust src operand in fsave frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2373) #	set_tag_x() - determine optype of src/dst operands		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2374) #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2375) #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2376) #	load_fpn2() - load dst operand from FP regfile			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2377) #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2378) #	decbin() - convert packed data to FP binary data		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2379) #	_real_fpu_disabled() - "callout" for "FPU disabled" exception	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2380) #	_real_access() - "callout" for access error exception		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2381) #	_mem_read() - read extended immediate operand from memory	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2382) #	_fpsp_done() - "callout" for exit; work all done		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2383) #	_real_trace() - "callout" for Trace enabled exception		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2384) #	fmovm_dynamic() - emulate dynamic fmovm instruction		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2385) #	fmovm_ctrl() - emulate fmovm control instruction		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2386) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2387) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2388) #	- The system stack contains the "Unimplemented <ea>" stk frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2389) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2390) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2391) #	If access error:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2392) #	- The system stack is changed to an access error stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2393) #	If FPU disabled:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2394) #	- The system stack is changed to an FPU disabled stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2395) #	If Trace exception enabled:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2396) #	- The system stack is changed to a Trace exception stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2397) #	Else: (normal case)						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2398) #	- None (correct result has been stored as appropriate)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2399) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2400) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2401) #	This exception handles 3 types of operations:			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2402) # (1) FP Instructions using extended precision or packed immediate	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2403) #     addressing mode.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2404) # (2) The "fmovm.x" instruction w/ dynamic register specification.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2405) # (3) The "fmovm.l" instruction w/ 2 or 3 control registers.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2406) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2407) #	For immediate data operations, the data is read in w/ a		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2408) # _mem_read() "callout", converted to FP binary (if packed), and used	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2409) # as the source operand to the instruction specified by the instruction	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2410) # word. If no FP exception should be reported ads a result of the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2411) # emulation, then the result is stored to the destination register and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2412) # the handler exits through _fpsp_done(). If an enabled exc has been	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2413) # signalled as a result of emulation, then an fsave state frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2414) # corresponding to the FP exception type must be entered into the 060	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2415) # FPU before exiting. In either the enabled or disabled cases, we	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2416) # must also check if a Trace exception is pending, in which case, we	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2417) # must create a Trace exception stack frame from the current exception	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2418) # stack frame. If no Trace is pending, we simply exit through		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2419) # _fpsp_done().								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2420) #	For "fmovm.x", call the routine fmovm_dynamic() which will	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2421) # decode and emulate the instruction. No FP exceptions can be pending	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2422) # as a result of this operation emulation. A Trace exception can be	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2423) # pending, though, which means the current stack frame must be changed	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2424) # to a Trace stack frame and an exit made through _real_trace().	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2425) # For the case of "fmovm.x Dn,-(a7)", where the offending instruction	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2426) # was executed from supervisor mode, this handler must store the FP	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2427) # register file values to the system stack by itself since		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2428) # fmovm_dynamic() can't handle this. A normal exit is made through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2429) # fpsp_done().								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2430) #	For "fmovm.l", fmovm_ctrl() is used to emulate the instruction.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2431) # Again, a Trace exception may be pending and an exit made through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2432) # _real_trace(). Else, a normal exit is made through _fpsp_done().	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2433) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2434) #	Before any of the above is attempted, it must be checked to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2435) # see if the FPU is disabled. Since the "Unimp <ea>" exception is taken	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2436) # before the "FPU disabled" exception, but the "FPU disabled" exception	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2437) # has higher priority, we check the disabled bit in the PCR. If set,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2438) # then we must create an 8 word "FPU disabled" exception stack frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2439) # from the current 4 word exception stack frame. This includes		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2440) # reproducing the effective address of the instruction to put on the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2441) # new stack frame.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2442) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2443) #	In the process of all emulation work, if a _mem_read()		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2444) # "callout" returns a failing result indicating an access error, then	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2445) # we must create an access error stack frame from the current stack	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2446) # frame. This information includes a faulting address and a fault-	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2447) # status-longword. These are created within this handler.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2448) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2449) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2451) 	global		_fpsp_effadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2452) _fpsp_effadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2454) # This exception type takes priority over the "Line F Emulator"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2455) # exception. Therefore, the FPU could be disabled when entering here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2456) # So, we must check to see if it's disabled and handle that case separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2457) 	mov.l		%d0,-(%sp)		# save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2458) 	movc		%pcr,%d0		# load proc cr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2459) 	btst		&0x1,%d0		# is FPU disabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2460) 	bne.w		iea_disabled		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2461) 	mov.l		(%sp)+,%d0		# restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2463) 	link		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2465) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2466) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2467) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2469) # PC of instruction that took the exception is the PC in the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2470) 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2472) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2473) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2474) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2475) 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2477) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2479) 	tst.w		%d0			# is operation fmovem?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2480) 	bmi.w		iea_fmovm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2482) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2483) # here, we will have:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2484) #	fabs	fdabs	fsabs		facos		fmod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2485) #	fadd	fdadd	fsadd		fasin		frem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2486) #	fcmp				fatan		fscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2487) #	fdiv	fddiv	fsdiv		fatanh		fsin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2488) #	fint				fcos		fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2489) #	fintrz				fcosh		fsinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2490) #	fmove	fdmove	fsmove		fetox		ftan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2491) #	fmul	fdmul	fsmul		fetoxm1		ftanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2492) #	fneg	fdneg	fsneg		fgetexp		ftentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2493) #	fsgldiv				fgetman		ftwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2494) #	fsglmul				flog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2495) #	fsqrt				flog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2496) #	fsub	fdsub	fssub		flogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2497) #	ftst				flognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2498) # which can all use f<op>.{x,p}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2499) # so, now it's immediate data extended precision AND PACKED FORMAT!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2500) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2501) iea_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2502) 	andi.l		&0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2504) 	btst		&0xa,%d0		# is src fmt x or p?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2505) 	bne.b		iea_op_pack		# packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2508) 	mov.l		EXC_EXTWPTR(%a6),%a0	# pass: ptr to #<data>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2509) 	lea		FP_SRC(%a6),%a1		# pass: ptr to super addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2510) 	mov.l		&0xc,%d0		# pass: 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2511) 	bsr.l		_imem_read		# read extended immediate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2513) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2514) 	bne.w		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2516) 	bra.b		iea_op_setsrc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2518) iea_op_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2520) 	mov.l		EXC_EXTWPTR(%a6),%a0	# pass: ptr to #<data>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2521) 	lea		FP_SRC(%a6),%a1		# pass: ptr to super dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2522) 	mov.l		&0xc,%d0		# pass: 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2523) 	bsr.l		_imem_read		# read packed operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2525) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2526) 	bne.w		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2528) # The packed operand is an INF or a NAN if the exponent field is all ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2529) 	bfextu		FP_SRC(%a6){&1:&15},%d0	# get exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2530) 	cmpi.w		%d0,&0x7fff		# INF or NAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2531) 	beq.b		iea_op_setsrc		# operand is an INF or NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2533) # The packed operand is a zero if the mantissa is all zero, else it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2534) # a normal packed op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2535) 	mov.b		3+FP_SRC(%a6),%d0	# get byte 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2536) 	andi.b		&0x0f,%d0		# clear all but last nybble
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2537) 	bne.b		iea_op_gp_not_spec	# not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2538) 	tst.l		FP_SRC_HI(%a6)		# is lw 2 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2539) 	bne.b		iea_op_gp_not_spec	# not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2540) 	tst.l		FP_SRC_LO(%a6)		# is lw 3 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2541) 	beq.b		iea_op_setsrc		# operand is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2542) iea_op_gp_not_spec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2543) 	lea		FP_SRC(%a6),%a0		# pass: ptr to packed op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2544) 	bsr.l		decbin			# convert to extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2545) 	fmovm.x		&0x80,FP_SRC(%a6)	# make this the srcop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2547) iea_op_setsrc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2548) 	addi.l		&0xc,EXC_EXTWPTR(%a6)	# update extension word pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2550) # FP_SRC now holds the src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2551) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2552) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2553) 	mov.b		%d0,STAG(%a6)		# could be ANYTHING!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2554) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2555) 	bne.b		iea_op_getdst		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2556) 	bsr.l		unnorm_fix		# yes; convert to NORM/DENORM/ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2557) 	mov.b		%d0,STAG(%a6)		# set new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2558) iea_op_getdst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2559) 	clr.b		STORE_FLG(%a6)		# clear "store result" boolean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2561) 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2562) 	beq.b		iea_op_extract		# monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2563) 	btst		&0x4,1+EXC_CMDREG(%a6)	# is operation fsincos,ftst,fcmp?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2564) 	bne.b		iea_op_spec		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2566) iea_op_loaddst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2567) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2568) 	bsr.l		load_fpn2		# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2570) 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2571) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2572) 	mov.b		%d0,DTAG(%a6)		# could be ANYTHING!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2573) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2574) 	bne.b		iea_op_extract		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2575) 	bsr.l		unnorm_fix		# yes; convert to NORM/DENORM/ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2576) 	mov.b		%d0,DTAG(%a6)		# set new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2577) 	bra.b		iea_op_extract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2579) # the operation is fsincos, ftst, or fcmp. only fcmp is dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2580) iea_op_spec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2581) 	btst		&0x3,1+EXC_CMDREG(%a6)	# is operation fsincos?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2582) 	beq.b		iea_op_extract		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2583) # now, we're left with ftst and fcmp. so, first let's tag them so that they don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2584) # store a result. then, only fcmp will branch back and pick up a dst operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2585) 	st		STORE_FLG(%a6)		# don't store a final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2586) 	btst		&0x1,1+EXC_CMDREG(%a6)	# is operation fcmp?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2587) 	beq.b		iea_op_loaddst		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2589) iea_op_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2590) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2591) 	mov.b		FPCR_MODE(%a6),%d0	# pass: rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2593) 	mov.b		1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2594) 	andi.w		&0x007f,%d1		# extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2596) 	fmov.l		&0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2597) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2599) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2600) 	lea		FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2602) 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2603) 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2605) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2606) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2607) #	BSUN	: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2608) #	SNAN	: all operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2609) #	OPERR	: all reg-reg or mem-reg operations that can normally operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2610) #	OVFL	: same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2611) #	UNFL	: same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2612) #	DZ	: same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2613) #	INEX2	: same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2614) #	INEX1	: all packed immediate operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2615) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2617) # we determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2618) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2619) 	mov.b		FPCR_ENABLE(%a6),%d0	# fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2620) 	bne.b		iea_op_ena		# some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2622) # now, we save the result, unless, of course, the operation was ftst or fcmp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2623) # these don't save results.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2624) iea_op_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2625) 	tst.b		STORE_FLG(%a6)		# does this op store a result?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2626) 	bne.b		iea_op_exit1		# exit with no frestore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2628) iea_op_store:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2629) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2630) 	bsr.l		store_fpreg		# store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2632) iea_op_exit1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2633) 	mov.l		EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2634) 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2636) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2637) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2638) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2640) 	unlk		%a6			# unravel the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2642) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2643) 	bne.w		iea_op_trace		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2645) 	bra.l		_fpsp_done		# exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2647) iea_op_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2648) 	and.b		FPSR_EXCEPT(%a6),%d0	# keep only ones enable and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2649) 	bfffo		%d0{&24:&8},%d0		# find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2650) 	bne.b		iea_op_exc		# at least one was set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2652) # no exception occurred. now, did a disabled, exact overflow occur with inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2653) # enabled? if so, then we have to stuff an overflow frame into the FPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2654) 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2655) 	beq.b		iea_op_save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2657) iea_op_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2658) 	btst		&inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2659) 	beq.b		iea_op_store		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2660) 	bra.b		iea_op_exc_ovfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2662) # an enabled exception occurred. we have to insert the exception type back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2663) # the machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2664) iea_op_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2665) 	subi.l		&24,%d0			# fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2666) 	cmpi.b		%d0,&0x6		# is exception INEX?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2667) 	bne.b		iea_op_exc_force	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2669) # the enabled exception was inexact. so, if it occurs with an overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2670) # or underflow that was disabled, then we have to force an overflow or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2671) # underflow frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2672) 	btst		&ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2673) 	bne.b		iea_op_exc_ovfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2674) 	btst		&unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2675) 	bne.b		iea_op_exc_unfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2677) iea_op_exc_force:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2678) 	mov.w		(tbl_iea_except.b,%pc,%d0.w*2),2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2679) 	bra.b		iea_op_exit2		# exit with frestore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2681) tbl_iea_except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2682) 	short		0xe002, 0xe006, 0xe004, 0xe005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2683) 	short		0xe003, 0xe002, 0xe001, 0xe001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2685) iea_op_exc_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2686) 	mov.w		&0xe005,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2687) 	bra.b		iea_op_exit2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2689) iea_op_exc_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2690) 	mov.w		&0xe003,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2692) iea_op_exit2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2693) 	mov.l		EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2694) 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2696) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2697) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2698) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2700) 	frestore	FP_SRC(%a6)		# restore exceptional state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2702) 	unlk		%a6			# unravel the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2704) 	btst		&0x7,(%sp)		# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2705) 	bne.b		iea_op_trace		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2707) 	bra.l		_fpsp_done		# exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2709) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2710) # The opclass two instruction that took an "Unimplemented Effective Address"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2711) # exception was being traced. Make the "current" PC the FPIAR and put it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2712) # the trace stack frame then jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2713) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2714) #		 UNIMP EA FRAME		   TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2715) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2716) #		* 0x0 *  0x0f0	*	*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2717) #		*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2718) #		*    Current	*	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2719) #		*      PC	*	* 0x2 *  0x024	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2720) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2721) #		*      SR	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2722) #		*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2723) #					*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2724) #					*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2725) #					*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2726) iea_op_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2727) 	mov.l		(%sp),-(%sp)		# shift stack frame "down"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2728) 	mov.w		0x8(%sp),0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2729) 	mov.w		&0x2024,0x6(%sp)	# stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2730) 	fmov.l		%fpiar,0x8(%sp)		# "Current PC" is in FPIAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2732) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2734) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2735) iea_fmovm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2736) 	btst		&14,%d0			# ctrl or data reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2737) 	beq.w		iea_fmovm_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2739) iea_fmovm_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2741) 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2742) 	bne.b		iea_fmovm_data_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2744) iea_fmovm_data_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2745) 	mov.l		%usp,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2746) 	mov.l		%a0,EXC_A7(%a6)		# store current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2747) 	bsr.l		fmovm_dynamic		# do dynamic fmovm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2748) 	mov.l		EXC_A7(%a6),%a0		# load possibly new a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2749) 	mov.l		%a0,%usp		# update usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2750) 	bra.w		iea_fmovm_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2752) iea_fmovm_data_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2753) 	clr.b		SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2754) 	lea		0x2+EXC_VOFF(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2755) 	mov.l		%a0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2756) 	bsr.l		fmovm_dynamic		# do dynamic fmovm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2758) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2759) 	beq.w		iea_fmovm_data_predec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2760) 	cmpi.b		SPCOND_FLG(%a6),&mia7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2761) 	bne.w		iea_fmovm_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2763) # right now, d0 = the size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2764) # the data has been fetched from the supervisor stack, but we have not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2765) # incremented the stack pointer by the appropriate number of bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2766) # do it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2767) iea_fmovm_data_postinc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2768) 	btst		&0x7,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2769) 	bne.b		iea_fmovm_data_pi_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2771) 	mov.w		EXC_SR(%a6),(EXC_SR,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2772) 	mov.l		EXC_EXTWPTR(%a6),(EXC_PC,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2773) 	mov.w		&0x00f0,(EXC_VOFF,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2775) 	lea		(EXC_SR,%a6,%d0),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2776) 	mov.l		%a0,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2778) 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2779) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2780) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2782) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2783) 	mov.l		(%sp)+,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2784) 	bra.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2786) iea_fmovm_data_pi_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2787) 	mov.w		EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2788) 	mov.l		EXC_EXTWPTR(%a6),(EXC_PC-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2789) 	mov.w		&0x2024,(EXC_VOFF-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2790) 	mov.l		EXC_PC(%a6),(EXC_VOFF+0x2-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2792) 	lea		(EXC_SR-0x4,%a6,%d0),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2793) 	mov.l		%a0,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2795) 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2796) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2797) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2799) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2800) 	mov.l		(%sp)+,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2801) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2803) # right now, d1 = size and d0 = the strg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2804) iea_fmovm_data_predec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2805) 	mov.b		%d1,EXC_VOFF(%a6)	# store strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2806) 	mov.b		%d0,0x1+EXC_VOFF(%a6)	# store size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2808) 	fmovm.x		EXC_FP0(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2809) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2810) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2812) 	mov.l		(%a6),-(%sp)		# make a copy of a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2813) 	mov.l		%d0,-(%sp)		# save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2814) 	mov.l		%d1,-(%sp)		# save d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2815) 	mov.l		EXC_EXTWPTR(%a6),-(%sp)	# make a copy of Next PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2817) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2818) 	mov.b		0x1+EXC_VOFF(%a6),%d0	# fetch size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2819) 	neg.l		%d0			# get negative of size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2821) 	btst		&0x7,EXC_SR(%a6)	# is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2822) 	beq.b		iea_fmovm_data_p2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2824) 	mov.w		EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2825) 	mov.l		EXC_PC(%a6),(EXC_VOFF-0x2,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2826) 	mov.l		(%sp)+,(EXC_PC-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2827) 	mov.w		&0x2024,(EXC_VOFF-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2829) 	pea		(%a6,%d0)		# create final sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2830) 	bra.b		iea_fmovm_data_p3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2832) iea_fmovm_data_p2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2833) 	mov.w		EXC_SR(%a6),(EXC_SR,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2834) 	mov.l		(%sp)+,(EXC_PC,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2835) 	mov.w		&0x00f0,(EXC_VOFF,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2837) 	pea		(0x4,%a6,%d0)		# create final sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2839) iea_fmovm_data_p3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2840) 	clr.l		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2841) 	mov.b		EXC_VOFF(%a6),%d1	# fetch strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2843) 	tst.b		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2844) 	bpl.b		fm_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2845) 	fmovm.x		&0x80,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2846) 	addi.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2847) fm_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2848) 	lsl.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2849) 	bpl.b		fm_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2850) 	fmovm.x		&0x40,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2851) 	addi.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2852) fm_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2853) 	lsl.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2854) 	bpl.b		fm_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2855) 	fmovm.x		&0x20,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2856) 	addi.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2857) fm_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2858) 	lsl.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2859) 	bpl.b		fm_4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2860) 	fmovm.x		&0x10,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2861) 	addi.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2862) fm_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2863) 	lsl.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2864) 	bpl.b		fm_5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2865) 	fmovm.x		&0x08,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2866) 	addi.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2867) fm_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2868) 	lsl.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2869) 	bpl.b		fm_6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2870) 	fmovm.x		&0x04,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2871) 	addi.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2872) fm_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2873) 	lsl.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2874) 	bpl.b		fm_7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2875) 	fmovm.x		&0x02,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2876) 	addi.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2877) fm_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2878) 	lsl.b		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2879) 	bpl.b		fm_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2880) 	fmovm.x		&0x01,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2881) fm_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2882) 	mov.l		0x4(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2883) 	mov.l		0x8(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2884) 	mov.l		0xc(%sp),%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2885) 	mov.l		(%sp)+,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2887) 	btst		&0x7,(%sp)		# is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2888) 	beq.l		_fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2889) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2891) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2892) iea_fmovm_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2894) 	bsr.l		fmovm_ctrl		# load ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2896) iea_fmovm_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2897) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2898) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2899) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2901) 	btst		&0x7,EXC_SR(%a6)	# is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2902) 	bne.b		iea_fmovm_trace		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2904) 	mov.l		EXC_EXTWPTR(%a6),EXC_PC(%a6) # set Next PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2906) 	unlk		%a6			# unravel the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2908) 	bra.l		_fpsp_done		# exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2910) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2911) # The control reg instruction that took an "Unimplemented Effective Address"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2912) # exception was being traced. The "Current PC" for the trace frame is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2913) # PC stacked for Unimp EA. The "Next PC" is in EXC_EXTWPTR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2914) # After fixing the stack frame, jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2915) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2916) #		 UNIMP EA FRAME		   TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2917) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2918) #		* 0x0 *  0x0f0	*	*    Current	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2919) #		*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2920) #		*    Current	*	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2921) #		*      PC	*	* 0x2 *  0x024	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2922) #		*****************	*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2923) #		*      SR	*	*     Next	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2924) #		*****************	*      PC	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2925) #					*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2926) #					*      SR	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2927) #					*****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2928) # this ain't a pretty solution, but it works:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2929) # -restore a6 (not with unlk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2930) # -shift stack frame down over where old a6 used to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2931) # -add LOCAL_SIZE to stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2932) iea_fmovm_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2933) 	mov.l		(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2934) 	mov.w		EXC_SR+LOCAL_SIZE(%sp),0x0+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2935) 	mov.l		EXC_PC+LOCAL_SIZE(%sp),0x8+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2936) 	mov.l		EXC_EXTWPTR+LOCAL_SIZE(%sp),0x2+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2937) 	mov.w		&0x2024,0x6+LOCAL_SIZE(%sp) # stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2938) 	add.l		&LOCAL_SIZE,%sp		# clear stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2940) 	bra.l		_real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2942) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2943) # The FPU is disabled and so we should really have taken the "Line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2944) # F Emulator" exception. So, here we create an 8-word stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2945) # from our 4-word stack frame. This means we must calculate the length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2946) # the faulting instruction to get the "next PC". This is trivial for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2947) # immediate operands but requires some extra work for fmovm dynamic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2948) # which can use most addressing modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2949) iea_disabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2950) 	mov.l		(%sp)+,%d0		# restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2952) 	link		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2954) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2956) # PC of instruction that took the exception is the PC in the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2957) 	mov.l		EXC_PC(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2958) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2959) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2960) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2961) 	mov.l		%d0,EXC_OPWORD(%a6)	# store OPWORD and EXTWORD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2963) 	tst.w		%d0			# is instr fmovm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2964) 	bmi.b		iea_dis_fmovm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2965) # instruction is using an extended precision immediate operand. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2966) # the total instruction length is 16 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2967) iea_dis_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2968) 	mov.l		&0x10,%d0		# 16 bytes of instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2969) 	bra.b		iea_dis_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2970) iea_dis_fmovm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2971) 	btst		&0xe,%d0		# is instr fmovm ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2972) 	bne.b		iea_dis_fmovm_data	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2973) # the instruction is a fmovm.l with 2 or 3 registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2974) 	bfextu		%d0{&19:&3},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2975) 	mov.l		&0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2976) 	cmpi.b		%d1,&0x7		# move all regs?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2977) 	bne.b		iea_dis_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2978) 	addq.l		&0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2979) 	bra.b		iea_dis_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2980) # the instruction is an fmovm.x dynamic which can use many addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2981) # modes and thus can have several different total instruction lengths.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2982) # call fmovm_calc_ea which will go through the ea calc process and,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2983) # as a by-product, will tell us how long the instruction is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2984) iea_dis_fmovm_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2985) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2986) 	bsr.l		fmovm_calc_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2987) 	mov.l		EXC_EXTWPTR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2988) 	sub.l		EXC_PC(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2989) iea_dis_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2990) 	mov.w		%d0,EXC_VOFF(%a6)	# store stack shift value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2992) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2994) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2996) # here, we actually create the 8-word frame from the 4-word frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2997) # with the "next PC" as additional info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2998) # the <ea> field is let as undefined.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2999) 	subq.l		&0x8,%sp		# make room for new stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3000) 	mov.l		%d0,-(%sp)		# save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3001) 	mov.w		0xc(%sp),0x4(%sp)	# move SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3002) 	mov.l		0xe(%sp),0x6(%sp)	# move Current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3003) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3004) 	mov.w		0x12(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3005) 	mov.l		0x6(%sp),0x10(%sp)	# move Current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3006) 	add.l		%d0,0x6(%sp)		# make Next PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3007) 	mov.w		&0x402c,0xa(%sp)	# insert offset,frame format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3008) 	mov.l		(%sp)+,%d0		# restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3010) 	bra.l		_real_fpu_disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3012) ##########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3014) iea_iacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3015) 	movc		%pcr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3016) 	btst		&0x1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3017) 	bne.b		iea_iacc_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3018) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3019) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3020) iea_iacc_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3021) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3023) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3025) 	subq.w		&0x8,%sp		# make stack frame bigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3026) 	mov.l		0x8(%sp),(%sp)		# store SR,hi(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3027) 	mov.w		0xc(%sp),0x4(%sp)	# store lo(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3028) 	mov.w		&0x4008,0x6(%sp)	# store voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3029) 	mov.l		0x2(%sp),0x8(%sp)	# store ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3030) 	mov.l		&0x09428001,0xc(%sp)	# store fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3032) iea_acc_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3033) 	btst		&0x5,(%sp)		# user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3034) 	beq.b		iea_acc_done2		# user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3035) 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3037) iea_acc_done2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3038) 	bra.l		_real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3040) iea_dacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3041) 	lea		-LOCAL_SIZE(%a6),%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3043) 	movc		%pcr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3044) 	btst		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3045) 	bne.b		iea_dacc_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3046) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3047) 	fmovm.l		LOCAL_SIZE+USER_FPCR(%sp),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3048) iea_dacc_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3049) 	mov.l		(%a6),%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3051) 	mov.l		0x4+LOCAL_SIZE(%sp),-0x8+0x4+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3052) 	mov.w		0x8+LOCAL_SIZE(%sp),-0x8+0x8+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3053) 	mov.w		&0x4008,-0x8+0xa+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3054) 	mov.l		%a0,-0x8+0xc+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3055) 	mov.w		%d0,-0x8+0x10+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3056) 	mov.w		&0x0001,-0x8+0x12+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3058) 	movm.l		LOCAL_SIZE+EXC_DREGS(%sp),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3059) 	add.w		&LOCAL_SIZE-0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3061) 	bra.b		iea_acc_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3063) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3064) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3065) #	_fpsp_operr(): 060FPSP entry point for FP Operr exception.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3066) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3067) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3068) #	FP Operand Error exception in an operating system.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3069) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3070) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3071) #	_imem_read_long() - read instruction longword			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3072) #	fix_skewed_ops() - adjust src operand in fsave frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3073) #	_real_operr() - "callout" to operating system operr handler	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3074) #	_dmem_write_{byte,word,long}() - store data to mem (opclass 3)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3075) #	store_dreg_{b,w,l}() - store data to data regfile (opclass 3)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3076) #	facc_out_{b,w,l}() - store to memory took access error (opcl 3)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3077) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3078) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3079) #	- The system stack contains the FP Operr exception frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3080) #	- The fsave frame contains the source operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3081) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3082) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3083) #	No access error:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3084) #	- The system stack is unchanged					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3085) #	- The fsave frame contains the adjusted src op for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3086) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3087) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3088) #	In a system where the FP Operr exception is enabled, the goal	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3089) # is to get to the handler specified at _real_operr(). But, on the 060,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3090) # for opclass zero and two instruction taking this exception, the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3091) # input operand in the fsave frame may be incorrect for some cases	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3092) # and needs to be corrected. This handler calls fix_skewed_ops() to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3093) # do just this and then exits through _real_operr().			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3094) #	For opclass 3 instructions, the 060 doesn't store the default	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3095) # operr result out to memory or data register file as it should.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3096) # This code must emulate the move out before finally exiting through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3097) # _real_inex(). The move out, if to memory, is performed using		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3098) # _mem_write() "callout" routines that may return a failing result.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3099) # In this special case, the handler must exit through facc_out()	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3100) # which creates an access error stack frame from the current operr	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3101) # stack frame.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3102) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3103) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3105) 	global		_fpsp_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3106) _fpsp_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3108) 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3110) 	fsave		FP_SRC(%a6)		# grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3112) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3113) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3114) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3116) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3117) 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3119) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3120) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3121) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3122) 	mov.l		%d0,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3124) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3126) 	btst		&13,%d0			# is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3127) 	bne.b		foperr_out		# fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3130) # here, we simply see if the operand in the fsave frame needs to be "unskewed".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3131) # this would be the case for opclass two operations with a source infinity or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3132) # denorm operand in the sgl or dbl format. NANs also become skewed, but can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3133) # cause an operr so we don't need to check for them here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3134) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3135) 	bsr.l		fix_skewed_ops		# fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3137) foperr_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3138) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3139) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3140) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3142) 	frestore	FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3144) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3145) 	bra.l		_real_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3147) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3149) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3150) # the hardware does not save the default result to memory on enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3151) # operand error exceptions. we do this here before passing control to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3152) # the user operand error handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3153) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3154) # byte, word, and long destination format operations can pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3155) # through here. we simply need to test the sign of the src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3156) # operand and save the appropriate minimum or maximum integer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3157) # to the effective address as pointed to by the stacked effective address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3158) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3159) # although packed opclass three operations can take operand error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3160) # exceptions, they won't pass through here since they are caught
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3161) # first by the unsupported data format exception handler. that handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3162) # sends them directly to _real_operr() if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3163) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3164) foperr_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3166) 	mov.w		FP_SRC_EX(%a6),%d1	# fetch exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3167) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3168) 	cmpi.w		%d1,&0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3169) 	bne.b		foperr_out_not_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3170) # the operand is either an infinity or a QNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3171) 	tst.l		FP_SRC_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3172) 	bne.b		foperr_out_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3173) 	mov.l		FP_SRC_HI(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3174) 	andi.l		&0x7fffffff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3175) 	beq.b		foperr_out_not_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3176) foperr_out_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3177) 	mov.l		FP_SRC_HI(%a6),L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3178) 	bra.b		foperr_out_jmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3180) foperr_out_not_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3181) 	mov.l		&0x7fffffff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3182) 	tst.b		FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3183) 	bpl.b		foperr_out_not_qnan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3184) 	addq.l		&0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3185) foperr_out_not_qnan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3186) 	mov.l		%d1,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3188) foperr_out_jmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3189) 	bfextu		%d0{&19:&3},%d0		# extract dst format field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3190) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract <ea> mode,reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3191) 	mov.w		(tbl_operr.b,%pc,%d0.w*2),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3192) 	jmp		(tbl_operr.b,%pc,%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3194) tbl_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3195) 	short		foperr_out_l - tbl_operr # long word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3196) 	short		tbl_operr    - tbl_operr # sgl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3197) 	short		tbl_operr    - tbl_operr # ext prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3198) 	short		foperr_exit  - tbl_operr # packed won't enter here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3199) 	short		foperr_out_w - tbl_operr # word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3200) 	short		tbl_operr    - tbl_operr # dbl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3201) 	short		foperr_out_b - tbl_operr # byte integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3202) 	short		tbl_operr    - tbl_operr # packed won't enter here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3204) foperr_out_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3205) 	mov.b		L_SCR1(%a6),%d0		# load positive default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3206) 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3207) 	ble.b		foperr_out_b_save_dn	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3208) 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3209) 	bsr.l		_dmem_write_byte	# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3211) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3212) 	bne.l		facc_out_b		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3214) 	bra.w		foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3215) foperr_out_b_save_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3216) 	andi.w		&0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3217) 	bsr.l		store_dreg_b		# store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3218) 	bra.w		foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3220) foperr_out_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3221) 	mov.w		L_SCR1(%a6),%d0		# load positive default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3222) 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3223) 	ble.b		foperr_out_w_save_dn	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3224) 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3225) 	bsr.l		_dmem_write_word	# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3227) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3228) 	bne.l		facc_out_w		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3230) 	bra.w		foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3231) foperr_out_w_save_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3232) 	andi.w		&0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3233) 	bsr.l		store_dreg_w		# store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3234) 	bra.w		foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3236) foperr_out_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3237) 	mov.l		L_SCR1(%a6),%d0		# load positive default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3238) 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3239) 	ble.b		foperr_out_l_save_dn	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3240) 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3241) 	bsr.l		_dmem_write_long	# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3243) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3244) 	bne.l		facc_out_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3246) 	bra.w		foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3247) foperr_out_l_save_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3248) 	andi.w		&0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3249) 	bsr.l		store_dreg_l		# store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3250) 	bra.w		foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3252) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3253) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3254) #	_fpsp_snan(): 060FPSP entry point for FP SNAN exception.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3255) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3256) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3257) #	FP Signalling NAN exception in an operating system.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3258) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3259) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3260) #	_imem_read_long() - read instruction longword			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3261) #	fix_skewed_ops() - adjust src operand in fsave frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3262) #	_real_snan() - "callout" to operating system SNAN handler	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3263) #	_dmem_write_{byte,word,long}() - store data to mem (opclass 3)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3264) #	store_dreg_{b,w,l}() - store data to data regfile (opclass 3)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3265) #	facc_out_{b,w,l,d,x}() - store to mem took acc error (opcl 3)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3266) #	_calc_ea_fout() - fix An if <ea> is -() or ()+; also get <ea>	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3267) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3268) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3269) #	- The system stack contains the FP SNAN exception frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3270) #	- The fsave frame contains the source operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3271) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3272) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3273) #	No access error:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3274) #	- The system stack is unchanged					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3275) #	- The fsave frame contains the adjusted src op for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3276) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3277) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3278) #	In a system where the FP SNAN exception is enabled, the goal	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3279) # is to get to the handler specified at _real_snan(). But, on the 060,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3280) # for opclass zero and two instructions taking this exception, the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3281) # input operand in the fsave frame may be incorrect for some cases	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3282) # and needs to be corrected. This handler calls fix_skewed_ops() to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3283) # do just this and then exits through _real_snan().			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3284) #	For opclass 3 instructions, the 060 doesn't store the default	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3285) # SNAN result out to memory or data register file as it should.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3286) # This code must emulate the move out before finally exiting through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3287) # _real_snan(). The move out, if to memory, is performed using		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3288) # _mem_write() "callout" routines that may return a failing result.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3289) # In this special case, the handler must exit through facc_out()	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3290) # which creates an access error stack frame from the current SNAN	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3291) # stack frame.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3292) #	For the case of an extended precision opclass 3 instruction,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3293) # if the effective addressing mode was -() or ()+, then the address	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3294) # register must get updated by calling _calc_ea_fout(). If the <ea>	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3295) # was -(a7) from supervisor mode, then the exception frame currently	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3296) # on the system stack must be carefully moved "down" to make room	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3297) # for the operand being moved.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3298) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3299) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3301) 	global		_fpsp_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3302) _fpsp_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3304) 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3306) 	fsave		FP_SRC(%a6)		# grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3308) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3309) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3310) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3312) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3313) 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3315) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3316) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3317) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3318) 	mov.l		%d0,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3320) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3322) 	btst		&13,%d0			# is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3323) 	bne.w		fsnan_out		# fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3326) # here, we simply see if the operand in the fsave frame needs to be "unskewed".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3327) # this would be the case for opclass two operations with a source infinity or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3328) # denorm operand in the sgl or dbl format. NANs also become skewed and must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3329) # fixed here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3330) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3331) 	bsr.l		fix_skewed_ops		# fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3333) fsnan_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3334) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3335) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3336) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3338) 	frestore	FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3340) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3341) 	bra.l		_real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3343) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3345) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3346) # the hardware does not save the default result to memory on enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3347) # snan exceptions. we do this here before passing control to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3348) # the user snan handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3349) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3350) # byte, word, long, and packed destination format operations can pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3351) # through here. since packed format operations already were handled by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3352) # fpsp_unsupp(), then we need to do nothing else for them here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3353) # for byte, word, and long, we simply need to test the sign of the src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3354) # operand and save the appropriate minimum or maximum integer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3355) # to the effective address as pointed to by the stacked effective address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3356) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3357) fsnan_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3359) 	bfextu		%d0{&19:&3},%d0		# extract dst format field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3360) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract <ea> mode,reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3361) 	mov.w		(tbl_snan.b,%pc,%d0.w*2),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3362) 	jmp		(tbl_snan.b,%pc,%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3364) tbl_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3365) 	short		fsnan_out_l - tbl_snan # long word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3366) 	short		fsnan_out_s - tbl_snan # sgl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3367) 	short		fsnan_out_x - tbl_snan # ext prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3368) 	short		tbl_snan    - tbl_snan # packed needs no help
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3369) 	short		fsnan_out_w - tbl_snan # word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3370) 	short		fsnan_out_d - tbl_snan # dbl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3371) 	short		fsnan_out_b - tbl_snan # byte integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3372) 	short		tbl_snan    - tbl_snan # packed needs no help
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3374) fsnan_out_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3375) 	mov.b		FP_SRC_HI(%a6),%d0	# load upper byte of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3376) 	bset		&6,%d0			# set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3377) 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3378) 	ble.b		fsnan_out_b_dn		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3379) 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3380) 	bsr.l		_dmem_write_byte	# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3382) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3383) 	bne.l		facc_out_b		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3385) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3386) fsnan_out_b_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3387) 	andi.w		&0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3388) 	bsr.l		store_dreg_b		# store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3389) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3391) fsnan_out_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3392) 	mov.w		FP_SRC_HI(%a6),%d0	# load upper word of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3393) 	bset		&14,%d0			# set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3394) 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3395) 	ble.b		fsnan_out_w_dn		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3396) 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3397) 	bsr.l		_dmem_write_word	# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3399) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3400) 	bne.l		facc_out_w		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3402) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3403) fsnan_out_w_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3404) 	andi.w		&0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3405) 	bsr.l		store_dreg_w		# store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3406) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3408) fsnan_out_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3409) 	mov.l		FP_SRC_HI(%a6),%d0	# load upper longword of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3410) 	bset		&30,%d0			# set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3411) 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3412) 	ble.b		fsnan_out_l_dn		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3413) 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3414) 	bsr.l		_dmem_write_long	# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3416) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3417) 	bne.l		facc_out_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3419) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3420) fsnan_out_l_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3421) 	andi.w		&0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3422) 	bsr.l		store_dreg_l		# store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3423) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3425) fsnan_out_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3426) 	cmpi.b		%d1,&0x7		# is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3427) 	ble.b		fsnan_out_d_dn		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3428) 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3429) 	andi.l		&0x80000000,%d0		# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3430) 	ori.l		&0x7fc00000,%d0		# insert new exponent,SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3431) 	mov.l		FP_SRC_HI(%a6),%d1	# load mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3432) 	lsr.l		&0x8,%d1		# shift mantissa for sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3433) 	or.l		%d1,%d0			# create sgl SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3434) 	mov.l		EXC_EA(%a6),%a0		# pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3435) 	bsr.l		_dmem_write_long	# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3437) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3438) 	bne.l		facc_out_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3440) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3441) fsnan_out_d_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3442) 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3443) 	andi.l		&0x80000000,%d0		# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3444) 	ori.l		&0x7fc00000,%d0		# insert new exponent,SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3445) 	mov.l		%d1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3446) 	mov.l		FP_SRC_HI(%a6),%d1	# load mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3447) 	lsr.l		&0x8,%d1		# shift mantissa for sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3448) 	or.l		%d1,%d0			# create sgl SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3449) 	mov.l		(%sp)+,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3450) 	andi.w		&0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3451) 	bsr.l		store_dreg_l		# store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3452) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3454) fsnan_out_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3455) 	mov.l		FP_SRC_EX(%a6),%d0	# fetch SNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3456) 	andi.l		&0x80000000,%d0		# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3457) 	ori.l		&0x7ff80000,%d0		# insert new exponent,SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3458) 	mov.l		FP_SRC_HI(%a6),%d1	# load hi mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3459) 	mov.l		%d0,FP_SCR0_EX(%a6)	# store to temp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3460) 	mov.l		&11,%d0			# load shift amt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3461) 	lsr.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3462) 	or.l		%d1,FP_SCR0_EX(%a6)	# create dbl hi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3463) 	mov.l		FP_SRC_HI(%a6),%d1	# load hi mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3464) 	andi.l		&0x000007ff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3465) 	ror.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3466) 	mov.l		%d1,FP_SCR0_HI(%a6)	# store to temp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3467) 	mov.l		FP_SRC_LO(%a6),%d1	# load lo mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3468) 	lsr.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3469) 	or.l		%d1,FP_SCR0_HI(%a6)	# create dbl lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3470) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3471) 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3472) 	movq.l		&0x8,%d0		# pass: size of 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3473) 	bsr.l		_dmem_write		# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3475) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3476) 	bne.l		facc_out_d		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3478) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3480) # for extended precision, if the addressing mode is pre-decrement or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3481) # post-increment, then the address register did not get updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3482) # in addition, for pre-decrement, the stacked <ea> is incorrect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3483) fsnan_out_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3484) 	clr.b		SPCOND_FLG(%a6)		# clear special case flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3486) 	mov.w		FP_SRC_EX(%a6),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3487) 	clr.w		2+FP_SCR0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3488) 	mov.l		FP_SRC_HI(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3489) 	bset		&30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3490) 	mov.l		%d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3491) 	mov.l		FP_SRC_LO(%a6),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3493) 	btst		&0x5,EXC_SR(%a6)	# supervisor mode exception?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3494) 	bne.b		fsnan_out_x_s		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3496) 	mov.l		%usp,%a0		# fetch user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3497) 	mov.l		%a0,EXC_A7(%a6)		# save on stack for calc_ea()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3498) 	mov.l		(%a6),EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3500) 	bsr.l		_calc_ea_fout		# find the correct ea,update An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3501) 	mov.l		%a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3502) 	mov.l		%a0,EXC_EA(%a6)		# stack correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3504) 	mov.l		EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3505) 	mov.l		%a0,%usp		# restore user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3506) 	mov.l		EXC_A6(%a6),(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3508) fsnan_out_x_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3509) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3510) 	movq.l		&0xc,%d0		# pass: size of extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3511) 	bsr.l		_dmem_write		# write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3513) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3514) 	bne.l		facc_out_x		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3516) 	bra.w		fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3518) fsnan_out_x_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3519) 	mov.l		(%a6),EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3521) 	bsr.l		_calc_ea_fout		# find the correct ea,update An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3522) 	mov.l		%a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3523) 	mov.l		%a0,EXC_EA(%a6)		# stack correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3525) 	mov.l		EXC_A6(%a6),(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3527) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3528) 	bne.b		fsnan_out_x_save	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3530) # the operation was "fmove.x SNAN,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3531) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3532) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3533) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3535) 	frestore	FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3537) 	mov.l		EXC_A6(%a6),%a6		# restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3539) 	mov.l		LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3540) 	mov.l		LOCAL_SIZE+EXC_PC+0x2(%sp),LOCAL_SIZE+EXC_PC+0x2-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3541) 	mov.l		LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3543) 	mov.l		LOCAL_SIZE+FP_SCR0_EX(%sp),LOCAL_SIZE+EXC_SR(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3544) 	mov.l		LOCAL_SIZE+FP_SCR0_HI(%sp),LOCAL_SIZE+EXC_PC+0x2(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3545) 	mov.l		LOCAL_SIZE+FP_SCR0_LO(%sp),LOCAL_SIZE+EXC_EA(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3547) 	add.l		&LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3549) 	bra.l		_real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3551) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3552) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3553) #	_fpsp_inex(): 060FPSP entry point for FP Inexact exception.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3554) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3555) #	This handler should be the first code executed upon taking the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3556) #	FP Inexact exception in an operating system.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3557) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3558) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3559) #	_imem_read_long() - read instruction longword			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3560) #	fix_skewed_ops() - adjust src operand in fsave frame		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3561) #	set_tag_x() - determine optype of src/dst operands		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3562) #	store_fpreg() - store opclass 0 or 2 result to FP regfile	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3563) #	unnorm_fix() - change UNNORM operands to NORM or ZERO		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3564) #	load_fpn2() - load dst operand from FP regfile			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3565) #	smovcr() - emulate an "fmovcr" instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3566) #	fout() - emulate an opclass 3 instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3567) #	tbl_unsupp - add of table of emulation routines for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3568) #	_real_inex() - "callout" to operating system inexact handler	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3569) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3570) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3571) #	- The system stack contains the FP Inexact exception frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3572) #	- The fsave frame contains the source operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3573) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3574) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3575) #	- The system stack is unchanged					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3576) #	- The fsave frame contains the adjusted src op for opclass 0,2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3577) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3578) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3579) #	In a system where the FP Inexact exception is enabled, the goal	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3580) # is to get to the handler specified at _real_inex(). But, on the 060,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3581) # for opclass zero and two instruction taking this exception, the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3582) # hardware doesn't store the correct result to the destination FP	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3583) # register as did the '040 and '881/2. This handler must emulate the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3584) # instruction in order to get this value and then store it to the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3585) # correct register before calling _real_inex().				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3586) #	For opclass 3 instructions, the 060 doesn't store the default	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3587) # inexact result out to memory or data register file as it should.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3588) # This code must emulate the move out by calling fout() before finally	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3589) # exiting through _real_inex().						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3590) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3591) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3593) 	global		_fpsp_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3594) _fpsp_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3596) 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3598) 	fsave		FP_SRC(%a6)		# grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3600) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3601) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3602) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3604) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3605) 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3607) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3608) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3609) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3610) 	mov.l		%d0,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3612) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3614) 	btst		&13,%d0			# is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3615) 	bne.w		finex_out		# fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3618) # the hardware, for "fabs" and "fneg" w/ a long source format, puts the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3619) # longword integer directly into the upper longword of the mantissa along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3620) # w/ an exponent value of 0x401e. we convert this to extended precision here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3621) 	bfextu		%d0{&19:&3},%d0		# fetch instr size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3622) 	bne.b		finex_cont		# instr size is not long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3623) 	cmpi.w		FP_SRC_EX(%a6),&0x401e	# is exponent 0x401e?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3624) 	bne.b		finex_cont		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3625) 	fmov.l		&0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3626) 	fmov.l		FP_SRC_HI(%a6),%fp0	# load integer src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3627) 	fmov.x		%fp0,FP_SRC(%a6)	# store integer as extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3628) 	mov.w		&0xe001,0x2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3630) finex_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3631) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3632) 	bsr.l		fix_skewed_ops		# fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3634) # Here, we zero the ccode and exception byte field since we're going to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3635) # emulate the whole instruction. Notice, though, that we don't kill the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3636) # INEX1 bit. This is because a packed op has long since been converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3637) # to extended before arriving here. Therefore, we need to retain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3638) # INEX1 bit from when the operand was first converted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3639) 	andi.l		&0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3641) 	fmov.l		&0x0,%fpcr		# zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3642) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3644) 	bfextu		EXC_EXTWORD(%a6){&0:&6},%d1 # extract upper 6 of cmdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3645) 	cmpi.b		%d1,&0x17		# is op an fmovecr?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3646) 	beq.w		finex_fmovcr		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3648) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3649) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3650) 	mov.b		%d0,STAG(%a6)		# maybe NORM,DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3652) # bits four and five of the fp extension word separate the monadic and dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3653) # operations that can pass through fpsp_inex(). remember that fcmp and ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3654) # will never take this exception, but fsincos will.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3655) 	btst		&0x5,1+EXC_CMDREG(%a6)	# is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3656) 	beq.b		finex_extract		# monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3658) 	btst		&0x4,1+EXC_CMDREG(%a6)	# is operation an fsincos?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3659) 	bne.b		finex_extract		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3661) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3662) 	bsr.l		load_fpn2		# load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3664) 	lea		FP_DST(%a6),%a0		# pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3665) 	bsr.l		set_tag_x		# tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3666) 	cmpi.b		%d0,&UNNORM		# is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3667) 	bne.b		finex_op2_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3668) 	bsr.l		unnorm_fix		# yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3669) finex_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3670) 	mov.b		%d0,DTAG(%a6)		# save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3672) finex_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3673) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3674) 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3676) 	mov.b		1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3677) 	andi.w		&0x007f,%d1		# extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3679) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3680) 	lea		FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3682) 	mov.l		(tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3683) 	jsr		(tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3685) # the operation has been emulated. the result is in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3686) finex_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3687) 	bfextu		EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3688) 	bsr.l		store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3690) finex_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3691) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3692) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3693) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3695) 	frestore	FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3697) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3698) 	bra.l		_real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3700) finex_fmovcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3701) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3702) 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3703) 	mov.b		1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3704) 	andi.l		&0x0000007f,%d1		# pass rom offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3705) 	bsr.l		smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3706) 	bra.b		finex_save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3708) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3710) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3711) # the hardware does not save the default result to memory on enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3712) # inexact exceptions. we do this here before passing control to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3713) # the user inexact handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3714) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3715) # byte, word, and long destination format operations can pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3716) # through here. so can double and single precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3717) # although packed opclass three operations can take inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3718) # exceptions, they won't pass through here since they are caught
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3719) # first by the unsupported data format exception handler. that handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3720) # sends them directly to _real_inex() if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3721) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3722) finex_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3724) 	mov.b		&NORM,STAG(%a6)		# src is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3726) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3727) 	mov.b		FPCR_MODE(%a6),%d0	# pass rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3729) 	andi.l		&0xffff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3731) 	lea		FP_SRC(%a6),%a0		# pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3733) 	bsr.l		fout			# store the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3735) 	bra.b		finex_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3737) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3738) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3739) #	_fpsp_dz(): 060FPSP entry point for FP DZ exception.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3740) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3741) #	This handler should be the first code executed upon taking	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3742) #	the FP DZ exception in an operating system.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3743) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3744) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3745) #	_imem_read_long() - read instruction longword from memory	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3746) #	fix_skewed_ops() - adjust fsave operand				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3747) #	_real_dz() - "callout" exit point from FP DZ handler		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3748) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3749) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3750) #	- The system stack contains the FP DZ exception stack.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3751) #	- The fsave frame contains the source operand.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3752) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3753) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3754) #	- The system stack contains the FP DZ exception stack.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3755) #	- The fsave frame contains the adjusted source operand.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3756) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3757) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3758) #	In a system where the DZ exception is enabled, the goal is to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3759) # get to the handler specified at _real_dz(). But, on the 060, when the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3760) # exception is taken, the input operand in the fsave state frame may	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3761) # be incorrect for some cases and need to be adjusted. So, this package	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3762) # adjusts the operand using fix_skewed_ops() and then branches to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3763) # _real_dz().								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3764) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3765) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3767) 	global		_fpsp_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3768) _fpsp_dz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3770) 	link.w		%a6,&-LOCAL_SIZE	# init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3772) 	fsave		FP_SRC(%a6)		# grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3774) 	movm.l		&0x0303,EXC_DREGS(%a6)	# save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3775) 	fmovm.l		%fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3776) 	fmovm.x		&0xc0,EXC_FPREGS(%a6)	# save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3778) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3779) 	mov.l		USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3781) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3782) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3783) 	bsr.l		_imem_read_long		# fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3784) 	mov.l		%d0,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3786) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3789) # here, we simply see if the operand in the fsave frame needs to be "unskewed".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3790) # this would be the case for opclass two operations with a source zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3791) # in the sgl or dbl format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3792) 	lea		FP_SRC(%a6),%a0		# pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3793) 	bsr.l		fix_skewed_ops		# fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3795) fdz_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3796) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3797) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3798) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3800) 	frestore	FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3802) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3803) 	bra.l		_real_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3805) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3806) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3807) #	_fpsp_fline(): 060FPSP entry point for "Line F emulator"	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3808) #		       exception when the "reduced" version of the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3809) #		       FPSP is implemented that does not emulate	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3810) #		       FP unimplemented instructions.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3811) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3812) #	This handler should be the first code executed upon taking a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3813) #	"Line F Emulator" exception in an operating system integrating	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3814) #	the reduced version of 060FPSP.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3815) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3816) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3817) #	_real_fpu_disabled() - Handle "FPU disabled" exceptions		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3818) #	_real_fline() - Handle all other cases (treated equally)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3819) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3820) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3821) #	- The system stack contains a "Line F Emulator" exception	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3822) #	  stack frame.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3823) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3824) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3825) #	- The system stack is unchanged.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3826) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3827) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3828) #	When a "Line F Emulator" exception occurs in a system where	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3829) # "FPU Unimplemented" instructions will not be emulated, the exception	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3830) # can occur because then FPU is disabled or the instruction is to be	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3831) # classifed as "Line F". This module determines which case exists and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3832) # calls the appropriate "callout".					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3833) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3834) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3836) 	global		_fpsp_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3837) _fpsp_fline:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3839) # check to see if the FPU is disabled. if so, jump to the OS entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3840) # point for that condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3841) 	cmpi.w		0x6(%sp),&0x402c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3842) 	beq.l		_real_fpu_disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3844) 	bra.l		_real_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3846) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3847) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3848) #	_dcalc_ea(): calc correct <ea> from <ea> stacked on exception	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3849) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3850) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3851) #	inc_areg() - increment an address register			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3852) #	dec_areg() - decrement an address register			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3853) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3854) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3855) #	d0 = number of bytes to adjust <ea> by				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3856) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3857) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3858) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3859) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3860) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3861) # "Dummy" CALCulate Effective Address:					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3862) #	The stacked <ea> for FP unimplemented instructions and opclass	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3863) #	two packed instructions is correct with the exception of...	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3864) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3865) #	1) -(An)   : The register is not updated regardless of size.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3866) #		     Also, for extended precision and packed, the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3867) #		     stacked <ea> value is 8 bytes too big		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3868) #	2) (An)+   : The register is not updated.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3869) #	3) #<data> : The upper longword of the immediate operand is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3870) #		     stacked b,w,l and s sizes are completely stacked.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3871) #		     d,x, and p are not.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3872) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3873) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3875) 	global		_dcalc_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3876) _dcalc_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3877) 	mov.l		%d0, %a0		# move # bytes to %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3879) 	mov.b		1+EXC_OPWORD(%a6), %d0	# fetch opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3880) 	mov.l		%d0, %d1		# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3882) 	andi.w		&0x38, %d0		# extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3883) 	andi.l		&0x7, %d1		# extract reg  field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3885) 	cmpi.b		%d0,&0x18		# is mode (An)+ ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3886) 	beq.b		dcea_pi			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3888) 	cmpi.b		%d0,&0x20		# is mode -(An) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3889) 	beq.b		dcea_pd			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3891) 	or.w		%d1,%d0			# concat mode,reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3892) 	cmpi.b		%d0,&0x3c		# is mode #<data>?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3894) 	beq.b		dcea_imm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3896) 	mov.l		EXC_EA(%a6),%a0		# return <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3897) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3899) # need to set immediate data flag here since we'll need to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3900) # an imem_read to fetch this later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3901) dcea_imm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3902) 	mov.b		&immed_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3903) 	lea		([USER_FPIAR,%a6],0x4),%a0 # no; return <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3904) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3906) # here, the <ea> is stacked correctly. however, we must update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3907) # address register...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3908) dcea_pi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3909) 	mov.l		%a0,%d0			# pass amt to inc by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3910) 	bsr.l		inc_areg		# inc addr register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3912) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3913) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3915) # the <ea> is stacked correctly for all but extended and packed which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3916) # the <ea>s are 8 bytes too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3917) # it would make no sense to have a pre-decrement to a7 in supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3918) # mode so we don't even worry about this tricky case here : )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3919) dcea_pd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3920) 	mov.l		%a0,%d0			# pass amt to dec by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3921) 	bsr.l		dec_areg		# dec addr register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3923) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3925) 	cmpi.b		%d0,&0xc		# is opsize ext or packed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3926) 	beq.b		dcea_pd2		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3927) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3928) dcea_pd2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3929) 	sub.l		&0x8,%a0		# correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3930) 	mov.l		%a0,EXC_EA(%a6)		# put correct <ea> on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3931) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3933) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3934) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3935) #	_calc_ea_fout(): calculate correct stacked <ea> for extended	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3936) #			 and packed data opclass 3 operations.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3937) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3938) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3939) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3940) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3941) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3942) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3943) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3944) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3945) #	a0 = return correct effective address				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3946) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3947) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3948) #	For opclass 3 extended and packed data operations, the <ea>	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3949) # stacked for the exception is incorrect for -(an) and (an)+ addressing	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3950) # modes. Also, while we're at it, the index register itself must get	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3951) # updated.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3952) #	So, for -(an), we must subtract 8 off of the stacked <ea> value	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3953) # and return that value as the correct <ea> and store that value in An.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3954) # For (an)+, the stacked <ea> is correct but we must adjust An by +12.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3955) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3956) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3958) # This calc_ea is currently used to retrieve the correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3959) # for fmove outs of type extended and packed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3960) 	global		_calc_ea_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3961) _calc_ea_fout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3962) 	mov.b		1+EXC_OPWORD(%a6),%d0	# fetch opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3963) 	mov.l		%d0,%d1			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3965) 	andi.w		&0x38,%d0		# extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3966) 	andi.l		&0x7,%d1		# extract reg  field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3968) 	cmpi.b		%d0,&0x18		# is mode (An)+ ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3969) 	beq.b		ceaf_pi			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3971) 	cmpi.b		%d0,&0x20		# is mode -(An) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3972) 	beq.w		ceaf_pd			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3974) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3975) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3977) # (An)+ : extended and packed fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3978) #	: stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3979) #	: "An" not updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3980) ceaf_pi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3981) 	mov.w		(tbl_ceaf_pi.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3982) 	mov.l		EXC_EA(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3983) 	jmp		(tbl_ceaf_pi.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3985) 	swbeg		&0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3986) tbl_ceaf_pi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3987) 	short		ceaf_pi0 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3988) 	short		ceaf_pi1 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3989) 	short		ceaf_pi2 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3990) 	short		ceaf_pi3 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3991) 	short		ceaf_pi4 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3992) 	short		ceaf_pi5 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3993) 	short		ceaf_pi6 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3994) 	short		ceaf_pi7 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3996) ceaf_pi0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3997) 	addi.l		&0xc,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3998) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3999) ceaf_pi1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4000) 	addi.l		&0xc,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4001) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4002) ceaf_pi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4003) 	add.l		&0xc,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4004) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4005) ceaf_pi3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4006) 	add.l		&0xc,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4007) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4008) ceaf_pi4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4009) 	add.l		&0xc,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4010) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4011) ceaf_pi5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4012) 	add.l		&0xc,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4013) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4014) ceaf_pi6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4015) 	addi.l		&0xc,EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4016) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4017) ceaf_pi7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4018) 	mov.b		&mia7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4019) 	addi.l		&0xc,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4020) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4022) # -(An) : extended and packed fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4023) #	: stacked <ea> = actual <ea> + 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4024) #	: "An" not updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4025) ceaf_pd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4026) 	mov.w		(tbl_ceaf_pd.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4027) 	mov.l		EXC_EA(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4028) 	sub.l		&0x8,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4029) 	sub.l		&0x8,EXC_EA(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4030) 	jmp		(tbl_ceaf_pd.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4032) 	swbeg		&0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4033) tbl_ceaf_pd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4034) 	short		ceaf_pd0 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4035) 	short		ceaf_pd1 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4036) 	short		ceaf_pd2 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4037) 	short		ceaf_pd3 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4038) 	short		ceaf_pd4 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4039) 	short		ceaf_pd5 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4040) 	short		ceaf_pd6 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4041) 	short		ceaf_pd7 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4043) ceaf_pd0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4044) 	mov.l		%a0,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4045) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4046) ceaf_pd1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4047) 	mov.l		%a0,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4048) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4049) ceaf_pd2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4050) 	mov.l		%a0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4051) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4052) ceaf_pd3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4053) 	mov.l		%a0,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4054) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4055) ceaf_pd4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4056) 	mov.l		%a0,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4057) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4058) ceaf_pd5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4059) 	mov.l		%a0,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4060) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4061) ceaf_pd6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4062) 	mov.l		%a0,EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4063) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4064) ceaf_pd7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4065) 	mov.l		%a0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4066) 	mov.b		&mda7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4067) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4069) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4070) # This table holds the offsets of the emulation routines for each individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4071) # math operation relative to the address of this table. Included are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4072) # routines like fadd/fmul/fabs. The transcendentals ARE NOT. This is because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4073) # this table is for the version if the 060FPSP without transcendentals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4074) # The location within the table is determined by the extension bits of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4075) # operation longword.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4076) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4078) 	swbeg		&109
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4079) tbl_unsupp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4080) 	long		fin		- tbl_unsupp	# 00: fmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4081) 	long		fint		- tbl_unsupp	# 01: fint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4082) 	long		tbl_unsupp	- tbl_unsupp	# 02: fsinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4083) 	long		fintrz		- tbl_unsupp	# 03: fintrz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4084) 	long		fsqrt		- tbl_unsupp	# 04: fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4085) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4086) 	long		tbl_unsupp	- tbl_unsupp	# 06: flognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4087) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4088) 	long		tbl_unsupp	- tbl_unsupp	# 08: fetoxm1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4089) 	long		tbl_unsupp	- tbl_unsupp	# 09: ftanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4090) 	long		tbl_unsupp	- tbl_unsupp	# 0a: fatan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4091) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4092) 	long		tbl_unsupp	- tbl_unsupp	# 0c: fasin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4093) 	long		tbl_unsupp	- tbl_unsupp	# 0d: fatanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4094) 	long		tbl_unsupp	- tbl_unsupp	# 0e: fsin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4095) 	long		tbl_unsupp	- tbl_unsupp	# 0f: ftan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4096) 	long		tbl_unsupp	- tbl_unsupp	# 10: fetox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4097) 	long		tbl_unsupp	- tbl_unsupp	# 11: ftwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4098) 	long		tbl_unsupp	- tbl_unsupp	# 12: ftentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4099) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4100) 	long		tbl_unsupp	- tbl_unsupp	# 14: flogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4101) 	long		tbl_unsupp	- tbl_unsupp	# 15: flog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4102) 	long		tbl_unsupp	- tbl_unsupp	# 16: flog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4103) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4104) 	long		fabs		- tbl_unsupp	# 18: fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4105) 	long		tbl_unsupp	- tbl_unsupp	# 19: fcosh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4106) 	long		fneg		- tbl_unsupp	# 1a: fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4107) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4108) 	long		tbl_unsupp	- tbl_unsupp	# 1c: facos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4109) 	long		tbl_unsupp	- tbl_unsupp	# 1d: fcos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4110) 	long		tbl_unsupp	- tbl_unsupp	# 1e: fgetexp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4111) 	long		tbl_unsupp	- tbl_unsupp	# 1f: fgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4112) 	long		fdiv		- tbl_unsupp	# 20: fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4113) 	long		tbl_unsupp	- tbl_unsupp	# 21: fmod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4114) 	long		fadd		- tbl_unsupp	# 22: fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4115) 	long		fmul		- tbl_unsupp	# 23: fmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4116) 	long		fsgldiv		- tbl_unsupp	# 24: fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4117) 	long		tbl_unsupp	- tbl_unsupp	# 25: frem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4118) 	long		tbl_unsupp	- tbl_unsupp	# 26: fscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4119) 	long		fsglmul		- tbl_unsupp	# 27: fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4120) 	long		fsub		- tbl_unsupp	# 28: fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4121) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4122) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4123) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4124) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4125) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4126) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4127) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4128) 	long		tbl_unsupp	- tbl_unsupp	# 30: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4129) 	long		tbl_unsupp	- tbl_unsupp	# 31: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4130) 	long		tbl_unsupp	- tbl_unsupp	# 32: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4131) 	long		tbl_unsupp	- tbl_unsupp	# 33: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4132) 	long		tbl_unsupp	- tbl_unsupp	# 34: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4133) 	long		tbl_unsupp	- tbl_unsupp	# 35: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4134) 	long		tbl_unsupp	- tbl_unsupp	# 36: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4135) 	long		tbl_unsupp	- tbl_unsupp	# 37: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4136) 	long		fcmp		- tbl_unsupp	# 38: fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4137) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4138) 	long		ftst		- tbl_unsupp	# 3a: ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4139) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4140) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4141) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4142) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4143) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4144) 	long		fsin		- tbl_unsupp	# 40: fsmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4145) 	long		fssqrt		- tbl_unsupp	# 41: fssqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4146) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4147) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4148) 	long		fdin		- tbl_unsupp	# 44: fdmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4149) 	long		fdsqrt		- tbl_unsupp	# 45: fdsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4150) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4151) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4152) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4153) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4154) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4155) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4156) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4157) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4158) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4159) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4160) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4161) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4162) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4163) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4164) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4165) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4166) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4167) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4168) 	long		fsabs		- tbl_unsupp	# 58: fsabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4169) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4170) 	long		fsneg		- tbl_unsupp	# 5a: fsneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4171) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4172) 	long		fdabs		- tbl_unsupp	# 5c: fdabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4173) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4174) 	long		fdneg		- tbl_unsupp	# 5e: fdneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4175) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4176) 	long		fsdiv		- tbl_unsupp	# 60: fsdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4177) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4178) 	long		fsadd		- tbl_unsupp	# 62: fsadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4179) 	long		fsmul		- tbl_unsupp	# 63: fsmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4180) 	long		fddiv		- tbl_unsupp	# 64: fddiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4181) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4182) 	long		fdadd		- tbl_unsupp	# 66: fdadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4183) 	long		fdmul		- tbl_unsupp	# 67: fdmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4184) 	long		fssub		- tbl_unsupp	# 68: fssub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4185) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4186) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4187) 	long		tbl_unsupp	- tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4188) 	long		fdsub		- tbl_unsupp	# 6c: fdsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4190) #################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4191) # Add this here so non-fp modules can compile.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4192) # (smovcr is called from fpsp_inex.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4193) 	global		smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4194) smovcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4195) 	bra.b		smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4197) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4198) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4199) #	fmovm_dynamic(): emulate "fmovm" dynamic instruction		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4200) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4201) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4202) #	fetch_dreg() - fetch data register				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4203) #	{i,d,}mem_read() - fetch data from memory			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4204) #	_mem_write() - write data to memory				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4205) #	iea_iacc() - instruction memory access error occurred		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4206) #	iea_dacc() - data memory access error occurred			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4207) #	restore() - restore An index regs if access error occurred	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4208) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4209) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4210) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4211) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4212) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4213) #	If instr is "fmovm Dn,-(A7)" from supervisor mode,		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4214) #		d0 = size of dump					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4215) #		d1 = Dn							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4216) #	Else if instruction access error,				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4217) #		d0 = FSLW						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4218) #	Else if data access error,					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4219) #		d0 = FSLW						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4220) #		a0 = address of fault					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4221) #	Else								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4222) #		none.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4223) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4224) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4225) #	The effective address must be calculated since this is entered	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4226) # from an "Unimplemented Effective Address" exception handler. So, we	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4227) # have our own fcalc_ea() routine here. If an access error is flagged	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4228) # by a _{i,d,}mem_read() call, we must exit through the special		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4229) # handler.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4230) #	The data register is determined and its value loaded to get the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4231) # string of FP registers affected. This value is used as an index into	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4232) # a lookup table such that we can determine the number of bytes		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4233) # involved.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4234) #	If the instruction is "fmovm.x <ea>,Dn", a _mem_read() is used	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4235) # to read in all FP values. Again, _mem_read() may fail and require a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4236) # special exit.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4237) #	If the instruction is "fmovm.x DN,<ea>", a _mem_write() is used	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4238) # to write all FP values. _mem_write() may also fail.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4239) #	If the instruction is "fmovm.x DN,-(a7)" from supervisor mode,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4240) # then we return the size of the dump and the string to the caller	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4241) # so that the move can occur outside of this routine. This special	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4242) # case is required so that moves to the system stack are handled	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4243) # correctly.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4244) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4245) # DYNAMIC:								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4246) #	fmovm.x	dn, <ea>						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4247) #	fmovm.x	<ea>, dn						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4248) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4249) #	      <WORD 1>		      <WORD2>				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4250) #	1111 0010 00 |<ea>|	11@& 1000 0$$$ 0000			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4251) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4252) #	& = (0): predecrement addressing mode				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4253) #	    (1): postincrement or control addressing mode		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4254) #	@ = (0): move listed regs from memory to the FPU		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4255) #	    (1): move listed regs from the FPU to memory		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4256) #	$$$    : index of data register holding reg select mask		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4257) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4258) # NOTES:								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4259) #	If the data register holds a zero, then the			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4260) #	instruction is a nop.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4261) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4262) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4264) 	global		fmovm_dynamic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4265) fmovm_dynamic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4267) # extract the data register in which the bit string resides...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4268) 	mov.b		1+EXC_EXTWORD(%a6),%d1	# fetch extword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4269) 	andi.w		&0x70,%d1		# extract reg bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4270) 	lsr.b		&0x4,%d1		# shift into lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4272) # fetch the bit string into d0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4273) 	bsr.l		fetch_dreg		# fetch reg string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4275) 	andi.l		&0x000000ff,%d0		# keep only lo byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4277) 	mov.l		%d0,-(%sp)		# save strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4278) 	mov.b		(tbl_fmovm_size.w,%pc,%d0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4279) 	mov.l		%d0,-(%sp)		# save size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4280) 	bsr.l		fmovm_calc_ea		# calculate <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4281) 	mov.l		(%sp)+,%d0		# restore size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4282) 	mov.l		(%sp)+,%d1		# restore strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4284) # if the bit string is a zero, then the operation is a no-op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4285) # but, make sure that we've calculated ea and advanced the opword pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4286) 	beq.w		fmovm_data_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4288) # separate move ins from move outs...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4289) 	btst		&0x5,EXC_EXTWORD(%a6)	# is it a move in or out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4290) 	beq.w		fmovm_data_in		# it's a move out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4292) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4293) # MOVE OUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4294) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4295) fmovm_data_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4296) 	btst		&0x4,EXC_EXTWORD(%a6)	# control or predecrement?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4297) 	bne.w		fmovm_out_ctrl		# control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4299) ############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4300) fmovm_out_predec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4301) # for predecrement mode, the bit string is the opposite of both control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4302) # operations and postincrement mode. (bit7 = FP7 ... bit0 = FP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4303) # here, we convert it to be just like the others...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4304) 	mov.b		(tbl_fmovm_convert.w,%pc,%d1.w*1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4306) 	btst		&0x5,EXC_SR(%a6)	# user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4307) 	beq.b		fmovm_out_ctrl		# user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4309) fmovm_out_predec_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4310) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4311) 	bne.b		fmovm_out_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4313) # the operation was unfortunately an: fmovm.x dn,-(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4314) # called from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4315) # we're also passing "size" and "strg" back to the calling routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4316) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4318) ############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4319) fmovm_out_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4320) 	mov.l		%a0,%a1			# move <ea> to a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4322) 	sub.l		%d0,%sp			# subtract size of dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4323) 	lea		(%sp),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4325) 	tst.b		%d1			# should FP0 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4326) 	bpl.b		fmovm_out_ctrl_fp1	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4328) 	mov.l		0x0+EXC_FP0(%a6),(%a0)+	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4329) 	mov.l		0x4+EXC_FP0(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4330) 	mov.l		0x8+EXC_FP0(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4332) fmovm_out_ctrl_fp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4333) 	lsl.b		&0x1,%d1		# should FP1 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4334) 	bpl.b		fmovm_out_ctrl_fp2	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4336) 	mov.l		0x0+EXC_FP1(%a6),(%a0)+	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4337) 	mov.l		0x4+EXC_FP1(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4338) 	mov.l		0x8+EXC_FP1(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4340) fmovm_out_ctrl_fp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4341) 	lsl.b		&0x1,%d1		# should FP2 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4342) 	bpl.b		fmovm_out_ctrl_fp3	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4344) 	fmovm.x		&0x20,(%a0)		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4345) 	add.l		&0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4347) fmovm_out_ctrl_fp3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4348) 	lsl.b		&0x1,%d1		# should FP3 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4349) 	bpl.b		fmovm_out_ctrl_fp4	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4351) 	fmovm.x		&0x10,(%a0)		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4352) 	add.l		&0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4354) fmovm_out_ctrl_fp4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4355) 	lsl.b		&0x1,%d1		# should FP4 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4356) 	bpl.b		fmovm_out_ctrl_fp5	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4358) 	fmovm.x		&0x08,(%a0)		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4359) 	add.l		&0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4361) fmovm_out_ctrl_fp5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4362) 	lsl.b		&0x1,%d1		# should FP5 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4363) 	bpl.b		fmovm_out_ctrl_fp6	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4365) 	fmovm.x		&0x04,(%a0)		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4366) 	add.l		&0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4368) fmovm_out_ctrl_fp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4369) 	lsl.b		&0x1,%d1		# should FP6 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4370) 	bpl.b		fmovm_out_ctrl_fp7	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4372) 	fmovm.x		&0x02,(%a0)		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4373) 	add.l		&0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4375) fmovm_out_ctrl_fp7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4376) 	lsl.b		&0x1,%d1		# should FP7 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4377) 	bpl.b		fmovm_out_ctrl_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4379) 	fmovm.x		&0x01,(%a0)		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4380) 	add.l		&0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4382) fmovm_out_ctrl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4383) 	mov.l		%a1,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4385) 	lea		(%sp),%a0		# pass: supervisor src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4386) 	mov.l		%d0,-(%sp)		# save size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4387) 	bsr.l		_dmem_write		# copy data to user mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4389) 	mov.l		(%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4390) 	add.l		%d0,%sp			# clear fpreg data from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4392) 	tst.l		%d1			# did dstore err?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4393) 	bne.w		fmovm_out_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4395) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4397) ############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4398) # MOVE IN: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4399) ############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4400) fmovm_data_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4401) 	mov.l		%a0,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4403) 	sub.l		%d0,%sp			# make room for fpregs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4404) 	lea		(%sp),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4406) 	mov.l		%d1,-(%sp)		# save bit string for later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4407) 	mov.l		%d0,-(%sp)		# save # of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4409) 	bsr.l		_dmem_read		# copy data from user mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4411) 	mov.l		(%sp)+,%d0		# retrieve # of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4413) 	tst.l		%d1			# did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4414) 	bne.w		fmovm_in_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4416) 	mov.l		(%sp)+,%d1		# load bit string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4418) 	lea		(%sp),%a0		# addr of stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4420) 	tst.b		%d1			# should FP0 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4421) 	bpl.b		fmovm_data_in_fp1	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4423) 	mov.l		(%a0)+,0x0+EXC_FP0(%a6)	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4424) 	mov.l		(%a0)+,0x4+EXC_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4425) 	mov.l		(%a0)+,0x8+EXC_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4427) fmovm_data_in_fp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4428) 	lsl.b		&0x1,%d1		# should FP1 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4429) 	bpl.b		fmovm_data_in_fp2	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4431) 	mov.l		(%a0)+,0x0+EXC_FP1(%a6)	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4432) 	mov.l		(%a0)+,0x4+EXC_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4433) 	mov.l		(%a0)+,0x8+EXC_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4435) fmovm_data_in_fp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4436) 	lsl.b		&0x1,%d1		# should FP2 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4437) 	bpl.b		fmovm_data_in_fp3	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4439) 	fmovm.x		(%a0)+,&0x20		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4441) fmovm_data_in_fp3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4442) 	lsl.b		&0x1,%d1		# should FP3 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4443) 	bpl.b		fmovm_data_in_fp4	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4445) 	fmovm.x		(%a0)+,&0x10		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4447) fmovm_data_in_fp4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4448) 	lsl.b		&0x1,%d1		# should FP4 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4449) 	bpl.b		fmovm_data_in_fp5	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4451) 	fmovm.x		(%a0)+,&0x08		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4453) fmovm_data_in_fp5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4454) 	lsl.b		&0x1,%d1		# should FP5 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4455) 	bpl.b		fmovm_data_in_fp6	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4457) 	fmovm.x		(%a0)+,&0x04		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4459) fmovm_data_in_fp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4460) 	lsl.b		&0x1,%d1		# should FP6 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4461) 	bpl.b		fmovm_data_in_fp7	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4463) 	fmovm.x		(%a0)+,&0x02		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4465) fmovm_data_in_fp7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4466) 	lsl.b		&0x1,%d1		# should FP7 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4467) 	bpl.b		fmovm_data_in_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4469) 	fmovm.x		(%a0)+,&0x01		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4471) fmovm_data_in_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4472) 	add.l		%d0,%sp			# remove fpregs from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4473) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4475) #####################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4477) fmovm_data_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4478) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4480) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4482) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4483) # table indexed by the operation's bit string that gives the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4484) # of bytes that will be moved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4485) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4486) # number of bytes = (# of 1's in bit string) * 12(bytes/fpreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4487) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4488) tbl_fmovm_size:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4489) 	byte	0x00,0x0c,0x0c,0x18,0x0c,0x18,0x18,0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4490) 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4491) 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4492) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4493) 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4494) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4495) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4496) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4497) 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4498) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4499) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4500) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4501) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4502) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4503) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4504) 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4505) 	byte	0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4506) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4507) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4508) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4509) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4510) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4511) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4512) 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4513) 	byte	0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4514) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4515) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4516) 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4517) 	byte	0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4518) 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4519) 	byte	0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4520) 	byte	0x3c,0x48,0x48,0x54,0x48,0x54,0x54,0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4522) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4523) # table to convert a pre-decrement bit string into a post-increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4524) # or control bit string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4525) # ex:	0x00	==>	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4526) #	0x01	==>	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4527) #	0x02	==>	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4528) #		.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4529) #		.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4530) #	0xfd	==>	0xbf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4531) #	0xfe	==>	0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4532) #	0xff	==>	0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4533) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4534) tbl_fmovm_convert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4535) 	byte	0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4536) 	byte	0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4537) 	byte	0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4538) 	byte	0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4539) 	byte	0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4540) 	byte	0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4541) 	byte	0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4542) 	byte	0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4543) 	byte	0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4544) 	byte	0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4545) 	byte	0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4546) 	byte	0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4547) 	byte	0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4548) 	byte	0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4549) 	byte	0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4550) 	byte	0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4551) 	byte	0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4552) 	byte	0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4553) 	byte	0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4554) 	byte	0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4555) 	byte	0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4556) 	byte	0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4557) 	byte	0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4558) 	byte	0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4559) 	byte	0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4560) 	byte	0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4561) 	byte	0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4562) 	byte	0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4563) 	byte	0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4564) 	byte	0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4565) 	byte	0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4566) 	byte	0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4568) 	global		fmovm_calc_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4569) ###############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4570) # _fmovm_calc_ea: calculate effective address #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4571) ###############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4572) fmovm_calc_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4573) 	mov.l		%d0,%a0			# move # bytes to a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4575) # currently, MODE and REG are taken from the EXC_OPWORD. this could be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4576) # easily changed if they were inputs passed in registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4577) 	mov.w		EXC_OPWORD(%a6),%d0	# fetch opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4578) 	mov.w		%d0,%d1			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4580) 	andi.w		&0x3f,%d0		# extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4581) 	andi.l		&0x7,%d1		# extract reg  field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4583) # jump to the corresponding function for each {MODE,REG} pair.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4584) 	mov.w		(tbl_fea_mode.b,%pc,%d0.w*2),%d0 # fetch jmp distance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4585) 	jmp		(tbl_fea_mode.b,%pc,%d0.w*1) # jmp to correct ea mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4587) 	swbeg		&64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4588) tbl_fea_mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4589) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4590) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4591) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4592) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4593) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4594) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4595) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4596) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4598) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4599) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4600) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4601) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4602) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4603) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4604) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4605) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4607) 	short		faddr_ind_a0	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4608) 	short		faddr_ind_a1	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4609) 	short		faddr_ind_a2	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4610) 	short		faddr_ind_a3	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4611) 	short		faddr_ind_a4	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4612) 	short		faddr_ind_a5	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4613) 	short		faddr_ind_a6	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4614) 	short		faddr_ind_a7	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4616) 	short		faddr_ind_p_a0	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4617) 	short		faddr_ind_p_a1	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4618) 	short		faddr_ind_p_a2	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4619) 	short		faddr_ind_p_a3	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4620) 	short		faddr_ind_p_a4	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4621) 	short		faddr_ind_p_a5	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4622) 	short		faddr_ind_p_a6	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4623) 	short		faddr_ind_p_a7	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4625) 	short		faddr_ind_m_a0	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4626) 	short		faddr_ind_m_a1	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4627) 	short		faddr_ind_m_a2	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4628) 	short		faddr_ind_m_a3	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4629) 	short		faddr_ind_m_a4	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4630) 	short		faddr_ind_m_a5	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4631) 	short		faddr_ind_m_a6	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4632) 	short		faddr_ind_m_a7	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4634) 	short		faddr_ind_disp_a0	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4635) 	short		faddr_ind_disp_a1	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4636) 	short		faddr_ind_disp_a2	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4637) 	short		faddr_ind_disp_a3	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4638) 	short		faddr_ind_disp_a4	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4639) 	short		faddr_ind_disp_a5	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4640) 	short		faddr_ind_disp_a6	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4641) 	short		faddr_ind_disp_a7	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4643) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4644) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4645) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4646) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4647) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4648) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4649) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4650) 	short		faddr_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4652) 	short		fabs_short	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4653) 	short		fabs_long	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4654) 	short		fpc_ind		-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4655) 	short		fpc_ind_ext	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4656) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4657) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4658) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4659) 	short		tbl_fea_mode	-	tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4661) ###################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4662) # Address register indirect: (An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4663) ###################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4664) faddr_ind_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4665) 	mov.l		EXC_DREGS+0x8(%a6),%a0	# Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4666) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4668) faddr_ind_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4669) 	mov.l		EXC_DREGS+0xc(%a6),%a0	# Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4670) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4672) faddr_ind_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4673) 	mov.l		%a2,%a0			# Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4674) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4676) faddr_ind_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4677) 	mov.l		%a3,%a0			# Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4678) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4680) faddr_ind_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4681) 	mov.l		%a4,%a0			# Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4682) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4684) faddr_ind_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4685) 	mov.l		%a5,%a0			# Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4686) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4688) faddr_ind_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4689) 	mov.l		(%a6),%a0		# Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4690) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4692) faddr_ind_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4693) 	mov.l		EXC_A7(%a6),%a0		# Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4694) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4696) #####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4697) # Address register indirect w/ postincrement: (An)+ #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4698) #####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4699) faddr_ind_p_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4700) 	mov.l		EXC_DREGS+0x8(%a6),%d0	# Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4701) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4702) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4703) 	mov.l		%d1,EXC_DREGS+0x8(%a6)	# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4704) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4705) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4707) faddr_ind_p_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4708) 	mov.l		EXC_DREGS+0xc(%a6),%d0	# Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4709) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4710) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4711) 	mov.l		%d1,EXC_DREGS+0xc(%a6)	# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4712) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4713) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4715) faddr_ind_p_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4716) 	mov.l		%a2,%d0			# Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4717) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4718) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4719) 	mov.l		%d1,%a2			# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4720) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4721) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4723) faddr_ind_p_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4724) 	mov.l		%a3,%d0			# Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4725) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4726) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4727) 	mov.l		%d1,%a3			# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4728) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4729) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4731) faddr_ind_p_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4732) 	mov.l		%a4,%d0			# Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4733) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4734) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4735) 	mov.l		%d1,%a4			# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4736) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4737) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4739) faddr_ind_p_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4740) 	mov.l		%a5,%d0			# Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4741) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4742) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4743) 	mov.l		%d1,%a5			# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4744) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4745) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4747) faddr_ind_p_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4748) 	mov.l		(%a6),%d0		# Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4749) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4750) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4751) 	mov.l		%d1,(%a6)		# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4752) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4753) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4755) faddr_ind_p_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4756) 	mov.b		&mia7_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4758) 	mov.l		EXC_A7(%a6),%d0		# Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4759) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4760) 	add.l		%a0,%d1			# Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4761) 	mov.l		%d1,EXC_A7(%a6)		# Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4762) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4763) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4765) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4766) # Address register indirect w/ predecrement: -(An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4767) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4768) faddr_ind_m_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4769) 	mov.l		EXC_DREGS+0x8(%a6),%d0	# Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4770) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4771) 	mov.l		%d0,EXC_DREGS+0x8(%a6)	# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4772) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4773) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4775) faddr_ind_m_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4776) 	mov.l		EXC_DREGS+0xc(%a6),%d0	# Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4777) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4778) 	mov.l		%d0,EXC_DREGS+0xc(%a6)	# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4779) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4780) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4782) faddr_ind_m_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4783) 	mov.l		%a2,%d0			# Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4784) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4785) 	mov.l		%d0,%a2			# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4786) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4787) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4789) faddr_ind_m_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4790) 	mov.l		%a3,%d0			# Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4791) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4792) 	mov.l		%d0,%a3			# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4793) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4794) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4796) faddr_ind_m_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4797) 	mov.l		%a4,%d0			# Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4798) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4799) 	mov.l		%d0,%a4			# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4800) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4801) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4803) faddr_ind_m_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4804) 	mov.l		%a5,%d0			# Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4805) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4806) 	mov.l		%d0,%a5			# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4807) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4808) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4810) faddr_ind_m_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4811) 	mov.l		(%a6),%d0		# Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4812) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4813) 	mov.l		%d0,(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4814) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4815) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4817) faddr_ind_m_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4818) 	mov.b		&mda7_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4820) 	mov.l		EXC_A7(%a6),%d0		# Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4821) 	sub.l		%a0,%d0			# Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4822) 	mov.l		%d0,EXC_A7(%a6)		# Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4823) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4824) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4826) ########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4827) # Address register indirect w/ displacement: (d16, An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4828) ########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4829) faddr_ind_disp_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4830) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4831) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4832) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4834) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4835) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4837) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4839) 	add.l		EXC_DREGS+0x8(%a6),%a0	# a0 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4840) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4842) faddr_ind_disp_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4843) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4844) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4845) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4847) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4848) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4850) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4852) 	add.l		EXC_DREGS+0xc(%a6),%a0	# a1 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4853) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4855) faddr_ind_disp_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4856) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4857) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4858) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4860) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4861) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4863) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4865) 	add.l		%a2,%a0			# a2 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4866) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4868) faddr_ind_disp_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4869) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4870) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4871) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4873) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4874) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4876) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4878) 	add.l		%a3,%a0			# a3 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4879) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4881) faddr_ind_disp_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4882) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4883) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4884) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4886) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4887) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4889) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4891) 	add.l		%a4,%a0			# a4 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4892) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4894) faddr_ind_disp_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4895) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4896) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4897) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4899) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4900) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4902) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4904) 	add.l		%a5,%a0			# a5 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4905) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4907) faddr_ind_disp_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4908) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4909) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4910) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4912) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4913) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4915) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4917) 	add.l		(%a6),%a0		# a6 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4918) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4920) faddr_ind_disp_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4921) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4922) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4923) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4925) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4926) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4928) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4930) 	add.l		EXC_A7(%a6),%a0		# a7 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4931) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4933) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4934) # Address register indirect w/ index(8-bit displacement): (d8, An, Xn) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4935) #    "       "         "    w/   "  (base displacement): (bd, An, Xn)  #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4936) # Memory indirect postindexed: ([bd, An], Xn, od)		       #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4937) # Memory indirect preindexed: ([bd, An, Xn], od)		       #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4938) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4939) faddr_ind_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4940) 	addq.l		&0x8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4941) 	bsr.l		fetch_dreg		# fetch base areg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4942) 	mov.l		%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4944) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4945) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4946) 	bsr.l		_imem_read_word		# fetch extword in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4948) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4949) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4951) 	mov.l		(%sp)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4953) 	btst		&0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4954) 	bne.w		fcalc_mem_ind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4956) 	mov.l		%d0,L_SCR1(%a6)		# hold opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4958) 	mov.l		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4959) 	rol.w		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4960) 	andi.w		&0xf,%d1		# extract index regno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4962) # count on fetch_dreg() not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4963) 	bsr.l		fetch_dreg		# fetch index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4965) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4966) 	mov.l		L_SCR1(%a6),%d2		# fetch opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4968) 	btst		&0xb,%d2		# is it word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4969) 	bne.b		faii8_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4970) 	ext.l		%d0			# sign extend word index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4971) faii8_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4972) 	mov.l		%d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4973) 	rol.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4974) 	andi.l		&0x3,%d1		# extract scale value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4976) 	lsl.l		%d1,%d0			# shift index by scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4978) 	extb.l		%d2			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4979) 	add.l		%d2,%d0			# index + disp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4980) 	add.l		%d0,%a0			# An + (index + disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4982) 	mov.l		(%sp)+,%d2		# restore old d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4983) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4985) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4986) # Absolute short: (XXX).W #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4987) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4988) fabs_short:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4989) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4990) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4991) 	bsr.l		_imem_read_word		# fetch short address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4993) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4994) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4996) 	mov.w		%d0,%a0			# return <ea> in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4997) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4999) ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5000) # Absolute long: (XXX).L #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5001) ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5002) fabs_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5003) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5004) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5005) 	bsr.l		_imem_read_long		# fetch long address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5007) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5008) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5010) 	mov.l		%d0,%a0			# return <ea> in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5011) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5013) #######################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5014) # Program counter indirect w/ displacement: (d16, PC) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5015) #######################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5016) fpc_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5017) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5018) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5019) 	bsr.l		_imem_read_word		# fetch word displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5021) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5022) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5024) 	mov.w		%d0,%a0			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5026) 	add.l		EXC_EXTWPTR(%a6),%a0	# pc + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5028) # _imem_read_word() increased the extwptr by 2. need to adjust here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5029) 	subq.l		&0x2,%a0		# adjust <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5030) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5032) ##########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5033) # PC indirect w/ index(8-bit displacement): (d8, PC, An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5034) # "     "     w/   "  (base displacement): (bd, PC, An)  #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5035) # PC memory indirect postindexed: ([bd, PC], Xn, od)     #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5036) # PC memory indirect preindexed: ([bd, PC, Xn], od)      #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5037) ##########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5038) fpc_ind_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5039) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5040) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5041) 	bsr.l		_imem_read_word		# fetch ext word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5043) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5044) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5046) 	mov.l		EXC_EXTWPTR(%a6),%a0	# put base in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5047) 	subq.l		&0x2,%a0		# adjust base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5049) 	btst		&0x8,%d0		# is disp only 8 bits?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5050) 	bne.w		fcalc_mem_ind		# calc memory indirect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5052) 	mov.l		%d0,L_SCR1(%a6)		# store opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5054) 	mov.l		%d0,%d1			# make extword copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5055) 	rol.w		&0x4,%d1		# rotate reg num into place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5056) 	andi.w		&0xf,%d1		# extract register number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5058) # count on fetch_dreg() not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5059) 	bsr.l		fetch_dreg		# fetch index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5061) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5062) 	mov.l		L_SCR1(%a6),%d2		# fetch opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5064) 	btst		&0xb,%d2		# is index word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5065) 	bne.b		fpii8_long		# long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5066) 	ext.l		%d0			# sign extend word index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5067) fpii8_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5068) 	mov.l		%d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5069) 	rol.w		&0x7,%d1		# rotate scale value into place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5070) 	andi.l		&0x3,%d1		# extract scale value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5072) 	lsl.l		%d1,%d0			# shift index by scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5074) 	extb.l		%d2			# sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5075) 	add.l		%d2,%d0			# disp + index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5076) 	add.l		%d0,%a0			# An + (index + disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5078) 	mov.l		(%sp)+,%d2		# restore temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5079) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5081) # d2 = index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5082) # d3 = base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5083) # d4 = od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5084) # d5 = extword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5085) fcalc_mem_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5086) 	btst		&0x6,%d0		# is the index suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5087) 	beq.b		fcalc_index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5089) 	movm.l		&0x3c00,-(%sp)		# save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5091) 	mov.l		%d0,%d5			# put extword in d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5092) 	mov.l		%a0,%d3			# put base in d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5094) 	clr.l		%d2			# yes, so index = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5095) 	bra.b		fbase_supp_ck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5097) # index:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5098) fcalc_index:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5099) 	mov.l		%d0,L_SCR1(%a6)		# save d0 (opword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5100) 	bfextu		%d0{&16:&4},%d1		# fetch dreg index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5101) 	bsr.l		fetch_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5103) 	movm.l		&0x3c00,-(%sp)		# save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5104) 	mov.l		%d0,%d2			# put index in d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5105) 	mov.l		L_SCR1(%a6),%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5106) 	mov.l		%a0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5108) 	btst		&0xb,%d5		# is index word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5109) 	bne.b		fno_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5110) 	ext.l		%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5112) fno_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5113) 	bfextu		%d5{&21:&2},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5114) 	lsl.l		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5116) # base address (passed as parameter in d3):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5117) # we clear the value here if it should actually be suppressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5118) fbase_supp_ck:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5119) 	btst		&0x7,%d5		# is the bd suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5120) 	beq.b		fno_base_sup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5121) 	clr.l		%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5123) # base displacement:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5124) fno_base_sup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5125) 	bfextu		%d5{&26:&2},%d0		# get bd size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5126) #	beq.l		fmovm_error		# if (size == 0) it's reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5128) 	cmpi.b		%d0,&0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5129) 	blt.b		fno_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5130) 	beq.b		fget_word_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5132) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5133) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5134) 	bsr.l		_imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5136) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5137) 	bne.l		fcea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5139) 	bra.b		fchk_ind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5141) fget_word_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5142) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5143) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5144) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5146) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5147) 	bne.l		fcea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5149) 	ext.l		%d0			# sign extend bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5151) fchk_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5152) 	add.l		%d0,%d3			# base += bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5154) # outer displacement:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5155) fno_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5156) 	bfextu		%d5{&30:&2},%d0		# is od suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5157) 	beq.w		faii_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5159) 	cmpi.b		%d0,&0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5160) 	blt.b		fnull_od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5161) 	beq.b		fword_od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5163) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5164) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5165) 	bsr.l		_imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5167) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5168) 	bne.l		fcea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5170) 	bra.b		fadd_them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5172) fword_od:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5173) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5174) 	addq.l		&0x2,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5175) 	bsr.l		_imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5177) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5178) 	bne.l		fcea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5180) 	ext.l		%d0			# sign extend od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5181) 	bra.b		fadd_them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5183) fnull_od:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5184) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5186) fadd_them:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5187) 	mov.l		%d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5189) 	btst		&0x2,%d5		# pre or post indexing?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5190) 	beq.b		fpre_indexed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5192) 	mov.l		%d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5193) 	bsr.l		_dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5195) 	tst.l		%d1			# did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5196) 	bne.w		fcea_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5198) 	add.l		%d2,%d0			# <ea> += index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5199) 	add.l		%d4,%d0			# <ea> += od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5200) 	bra.b		fdone_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5202) fpre_indexed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5203) 	add.l		%d2,%d3			# preindexing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5204) 	mov.l		%d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5205) 	bsr.l		_dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5207) 	tst.l		%d1			# did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5208) 	bne.w		fcea_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5210) 	add.l		%d4,%d0			# ea += od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5211) 	bra.b		fdone_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5213) faii_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5214) 	add.l		%d2,%d3			# ea = (base + bd) + index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5215) 	mov.l		%d3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5216) fdone_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5217) 	mov.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5219) 	movm.l		(%sp)+,&0x003c		# restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5220) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5222) #########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5223) fcea_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5224) 	mov.l		%d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5226) 	movm.l		(%sp)+,&0x003c		# restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5227) 	mov.w		&0x0101,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5228) 	bra.l		iea_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5230) fcea_iacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5231) 	movm.l		(%sp)+,&0x003c		# restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5232) 	bra.l		iea_iacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5234) fmovm_out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5235) 	bsr.l		restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5236) 	mov.w		&0x00e1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5237) 	bra.b		fmovm_err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5239) fmovm_in_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5240) 	bsr.l		restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5241) 	mov.w		&0x0161,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5243) fmovm_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5244) 	mov.l		L_SCR1(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5245) 	bra.l		iea_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5247) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5248) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5249) #	fmovm_ctrl(): emulate fmovm.l of control registers instr	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5250) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5251) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5252) #	_imem_read_long() - read longword from memory			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5253) #	iea_iacc() - _imem_read_long() failed; error recovery		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5254) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5255) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5256) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5257) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5258) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5259) #	If _imem_read_long() doesn't fail:				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5260) #		USER_FPCR(a6)  = new FPCR value				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5261) #		USER_FPSR(a6)  = new FPSR value				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5262) #		USER_FPIAR(a6) = new FPIAR value			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5263) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5264) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5265) #	Decode the instruction type by looking at the extension word	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5266) # in order to see how many control registers to fetch from memory.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5267) # Fetch them using _imem_read_long(). If this fetch fails, exit through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5268) # the special access error exit handler iea_iacc().			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5269) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5270) # Instruction word decoding:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5271) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5272) #	fmovem.l #<data>, {FPIAR&|FPCR&|FPSR}				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5273) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5274) #		WORD1			WORD2				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5275) #	1111 0010 00 111100	100$ $$00 0000 0000			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5276) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5277) #	$$$ (100): FPCR							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5278) #	    (010): FPSR							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5279) #	    (001): FPIAR						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5280) #	    (000): FPIAR						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5281) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5282) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5284) 	global		fmovm_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5285) fmovm_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5286) 	mov.b		EXC_EXTWORD(%a6),%d0	# fetch reg select bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5287) 	cmpi.b		%d0,&0x9c		# fpcr & fpsr & fpiar ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5288) 	beq.w		fctrl_in_7		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5289) 	cmpi.b		%d0,&0x98		# fpcr & fpsr ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5290) 	beq.w		fctrl_in_6		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5291) 	cmpi.b		%d0,&0x94		# fpcr & fpiar ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5292) 	beq.b		fctrl_in_5		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5294) # fmovem.l #<data>, fpsr/fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5295) fctrl_in_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5296) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5297) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5298) 	bsr.l		_imem_read_long		# fetch FPSR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5300) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5301) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5303) 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5304) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5305) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5306) 	bsr.l		_imem_read_long		# fetch FPIAR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5308) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5309) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5311) 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5312) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5314) # fmovem.l #<data>, fpcr/fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5315) fctrl_in_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5316) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5317) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5318) 	bsr.l		_imem_read_long		# fetch FPCR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5320) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5321) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5323) 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5324) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5325) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5326) 	bsr.l		_imem_read_long		# fetch FPIAR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5328) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5329) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5331) 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5332) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5334) # fmovem.l #<data>, fpcr/fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5335) fctrl_in_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5336) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5337) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5338) 	bsr.l		_imem_read_long		# fetch FPCR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5340) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5341) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5343) 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5344) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5345) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5346) 	bsr.l		_imem_read_long		# fetch FPSR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5348) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5349) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5351) 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5352) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5354) # fmovem.l #<data>, fpcr/fpsr/fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5355) fctrl_in_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5356) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5357) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5358) 	bsr.l		_imem_read_long		# fetch FPCR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5360) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5361) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5363) 	mov.l		%d0,USER_FPCR(%a6)	# store new FPCR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5364) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5365) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5366) 	bsr.l		_imem_read_long		# fetch FPSR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5368) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5369) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5371) 	mov.l		%d0,USER_FPSR(%a6)	# store new FPSR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5372) 	mov.l		EXC_EXTWPTR(%a6),%a0	# fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5373) 	addq.l		&0x4,EXC_EXTWPTR(%a6)	# incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5374) 	bsr.l		_imem_read_long		# fetch FPIAR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5376) 	tst.l		%d1			# did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5377) 	bne.l		iea_iacc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5379) 	mov.l		%d0,USER_FPIAR(%a6)	# store new FPIAR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5380) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5382) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5384) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5385) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5386) #	addsub_scaler2(): scale inputs to fadd/fsub such that no	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5387) #			  OVFL/UNFL exceptions will result		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5388) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5389) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5390) #	norm() - normalize mantissa after adjusting exponent		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5391) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5392) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5393) #	FP_SRC(a6) = fp op1(src)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5394) #	FP_DST(a6) = fp op2(dst)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5395) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5396) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5397) #	FP_SRC(a6) = fp op1 scaled(src)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5398) #	FP_DST(a6) = fp op2 scaled(dst)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5399) #	d0         = scale amount					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5400) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5401) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5402) #	If the DST exponent is > the SRC exponent, set the DST exponent	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5403) # equal to 0x3fff and scale the SRC exponent by the value that the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5404) # DST exponent was scaled by. If the SRC exponent is greater or equal,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5405) # do the opposite. Return this scale factor in d0.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5406) #	If the two exponents differ by > the number of mantissa bits	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5407) # plus two, then set the smallest exponent to a very small value as a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5408) # quick shortcut.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5409) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5410) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5412) 	global		addsub_scaler2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5413) addsub_scaler2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5414) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5415) 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5416) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5417) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5418) 	mov.w		SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5419) 	mov.w		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5420) 	mov.w		%d0,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5421) 	mov.w		%d1,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5423) 	andi.w		&0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5424) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5425) 	mov.w		%d0,L_SCR1(%a6)		# store src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5426) 	mov.w		%d1,2+L_SCR1(%a6)	# store dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5428) 	cmp.w		%d0, %d1		# is src exp >= dst exp?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5429) 	bge.l		src_exp_ge2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5431) # dst exp is >  src exp; scale dst to exp = 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5432) dst_exp_gt2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5433) 	bsr.l		scale_to_zero_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5434) 	mov.l		%d0,-(%sp)		# save scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5436) 	cmpi.b		STAG(%a6),&DENORM	# is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5437) 	bne.b		cmpexp12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5439) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5440) 	bsr.l		norm			# normalize the denorm; result is new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5441) 	neg.w		%d0			# new exp = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5442) 	mov.w		%d0,L_SCR1(%a6)		# inset new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5444) cmpexp12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5445) 	mov.w		2+L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5446) 	subi.w		&mantissalen+2,%d0	# subtract mantissalen+2 from larger exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5448) 	cmp.w		%d0,L_SCR1(%a6)		# is difference >= len(mantissa)+2?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5449) 	bge.b		quick_scale12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5451) 	mov.w		L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5452) 	add.w		0x2(%sp),%d0		# scale src exponent by scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5453) 	mov.w		FP_SCR0_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5454) 	and.w		&0x8000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5455) 	or.w		%d1,%d0			# concat {sgn,new exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5456) 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5458) 	mov.l		(%sp)+,%d0		# return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5459) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5461) quick_scale12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5462) 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# zero src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5463) 	bset		&0x0,1+FP_SCR0_EX(%a6)	# set exp = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5465) 	mov.l		(%sp)+,%d0		# return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5466) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5468) # src exp is >= dst exp; scale src to exp = 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5469) src_exp_ge2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5470) 	bsr.l		scale_to_zero_src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5471) 	mov.l		%d0,-(%sp)		# save scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5473) 	cmpi.b		DTAG(%a6),&DENORM	# is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5474) 	bne.b		cmpexp22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5475) 	lea		FP_SCR1(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5476) 	bsr.l		norm			# normalize the denorm; result is new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5477) 	neg.w		%d0			# new exp = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5478) 	mov.w		%d0,2+L_SCR1(%a6)	# inset new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5480) cmpexp22:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5481) 	mov.w		L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5482) 	subi.w		&mantissalen+2,%d0	# subtract mantissalen+2 from larger exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5484) 	cmp.w		%d0,2+L_SCR1(%a6)	# is difference >= len(mantissa)+2?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5485) 	bge.b		quick_scale22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5487) 	mov.w		2+L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5488) 	add.w		0x2(%sp),%d0		# scale dst exponent by scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5489) 	mov.w		FP_SCR1_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5490) 	andi.w		&0x8000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5491) 	or.w		%d1,%d0			# concat {sgn,new exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5492) 	mov.w		%d0,FP_SCR1_EX(%a6)	# insert new dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5494) 	mov.l		(%sp)+,%d0		# return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5495) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5497) quick_scale22:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5498) 	andi.w		&0x8000,FP_SCR1_EX(%a6)	# zero dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5499) 	bset		&0x0,1+FP_SCR1_EX(%a6)	# set exp = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5501) 	mov.l		(%sp)+,%d0		# return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5502) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5504) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5506) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5507) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5508) #	scale_to_zero_src(): scale the exponent of extended precision	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5509) #			     value at FP_SCR0(a6).			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5510) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5511) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5512) #	norm() - normalize the mantissa if the operand was a DENORM	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5513) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5514) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5515) #	FP_SCR0(a6) = extended precision operand to be scaled		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5516) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5517) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5518) #	FP_SCR0(a6) = scaled extended precision operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5519) #	d0	    = scale value					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5520) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5521) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5522) #	Set the exponent of the input operand to 0x3fff. Save the value	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5523) # of the difference between the original and new exponent. Then,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5524) # normalize the operand if it was a DENORM. Add this normalization	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5525) # value to the previous value. Return the result.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5526) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5527) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5529) 	global		scale_to_zero_src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5530) scale_to_zero_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5531) 	mov.w		FP_SCR0_EX(%a6),%d1	# extract operand's {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5532) 	mov.w		%d1,%d0			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5534) 	andi.l		&0x7fff,%d1		# extract operand's exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5536) 	andi.w		&0x8000,%d0		# extract operand's sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5537) 	or.w		&0x3fff,%d0		# insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5539) 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert biased exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5541) 	cmpi.b		STAG(%a6),&DENORM	# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5542) 	beq.b		stzs_denorm		# normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5544) stzs_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5545) 	mov.l		&0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5546) 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5548) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5550) stzs_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5551) 	lea		FP_SCR0(%a6),%a0	# pass ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5552) 	bsr.l		norm			# normalize denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5553) 	neg.l		%d0			# new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5554) 	mov.l		%d0,%d1			# prepare for op_norm call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5555) 	bra.b		stzs_norm		# finish scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5557) ###
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5559) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5560) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5561) #	scale_sqrt(): scale the input operand exponent so a subsequent	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5562) #		      fsqrt operation won't take an exception.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5563) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5564) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5565) #	norm() - normalize the mantissa if the operand was a DENORM	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5566) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5567) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5568) #	FP_SCR0(a6) = extended precision operand to be scaled		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5569) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5570) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5571) #	FP_SCR0(a6) = scaled extended precision operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5572) #	d0	    = scale value					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5573) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5574) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5575) #	If the input operand is a DENORM, normalize it.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5576) #	If the exponent of the input operand is even, set the exponent	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5577) # to 0x3ffe and return a scale factor of "(exp-0x3ffe)/2". If the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5578) # exponent of the input operand is off, set the exponent to ox3fff and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5579) # return a scale factor of "(exp-0x3fff)/2".				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5580) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5581) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5583) 	global		scale_sqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5584) scale_sqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5585) 	cmpi.b		STAG(%a6),&DENORM	# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5586) 	beq.b		ss_denorm		# normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5588) 	mov.w		FP_SCR0_EX(%a6),%d1	# extract operand's {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5589) 	andi.l		&0x7fff,%d1		# extract operand's exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5591) 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# extract operand's sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5593) 	btst		&0x0,%d1		# is exp even or odd?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5594) 	beq.b		ss_norm_even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5596) 	ori.w		&0x3fff,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5598) 	mov.l		&0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5599) 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5600) 	asr.l		&0x1,%d0		# divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5601) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5603) ss_norm_even:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5604) 	ori.w		&0x3ffe,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5606) 	mov.l		&0x3ffe,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5607) 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5608) 	asr.l		&0x1,%d0		# divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5609) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5611) ss_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5612) 	lea		FP_SCR0(%a6),%a0	# pass ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5613) 	bsr.l		norm			# normalize denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5615) 	btst		&0x0,%d0		# is exp even or odd?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5616) 	beq.b		ss_denorm_even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5618) 	ori.w		&0x3fff,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5620) 	add.l		&0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5621) 	asr.l		&0x1,%d0		# divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5622) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5624) ss_denorm_even:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5625) 	ori.w		&0x3ffe,FP_SCR0_EX(%a6)	# insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5627) 	add.l		&0x3ffe,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5628) 	asr.l		&0x1,%d0		# divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5629) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5631) ###
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5633) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5634) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5635) #	scale_to_zero_dst(): scale the exponent of extended precision	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5636) #			     value at FP_SCR1(a6).			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5637) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5638) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5639) #	norm() - normalize the mantissa if the operand was a DENORM	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5640) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5641) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5642) #	FP_SCR1(a6) = extended precision operand to be scaled		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5643) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5644) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5645) #	FP_SCR1(a6) = scaled extended precision operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5646) #	d0	    = scale value					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5647) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5648) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5649) #	Set the exponent of the input operand to 0x3fff. Save the value	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5650) # of the difference between the original and new exponent. Then,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5651) # normalize the operand if it was a DENORM. Add this normalization	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5652) # value to the previous value. Return the result.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5653) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5654) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5656) 	global		scale_to_zero_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5657) scale_to_zero_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5658) 	mov.w		FP_SCR1_EX(%a6),%d1	# extract operand's {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5659) 	mov.w		%d1,%d0			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5661) 	andi.l		&0x7fff,%d1		# extract operand's exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5663) 	andi.w		&0x8000,%d0		# extract operand's sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5664) 	or.w		&0x3fff,%d0		# insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5666) 	mov.w		%d0,FP_SCR1_EX(%a6)	# insert biased exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5668) 	cmpi.b		DTAG(%a6),&DENORM	# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5669) 	beq.b		stzd_denorm		# normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5671) stzd_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5672) 	mov.l		&0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5673) 	sub.l		%d1,%d0			# scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5674) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5676) stzd_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5677) 	lea		FP_SCR1(%a6),%a0	# pass ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5678) 	bsr.l		norm			# normalize denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5679) 	neg.l		%d0			# new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5680) 	mov.l		%d0,%d1			# prepare for op_norm call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5681) 	bra.b		stzd_norm		# finish scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5683) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5685) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5686) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5687) #	res_qnan(): return default result w/ QNAN operand for dyadic	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5688) #	res_snan(): return default result w/ SNAN operand for dyadic	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5689) #	res_qnan_1op(): return dflt result w/ QNAN operand for monadic	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5690) #	res_snan_1op(): return dflt result w/ SNAN operand for monadic	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5691) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5692) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5693) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5694) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5695) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5696) #	FP_SRC(a6) = pointer to extended precision src operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5697) #	FP_DST(a6) = pointer to extended precision dst operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5698) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5699) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5700) #	fp0 = default result						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5701) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5702) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5703) #	If either operand (but not both operands) of an operation is a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5704) # nonsignalling NAN, then that NAN is returned as the result. If both	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5705) # operands are nonsignalling NANs, then the destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5706) # nonsignalling NAN is returned as the result.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5707) #	If either operand to an operation is a signalling NAN (SNAN),	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5708) # then, the SNAN bit is set in the FPSR EXC byte. If the SNAN trap	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5709) # enable bit is set in the FPCR, then the trap is taken and the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5710) # destination is not modified. If the SNAN trap enable bit is not set,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5711) # then the SNAN is converted to a nonsignalling NAN (by setting the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5712) # SNAN bit in the operand to one), and the operation continues as	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5713) # described in the preceding paragraph, for nonsignalling NANs.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5714) #	Make sure the appropriate FPSR bits are set before exiting.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5715) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5716) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5718) 	global		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5719) 	global		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5720) res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5721) res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5722) 	cmp.b		DTAG(%a6), &SNAN	# is the dst an SNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5723) 	beq.b		dst_snan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5724) 	cmp.b		DTAG(%a6), &QNAN	# is the dst a  QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5725) 	beq.b		dst_qnan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5726) src_nan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5727) 	cmp.b		STAG(%a6), &QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5728) 	beq.b		src_qnan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5729) 	global		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5730) res_snan_1op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5731) src_snan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5732) 	bset		&0x6, FP_SRC_HI(%a6)	# set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5733) 	or.l		&nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5734) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5735) 	bra.b		nan_comp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5736) 	global		res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5737) res_qnan_1op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5738) src_qnan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5739) 	or.l		&nan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5740) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5741) 	bra.b		nan_comp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5742) dst_snan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5743) 	or.l		&nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5744) 	bset		&0x6, FP_DST_HI(%a6)	# set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5745) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5746) 	bra.b		nan_comp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5747) dst_qnan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5748) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5749) 	cmp.b		STAG(%a6), &SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5750) 	bne		nan_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5751) 	or.l		&aiop_mask+snan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5752) nan_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5753) 	or.l		&nan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5754) nan_comp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5755) 	btst		&0x7, FTEMP_EX(%a0)	# is NAN neg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5756) 	beq.b		nan_not_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5757) 	or.l		&neg_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5758) nan_not_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5759) 	fmovm.x		(%a0), &0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5760) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5762) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5763) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5764) #	res_operr(): return default result during operand error		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5765) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5766) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5767) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5768) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5769) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5770) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5771) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5772) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5773) #	fp0 = default operand error result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5774) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5775) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5776) #	An nonsignalling NAN is returned as the default result when	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5777) # an operand error occurs for the following cases:			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5778) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5779) #	Multiply: (Infinity x Zero)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5780) #	Divide  : (Zero / Zero) || (Infinity / Infinity)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5781) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5782) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5784) 	global		res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5785) res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5786) 	or.l		&nan_mask+operr_mask+aiop_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5787) 	fmovm.x		nan_return(%pc), &0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5788) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5790) nan_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5791) 	long		0x7fff0000, 0xffffffff, 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5793) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5794) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5795) #	_denorm(): denormalize an intermediate result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5796) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5797) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5798) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5799) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5800) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5801) #	a0 = points to the operand to be denormalized			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5802) #		(in the internal extended format)			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5803) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5804) #	d0 = rounding precision						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5805) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5806) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5807) #	a0 = pointer to the denormalized result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5808) #		(in the internal extended format)			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5809) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5810) #	d0 = guard,round,sticky						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5811) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5812) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5813) #	According to the exponent underflow threshold for the given	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5814) # precision, shift the mantissa bits to the right in order raise the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5815) # exponent of the operand to the threshold value. While shifting the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5816) # mantissa bits right, maintain the value of the guard, round, and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5817) # sticky bits.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5818) # other notes:								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5819) #	(1) _denorm() is called by the underflow routines		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5820) #	(2) _denorm() does NOT affect the status register		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5821) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5822) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5824) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5825) # table of exponent threshold values for each precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5826) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5827) tbl_thresh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5828) 	short		0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5829) 	short		sgl_thresh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5830) 	short		dbl_thresh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5832) 	global		_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5833) _denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5834) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5835) # Load the exponent threshold for the precision selected and check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5836) # to see if (threshold - exponent) is > 65 in which case we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5837) # simply calculate the sticky bit and zero the mantissa. otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5838) # we have to call the denormalization routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5839) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5840) 	lsr.b		&0x2, %d0		# shift prec to lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5841) 	mov.w		(tbl_thresh.b,%pc,%d0.w*2), %d1 # load prec threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5842) 	mov.w		%d1, %d0		# copy d1 into d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5843) 	sub.w		FTEMP_EX(%a0), %d0	# diff = threshold - exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5844) 	cmpi.w		%d0, &66		# is diff > 65? (mant + g,r bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5845) 	bpl.b		denorm_set_stky		# yes; just calc sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5847) 	clr.l		%d0			# clear g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5848) 	btst		&inex2_bit, FPSR_EXCEPT(%a6) # yes; was INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5849) 	beq.b		denorm_call		# no; don't change anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5850) 	bset		&29, %d0		# yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5852) denorm_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5853) 	bsr.l		dnrm_lp			# denormalize the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5854) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5856) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5857) # all bit would have been shifted off during the denorm so simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5858) # calculate if the sticky should be set and clear the entire mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5859) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5860) denorm_set_stky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5861) 	mov.l		&0x20000000, %d0	# set sticky bit in return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5862) 	mov.w		%d1, FTEMP_EX(%a0)	# load exp with threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5863) 	clr.l		FTEMP_HI(%a0)		# set d1 = 0 (ms mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5864) 	clr.l		FTEMP_LO(%a0)		# set d2 = 0 (ms mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5865) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5867) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5868) # dnrm_lp(): normalize exponent/mantissa to specified threshold		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5869) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5870) # INPUT:								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5871) #	%a0	   : points to the operand to be denormalized		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5872) #	%d0{31:29} : initial guard,round,sticky				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5873) #	%d1{15:0}  : denormalization threshold				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5874) # OUTPUT:								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5875) #	%a0	   : points to the denormalized operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5876) #	%d0{31:29} : final guard,round,sticky				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5877) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5879) # *** Local Equates *** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5880) set	GRS,		L_SCR2			# g,r,s temp storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5881) set	FTEMP_LO2,	L_SCR1			# FTEMP_LO copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5883) 	global		dnrm_lp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5884) dnrm_lp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5886) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5887) # make a copy of FTEMP_LO and place the g,r,s bits directly after it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5888) # in memory so as to make the bitfield extraction for denormalization easier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5889) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5890) 	mov.l		FTEMP_LO(%a0), FTEMP_LO2(%a6) # make FTEMP_LO copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5891) 	mov.l		%d0, GRS(%a6)		# place g,r,s after it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5893) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5894) # check to see how much less than the underflow threshold the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5895) # exponent is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5896) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5897) 	mov.l		%d1, %d0		# copy the denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5898) 	sub.w		FTEMP_EX(%a0), %d1	# d1 = threshold - uns exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5899) 	ble.b		dnrm_no_lp		# d1 <= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5900) 	cmpi.w		%d1, &0x20		# is ( 0 <= d1 < 32) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5901) 	blt.b		case_1			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5902) 	cmpi.w		%d1, &0x40		# is (32 <= d1 < 64) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5903) 	blt.b		case_2			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5904) 	bra.w		case_3			# (d1 >= 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5906) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5907) # No normalization necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5908) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5909) dnrm_no_lp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5910) 	mov.l		GRS(%a6), %d0		# restore original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5911) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5913) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5914) # case (0<d1<32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5915) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5916) # %d0 = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5917) # %d1 = "n" = amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5918) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5919) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5920) #	|     FTEMP_HI	  |	FTEMP_LO     |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5921) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5922) #	<-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5923) #	\	   \		      \			 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5924) #	 \	    \		       \		  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5925) #	  \	     \			\		   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5926) #	   \	      \			 \		    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5927) #	    \	       \		  \		     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5928) #	     \		\		   \		      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5929) #	      \		 \		    \		       \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5930) #	       \	  \		     \			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5931) #	<-(n)-><-(32 - n)-><------(32)-------><------(32)------->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5932) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5933) #	|0.....0| NEW_HI  |  NEW_FTEMP_LO     |grs		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5934) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5935) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5936) case_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5937) 	mov.l		%d2, -(%sp)		# create temp storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5939) 	mov.w		%d0, FTEMP_EX(%a0)	# exponent = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5940) 	mov.l		&32, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5941) 	sub.w		%d1, %d0		# %d0 = 32 - %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5943) 	cmpi.w		%d1, &29		# is shft amt >= 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5944) 	blt.b		case1_extract		# no; no fix needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5945) 	mov.b		GRS(%a6), %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5946) 	or.b		%d2, 3+FTEMP_LO2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5948) case1_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5949) 	bfextu		FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_HI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5950) 	bfextu		FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5951) 	bfextu		FTEMP_LO2(%a6){%d0:&32}, %d0 # %d0 = new G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5953) 	mov.l		%d2, FTEMP_HI(%a0)	# store new FTEMP_HI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5954) 	mov.l		%d1, FTEMP_LO(%a0)	# store new FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5956) 	bftst		%d0{&2:&30}		# were bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5957) 	beq.b		case1_sticky_clear	# no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5958) 	bset		&rnd_stky_bit, %d0	# yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5960) case1_sticky_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5961) 	and.l		&0xe0000000, %d0	# clear all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5962) 	mov.l		(%sp)+, %d2		# restore temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5963) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5965) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5966) # case (32<=d1<64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5967) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5968) # %d0 = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5969) # %d1 = "n" = amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5970) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5971) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5972) #	|     FTEMP_HI	  |	FTEMP_LO     |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5973) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5974) #	<-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5975) #	\	   \		      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5976) #	 \	    \		       \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5977) #	  \	     \			-------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5978) #	   \	      --------------------		   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5979) #	    -------------------		  \		    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5980) #			       \	   \		     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5981) #				\	    \		      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5982) #				 \	     \		       \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5983) #	<-------(32)------><-(n)-><-(32 - n)-><------(32)------->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5984) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5985) #	|0...............0|0....0| NEW_LO     |grs		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5986) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5987) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5988) case_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5989) 	mov.l		%d2, -(%sp)		# create temp storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5991) 	mov.w		%d0, FTEMP_EX(%a0)	# exponent = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5992) 	subi.w		&0x20, %d1		# %d1 now between 0 and 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5993) 	mov.l		&0x20, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5994) 	sub.w		%d1, %d0		# %d0 = 32 - %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5996) # subtle step here; or in the g,r,s at the bottom of FTEMP_LO to minimize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5997) # the number of bits to check for the sticky detect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5998) # it only plays a role in shift amounts of 61-63.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5999) 	mov.b		GRS(%a6), %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6000) 	or.b		%d2, 3+FTEMP_LO2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6002) 	bfextu		FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6003) 	bfextu		FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6005) 	bftst		%d1{&2:&30}		# were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6006) 	bne.b		case2_set_sticky	# yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6007) 	bftst		FTEMP_LO2(%a6){%d0:&31}	# were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6008) 	bne.b		case2_set_sticky	# yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6010) 	mov.l		%d1, %d0		# move new G,R,S to %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6011) 	bra.b		case2_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6013) case2_set_sticky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6014) 	mov.l		%d1, %d0		# move new G,R,S to %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6015) 	bset		&rnd_stky_bit, %d0	# set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6017) case2_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6018) 	clr.l		FTEMP_HI(%a0)		# store FTEMP_HI = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6019) 	mov.l		%d2, FTEMP_LO(%a0)	# store FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6020) 	and.l		&0xe0000000, %d0	# clear all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6022) 	mov.l		(%sp)+,%d2		# restore temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6023) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6025) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6026) # case (d1>=64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6027) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6028) # %d0 = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6029) # %d1 = amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6030) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6031) case_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6032) 	mov.w		%d0, FTEMP_EX(%a0)	# insert denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6034) 	cmpi.w		%d1, &65		# is shift amt > 65?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6035) 	blt.b		case3_64		# no; it's == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6036) 	beq.b		case3_65		# no; it's == 65
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6038) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6039) # case (d1>65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6040) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6041) # Shift value is > 65 and out of range. All bits are shifted off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6042) # Return a zero mantissa with the sticky bit set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6043) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6044) 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6045) 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6046) 	mov.l		&0x20000000, %d0	# set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6047) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6049) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6050) # case (d1 == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6051) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6052) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6053) #	|     FTEMP_HI	  |	FTEMP_LO     |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6054) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6055) #	<-------(32)------>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6056) #	\		   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6057) #	 \		    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6058) #	  \		     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6059) #	   \		      ------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6060) #	    -------------------------------		    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6061) #					   \		     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6062) #					    \		      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6063) #					     \		       \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6064) #					      <-------(32)------>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6065) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6066) #	|0...............0|0................0|grs		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6067) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6068) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6069) case3_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6070) 	mov.l		FTEMP_HI(%a0), %d0	# fetch hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6071) 	mov.l		%d0, %d1		# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6072) 	and.l		&0xc0000000, %d0	# extract G,R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6073) 	and.l		&0x3fffffff, %d1	# extract other bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6075) 	bra.b		case3_complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6077) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6078) # case (d1 == 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6079) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6080) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6081) #	|     FTEMP_HI	  |	FTEMP_LO     |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6082) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6083) #	<-------(32)------>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6084) #	\		   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6085) #	 \		    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6086) #	  \		     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6087) #	   \		      ------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6088) #	    --------------------------------		    \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6089) #					    \		     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6090) #					     \		      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6091) #					      \		       \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6092) #					       <-------(31)----->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6093) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6094) #	|0...............0|0................0|0rs		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6095) #	---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6096) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6097) case3_65:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6098) 	mov.l		FTEMP_HI(%a0), %d0	# fetch hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6099) 	and.l		&0x80000000, %d0	# extract R bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6100) 	lsr.l		&0x1, %d0		# shift high bit into R bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6101) 	and.l		&0x7fffffff, %d1	# extract other bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6103) case3_complete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6104) # last operation done was an "and" of the bits shifted off so the condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6105) # codes are already set so branch accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6106) 	bne.b		case3_set_sticky	# yes; go set new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6107) 	tst.l		FTEMP_LO(%a0)		# were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6108) 	bne.b		case3_set_sticky	# yes; go set new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6109) 	tst.b		GRS(%a6)		# were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6110) 	bne.b		case3_set_sticky	# yes; go set new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6112) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6113) # no bits were shifted off so don't set the sticky bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6114) # the guard and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6115) # the entire mantissa is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6116) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6117) 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6118) 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6119) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6121) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6122) # some bits were shifted off so set the sticky bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6123) # the entire mantissa is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6124) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6125) case3_set_sticky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6126) 	bset		&rnd_stky_bit,%d0	# set new sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6127) 	clr.l		FTEMP_HI(%a0)		# clear hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6128) 	clr.l		FTEMP_LO(%a0)		# clear lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6129) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6131) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6132) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6133) #	_round(): round result according to precision/mode		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6134) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6135) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6136) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6137) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6138) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6139) #	a0	  = ptr to input operand in internal extended format	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6140) #	d1(hi)    = contains rounding precision:			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6141) #			ext = $0000xxxx					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6142) #			sgl = $0004xxxx					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6143) #			dbl = $0008xxxx					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6144) #	d1(lo)	  = contains rounding mode:				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6145) #			RN  = $xxxx0000					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6146) #			RZ  = $xxxx0001					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6147) #			RM  = $xxxx0002					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6148) #			RP  = $xxxx0003					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6149) #	d0{31:29} = contains the g,r,s bits (extended)			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6150) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6151) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6152) #	a0 = pointer to rounded result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6153) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6154) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6155) #	On return the value pointed to by a0 is correctly rounded,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6156) #	a0 is preserved and the g-r-s bits in d0 are cleared.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6157) #	The result is not typed - the tag field is invalid.  The	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6158) #	result is still in the internal extended format.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6159) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6160) #	The INEX bit of USER_FPSR will be set if the rounded result was	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6161) #	inexact (i.e. if any of the g-r-s bits were set).		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6162) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6163) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6165) 	global		_round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6166) _round:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6167) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6168) # ext_grs() looks at the rounding precision and sets the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6169) # G,R,S bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6170) # If (G,R,S == 0) then result is exact and round is done, else set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6171) # the inex flag in status reg and continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6172) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6173) 	bsr.l		ext_grs			# extract G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6175) 	tst.l		%d0			# are G,R,S zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6176) 	beq.w		truncate		# yes; round is complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6178) 	or.w		&inx2a_mask, 2+USER_FPSR(%a6) # set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6180) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6181) # Use rounding mode as an index into a jump table for these modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6182) # All of the following assumes grs != 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6183) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6184) 	mov.w		(tbl_mode.b,%pc,%d1.w*2), %a1 # load jump offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6185) 	jmp		(tbl_mode.b,%pc,%a1)	# jmp to rnd mode handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6187) tbl_mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6188) 	short		rnd_near - tbl_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6189) 	short		truncate - tbl_mode	# RZ always truncates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6190) 	short		rnd_mnus - tbl_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6191) 	short		rnd_plus - tbl_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6193) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6194) #	ROUND PLUS INFINITY					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6195) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6196) #	If sign of fp number = 0 (positive), then add 1 to l.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6197) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6198) rnd_plus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6199) 	tst.b		FTEMP_SGN(%a0)		# check for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6200) 	bmi.w		truncate		# if positive then truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6202) 	mov.l		&0xffffffff, %d0	# force g,r,s to be all f's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6203) 	swap		%d1			# set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6205) 	cmpi.b		%d1, &s_mode		# is prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6206) 	beq.w		add_sgl			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6207) 	bgt.w		add_dbl			# no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6208) 	bra.w		add_ext			# no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6210) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6211) #	ROUND MINUS INFINITY					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6212) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6213) #	If sign of fp number = 1 (negative), then add 1 to l.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6214) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6215) rnd_mnus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6216) 	tst.b		FTEMP_SGN(%a0)		# check for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6217) 	bpl.w		truncate		# if negative then truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6219) 	mov.l		&0xffffffff, %d0	# force g,r,s to be all f's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6220) 	swap		%d1			# set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6222) 	cmpi.b		%d1, &s_mode		# is prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6223) 	beq.w		add_sgl			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6224) 	bgt.w		add_dbl			# no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6225) 	bra.w		add_ext			# no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6227) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6228) #	ROUND NEAREST						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6229) #								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6230) #	If (g=1), then add 1 to l and if (r=s=0), then clear l	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6231) #	Note that this will round to even in case of a tie.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6232) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6233) rnd_near:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6234) 	asl.l		&0x1, %d0		# shift g-bit to c-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6235) 	bcc.w		truncate		# if (g=1) then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6237) 	swap		%d1			# set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6239) 	cmpi.b		%d1, &s_mode		# is prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6240) 	beq.w		add_sgl			# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6241) 	bgt.w		add_dbl			# no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6242) 	bra.w		add_ext			# no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6244) # *** LOCAL EQUATES ***
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6245) set	ad_1_sgl,	0x00000100	# constant to add 1 to l-bit in sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6246) set	ad_1_dbl,	0x00000800	# constant to add 1 to l-bit in dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6248) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6249) #	ADD SINGLE	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6250) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6251) add_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6252) 	add.l		&ad_1_sgl, FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6253) 	bcc.b		scc_clr			# no mantissa overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6254) 	roxr.w		FTEMP_HI(%a0)		# shift v-bit back in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6255) 	roxr.w		FTEMP_HI+2(%a0)		# shift v-bit back in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6256) 	add.w		&0x1, FTEMP_EX(%a0)	# and incr exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6257) scc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6258) 	tst.l		%d0			# test for rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6259) 	bne.b		sgl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6260) 	and.w		&0xfe00, FTEMP_HI+2(%a0) # clear the l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6261) sgl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6262) 	and.l		&0xffffff00, FTEMP_HI(%a0) # truncate bits beyond sgl limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6263) 	clr.l		FTEMP_LO(%a0)		# clear d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6264) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6266) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6267) #	ADD EXTENDED	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6268) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6269) add_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6270) 	addq.l		&1,FTEMP_LO(%a0)	# add 1 to l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6271) 	bcc.b		xcc_clr			# test for carry out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6272) 	addq.l		&1,FTEMP_HI(%a0)	# propagate carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6273) 	bcc.b		xcc_clr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6274) 	roxr.w		FTEMP_HI(%a0)		# mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6275) 	roxr.w		FTEMP_HI+2(%a0)		# mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6276) 	roxr.w		FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6277) 	roxr.w		FTEMP_LO+2(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6278) 	add.w		&0x1,FTEMP_EX(%a0)	# and inc exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6279) xcc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6280) 	tst.l		%d0			# test rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6281) 	bne.b		add_ext_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6282) 	and.b		&0xfe,FTEMP_LO+3(%a0)	# clear the l bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6283) add_ext_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6284) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6286) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6287) #	ADD DOUBLE	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6288) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6289) add_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6290) 	add.l		&ad_1_dbl, FTEMP_LO(%a0) # add 1 to lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6291) 	bcc.b		dcc_clr			# no carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6292) 	addq.l		&0x1, FTEMP_HI(%a0)	# propagate carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6293) 	bcc.b		dcc_clr			# no carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6295) 	roxr.w		FTEMP_HI(%a0)		# mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6296) 	roxr.w		FTEMP_HI+2(%a0)		# mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6297) 	roxr.w		FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6298) 	roxr.w		FTEMP_LO+2(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6299) 	addq.w		&0x1, FTEMP_EX(%a0)	# incr exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6300) dcc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6301) 	tst.l		%d0			# test for rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6302) 	bne.b		dbl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6303) 	and.w		&0xf000, FTEMP_LO+2(%a0) # clear the l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6305) dbl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6306) 	and.l		&0xfffff800,FTEMP_LO(%a0) # truncate bits beyond dbl limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6307) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6309) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6310) # Truncate all other bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6311) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6312) truncate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6313) 	swap		%d1			# select rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6315) 	cmpi.b		%d1, &s_mode		# is prec sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6316) 	beq.w		sgl_done		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6317) 	bgt.b		dbl_done		# no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6318) 	rts					# no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6321) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6322) # ext_grs(): extract guard, round and sticky bits according to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6323) #	     rounding precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6324) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6325) # INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6326) #	d0	   = extended precision g,r,s (in d0{31:29})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6327) #	d1	   = {PREC,ROUND}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6328) # OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6329) #	d0{31:29}  = guard, round, sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6330) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6331) # The ext_grs extract the guard/round/sticky bits according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6332) # selected rounding precision. It is called by the round subroutine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6333) # only.  All registers except d0 are kept intact. d0 becomes an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6334) # updated guard,round,sticky in d0{31:29}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6335) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6336) # Notes: the ext_grs uses the round PREC, and therefore has to swap d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6337) #	 prior to usage, and needs to restore d1 to original. this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6338) #	 routine is tightly tied to the round routine and not meant to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6339) #	 uphold standard subroutine calling practices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6340) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6342) ext_grs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6343) 	swap		%d1			# have d1.w point to round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6344) 	tst.b		%d1			# is rnd prec = extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6345) 	bne.b		ext_grs_not_ext		# no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6347) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6348) # %d0 actually already hold g,r,s since _round() had it before calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6349) # this function. so, as long as we don't disturb it, we are "returning" it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6350) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6351) ext_grs_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6352) 	swap		%d1			# yes; return to correct positions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6353) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6355) ext_grs_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6356) 	movm.l		&0x3000, -(%sp)		# make some temp registers {d2/d3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6358) 	cmpi.b		%d1, &s_mode		# is rnd prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6359) 	bne.b		ext_grs_dbl		# no; go handle dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6361) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6362) # sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6363) #	96		64	  40	32		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6364) #	-----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6365) #	| EXP	|XXXXXXX|	  |xx	|		|grs|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6366) #	-----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6367) #			<--(24)--->nn\			   /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6368) #				   ee ---------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6369) #				   ww		|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6370) #						v
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6371) #				   gr	   new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6372) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6373) ext_grs_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6374) 	bfextu		FTEMP_HI(%a0){&24:&2}, %d3 # sgl prec. g-r are 2 bits right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6375) 	mov.l		&30, %d2		# of the sgl prec. limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6376) 	lsl.l		%d2, %d3		# shift g-r bits to MSB of d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6377) 	mov.l		FTEMP_HI(%a0), %d2	# get word 2 for s-bit test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6378) 	and.l		&0x0000003f, %d2	# s bit is the or of all other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6379) 	bne.b		ext_grs_st_stky		# bits to the right of g-r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6380) 	tst.l		FTEMP_LO(%a0)		# test lower mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6381) 	bne.b		ext_grs_st_stky		# if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6382) 	tst.l		%d0			# test original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6383) 	bne.b		ext_grs_st_stky		# if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6384) 	bra.b		ext_grs_end_sd		# if words 3 and 4 are clr, exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6386) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6387) # dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6388) #	96		64		32	 11	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6389) #	-----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6390) #	| EXP	|XXXXXXX|		|	 |xx	|grs|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6391) #	-----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6392) #						  nn\	    /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6393) #						  ee -------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6394) #						  ww	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6395) #							v
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6396) #						  gr	new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6397) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6398) ext_grs_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6399) 	bfextu		FTEMP_LO(%a0){&21:&2}, %d3 # dbl-prec. g-r are 2 bits right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6400) 	mov.l		&30, %d2		# of the dbl prec. limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6401) 	lsl.l		%d2, %d3		# shift g-r bits to the MSB of d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6402) 	mov.l		FTEMP_LO(%a0), %d2	# get lower mantissa  for s-bit test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6403) 	and.l		&0x000001ff, %d2	# s bit is the or-ing of all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6404) 	bne.b		ext_grs_st_stky		# other bits to the right of g-r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6405) 	tst.l		%d0			# test word original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6406) 	bne.b		ext_grs_st_stky		# if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6407) 	bra.b		ext_grs_end_sd		# if clear, exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6409) ext_grs_st_stky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6410) 	bset		&rnd_stky_bit, %d3	# set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6411) ext_grs_end_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6412) 	mov.l		%d3, %d0		# return grs to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6414) 	movm.l		(%sp)+, &0xc		# restore scratch registers {d2/d3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6416) 	swap		%d1			# restore d1 to original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6417) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6419) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6420) # norm(): normalize the mantissa of an extended precision input. the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6421) #	  input operand should not be normalized already.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6422) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6423) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6424) #	norm()								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6425) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6426) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6427) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6428) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6429) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6430) #	a0 = pointer fp extended precision operand to normalize		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6431) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6432) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6433) #	d0 = number of bit positions the mantissa was shifted		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6434) #	a0 = the input operand's mantissa is normalized; the exponent	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6435) #	     is unchanged.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6436) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6437) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6438) 	global		norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6439) norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6440) 	mov.l		%d2, -(%sp)		# create some temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6441) 	mov.l		%d3, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6443) 	mov.l		FTEMP_HI(%a0), %d0	# load hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6444) 	mov.l		FTEMP_LO(%a0), %d1	# load lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6446) 	bfffo		%d0{&0:&32}, %d2	# how many places to shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6447) 	beq.b		norm_lo			# hi(man) is all zeroes!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6449) norm_hi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6450) 	lsl.l		%d2, %d0		# left shift hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6451) 	bfextu		%d1{&0:%d2}, %d3	# extract lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6453) 	or.l		%d3, %d0		# create hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6454) 	lsl.l		%d2, %d1		# create lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6456) 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6457) 	mov.l		%d1, FTEMP_LO(%a0)	# store new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6459) 	mov.l		%d2, %d0		# return shift amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6461) 	mov.l		(%sp)+, %d3		# restore temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6462) 	mov.l		(%sp)+, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6464) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6466) norm_lo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6467) 	bfffo		%d1{&0:&32}, %d2	# how many places to shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6468) 	lsl.l		%d2, %d1		# shift lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6469) 	add.l		&32, %d2		# add 32 to shft amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6471) 	mov.l		%d1, FTEMP_HI(%a0)	# store hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6472) 	clr.l		FTEMP_LO(%a0)		# lo(man) is now zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6474) 	mov.l		%d2, %d0		# return shift amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6476) 	mov.l		(%sp)+, %d3		# restore temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6477) 	mov.l		(%sp)+, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6479) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6481) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6482) # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6483) #		- returns corresponding optype tag			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6484) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6485) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6486) #	unnorm_fix()							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6487) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6488) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6489) #	norm() - normalize the mantissa					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6490) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6491) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6492) #	a0 = pointer to unnormalized extended precision number		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6493) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6494) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6495) #	d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6496) #	a0 = input operand has been converted to a norm, denorm, or	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6497) #	     zero; both the exponent and mantissa are changed.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6498) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6499) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6501) 	global		unnorm_fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6502) unnorm_fix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6503) 	bfffo		FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6504) 	bne.b		unnorm_shift		# hi(man) is not all zeroes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6506) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6507) # hi(man) is all zeroes so see if any bits in lo(man) are set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6508) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6509) unnorm_chk_lo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6510) 	bfffo		FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6511) 	beq.w		unnorm_zero		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6513) 	add.w		&32, %d0		# no; fix shift distance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6515) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6516) # d0 = # shifts needed for complete normalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6517) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6518) unnorm_shift:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6519) 	clr.l		%d1			# clear top word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6520) 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6521) 	and.w		&0x7fff, %d1		# strip off sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6523) 	cmp.w		%d0, %d1		# will denorm push exp < 0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6524) 	bgt.b		unnorm_nrm_zero		# yes; denorm only until exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6526) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6527) # exponent would not go < 0. Therefore, number stays normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6528) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6529) 	sub.w		%d0, %d1		# shift exponent value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6530) 	mov.w		FTEMP_EX(%a0), %d0	# load old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6531) 	and.w		&0x8000, %d0		# save old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6532) 	or.w		%d0, %d1		# {sgn,new exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6533) 	mov.w		%d1, FTEMP_EX(%a0)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6535) 	bsr.l		norm			# normalize UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6537) 	mov.b		&NORM, %d0		# return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6538) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6540) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6541) # exponent would go < 0, so only denormalize until exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6542) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6543) unnorm_nrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6544) 	cmp.b		%d1, &32		# is exp <= 32?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6545) 	bgt.b		unnorm_nrm_zero_lrg	# no; go handle large exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6547) 	bfextu		FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6548) 	mov.l		%d0, FTEMP_HI(%a0)	# save new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6550) 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6551) 	lsl.l		%d1, %d0		# extract new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6552) 	mov.l		%d0, FTEMP_LO(%a0)	# save new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6554) 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6556) 	mov.b		&DENORM, %d0		# return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6557) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6559) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6560) # only mantissa bits set are in lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6561) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6562) unnorm_nrm_zero_lrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6563) 	sub.w		&32, %d1		# adjust shft amt by 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6565) 	mov.l		FTEMP_LO(%a0), %d0	# fetch old lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6566) 	lsl.l		%d1, %d0		# left shift lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6568) 	mov.l		%d0, FTEMP_HI(%a0)	# store new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6569) 	clr.l		FTEMP_LO(%a0)		# lo(man) = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6571) 	and.w		&0x8000, FTEMP_EX(%a0)	# set exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6573) 	mov.b		&DENORM, %d0		# return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6574) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6576) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6577) # whole mantissa is zero so this UNNORM is actually a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6578) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6579) unnorm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6580) 	and.w		&0x8000, FTEMP_EX(%a0)	# force exponent to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6582) 	mov.b		&ZERO, %d0		# fix optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6583) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6585) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6586) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6587) #	set_tag_x(): return the optype of the input ext fp number	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6588) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6589) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6590) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6591) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6592) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6593) #	a0 = pointer to extended precision operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6594) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6595) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6596) #	d0 = value of type tag						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6597) #		one of: NORM, INF, QNAN, SNAN, DENORM, UNNORM, ZERO	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6598) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6599) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6600) #	Simply test the exponent, j-bit, and mantissa values to		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6601) # determine the type of operand.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6602) #	If it's an unnormalized zero, alter the operand and force it	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6603) # to be a normal zero.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6604) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6605) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6607) 	global		set_tag_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6608) set_tag_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6609) 	mov.w		FTEMP_EX(%a0), %d0	# extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6610) 	andi.w		&0x7fff, %d0		# strip off sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6611) 	cmpi.w		%d0, &0x7fff		# is (EXP == MAX)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6612) 	beq.b		inf_or_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6613) not_inf_or_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6614) 	btst		&0x7,FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6615) 	beq.b		not_norm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6616) is_norm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6617) 	mov.b		&NORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6618) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6619) not_norm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6620) 	tst.w		%d0			# is exponent = 0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6621) 	bne.b		is_unnorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6622) not_unnorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6623) 	tst.l		FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6624) 	bne.b		is_denorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6625) 	tst.l		FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6626) 	bne.b		is_denorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6627) is_zero_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6628) 	mov.b		&ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6629) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6630) is_denorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6631) 	mov.b		&DENORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6632) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6633) # must distinguish now "Unnormalized zeroes" which we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6634) # must convert to zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6635) is_unnorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6636) 	tst.l		FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6637) 	bne.b		is_unnorm_reg_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6638) 	tst.l		FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6639) 	bne.b		is_unnorm_reg_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6640) # it's an "unnormalized zero". let's convert it to an actual zero...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6641) 	andi.w		&0x8000,FTEMP_EX(%a0)	# clear exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6642) 	mov.b		&ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6643) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6644) is_unnorm_reg_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6645) 	mov.b		&UNNORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6646) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6647) inf_or_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6648) 	tst.l		FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6649) 	bne.b		is_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6650) 	mov.l		FTEMP_HI(%a0), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6651) 	and.l		&0x7fffffff, %d0	# msb is a don't care!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6652) 	bne.b		is_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6653) is_inf_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6654) 	mov.b		&INF, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6655) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6656) is_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6657) 	btst		&0x6, FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6658) 	beq.b		is_snan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6659) 	mov.b		&QNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6660) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6661) is_snan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6662) 	mov.b		&SNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6663) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6665) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6666) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6667) #	set_tag_d(): return the optype of the input dbl fp number	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6668) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6669) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6670) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6671) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6672) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6673) #	a0 = points to double precision operand				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6674) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6675) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6676) #	d0 = value of type tag						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6677) #		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6678) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6679) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6680) #	Simply test the exponent, j-bit, and mantissa values to		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6681) # determine the type of operand.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6682) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6683) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6685) 	global		set_tag_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6686) set_tag_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6687) 	mov.l		FTEMP(%a0), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6688) 	mov.l		%d0, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6690) 	andi.l		&0x7ff00000, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6691) 	beq.b		zero_or_denorm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6693) 	cmpi.l		%d0, &0x7ff00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6694) 	beq.b		inf_or_nan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6696) is_norm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6697) 	mov.b		&NORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6698) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6699) zero_or_denorm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6700) 	and.l		&0x000fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6701) 	bne		is_denorm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6702) 	tst.l		4+FTEMP(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6703) 	bne		is_denorm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6704) is_zero_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6705) 	mov.b		&ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6706) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6707) is_denorm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6708) 	mov.b		&DENORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6709) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6710) inf_or_nan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6711) 	and.l		&0x000fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6712) 	bne		is_nan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6713) 	tst.l		4+FTEMP(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6714) 	bne		is_nan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6715) is_inf_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6716) 	mov.b		&INF, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6717) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6718) is_nan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6719) 	btst		&19, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6720) 	bne		is_qnan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6721) is_snan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6722) 	mov.b		&SNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6723) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6724) is_qnan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6725) 	mov.b		&QNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6726) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6728) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6729) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6730) #	set_tag_s(): return the optype of the input sgl fp number	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6731) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6732) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6733) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6734) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6735) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6736) #	a0 = pointer to single precision operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6737) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6738) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6739) #	d0 = value of type tag						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6740) #		one of: NORM, INF, QNAN, SNAN, DENORM, ZERO		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6741) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6742) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6743) #	Simply test the exponent, j-bit, and mantissa values to		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6744) # determine the type of operand.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6745) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6746) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6748) 	global		set_tag_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6749) set_tag_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6750) 	mov.l		FTEMP(%a0), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6751) 	mov.l		%d0, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6753) 	andi.l		&0x7f800000, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6754) 	beq.b		zero_or_denorm_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6756) 	cmpi.l		%d0, &0x7f800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6757) 	beq.b		inf_or_nan_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6759) is_norm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6760) 	mov.b		&NORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6761) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6762) zero_or_denorm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6763) 	and.l		&0x007fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6764) 	bne		is_denorm_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6765) is_zero_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6766) 	mov.b		&ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6767) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6768) is_denorm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6769) 	mov.b		&DENORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6770) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6771) inf_or_nan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6772) 	and.l		&0x007fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6773) 	bne		is_nan_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6774) is_inf_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6775) 	mov.b		&INF, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6776) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6777) is_nan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6778) 	btst		&22, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6779) 	bne		is_qnan_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6780) is_snan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6781) 	mov.b		&SNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6782) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6783) is_qnan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6784) 	mov.b		&QNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6785) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6787) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6788) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6789) #	unf_res(): routine to produce default underflow result of a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6790) #		   scaled extended precision number; this is used by	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6791) #		   fadd/fdiv/fmul/etc. emulation routines.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6792) #	unf_res4(): same as above but for fsglmul/fsgldiv which use	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6793) #		    single round prec and extended prec mode.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6794) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6795) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6796) #	_denorm() - denormalize according to scale factor		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6797) #	_round() - round denormalized number according to rnd prec	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6798) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6799) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6800) #	a0 = pointer to extended precison operand			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6801) #	d0 = scale factor						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6802) #	d1 = rounding precision/mode					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6803) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6804) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6805) #	a0 = pointer to default underflow result in extended precision	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6806) #	d0.b = result FPSR_cc which caller may or may not want to save	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6807) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6808) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6809) #	Convert the input operand to "internal format" which means the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6810) # exponent is extended to 16 bits and the sign is stored in the unused	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6811) # portion of the extended precison operand. Denormalize the number	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6812) # according to the scale factor passed in d0. Then, round the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6813) # denormalized result.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6814) #	Set the FPSR_exc bits as appropriate but return the cc bits in	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6815) # d0 in case the caller doesn't want to save them (as is the case for	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6816) # fmove out).								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6817) #	unf_res4() for fsglmul/fsgldiv forces the denorm to extended	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6818) # precision and the rounding mode to single.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6819) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6820) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6821) 	global		unf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6822) unf_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6823) 	mov.l		%d1, -(%sp)		# save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6825) 	btst		&0x7, FTEMP_EX(%a0)	# make "internal" format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6826) 	sne		FTEMP_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6828) 	mov.w		FTEMP_EX(%a0), %d1	# extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6829) 	and.w		&0x7fff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6830) 	sub.w		%d0, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6831) 	mov.w		%d1, FTEMP_EX(%a0)	# insert 16 bit exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6833) 	mov.l		%a0, -(%sp)		# save operand ptr during calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6835) 	mov.l		0x4(%sp),%d0		# pass rnd prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6836) 	andi.w		&0x00c0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6837) 	lsr.w		&0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6838) 	bsr.l		_denorm			# denorm result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6840) 	mov.l		(%sp),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6841) 	mov.w		0x6(%sp),%d1		# load prec:mode into %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6842) 	andi.w		&0xc0,%d1		# extract rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6843) 	lsr.w		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6844) 	swap		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6845) 	mov.w		0x6(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6846) 	andi.w		&0x30,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6847) 	lsr.w		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6848) 	bsr.l		_round			# round the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6850) 	mov.l		(%sp)+, %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6852) # result is now rounded properly. convert back to normal format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6853) 	bclr		&0x7, FTEMP_EX(%a0)	# clear sgn first; may have residue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6854) 	tst.b		FTEMP_SGN(%a0)		# is "internal result" sign set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6855) 	beq.b		unf_res_chkifzero	# no; result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6856) 	bset		&0x7, FTEMP_EX(%a0)	# set result sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6857) 	clr.b		FTEMP_SGN(%a0)		# clear temp sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6859) # the number may have become zero after rounding. set ccodes accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6860) unf_res_chkifzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6861) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6862) 	tst.l		FTEMP_HI(%a0)		# is value now a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6863) 	bne.b		unf_res_cont		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6864) 	tst.l		FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6865) 	bne.b		unf_res_cont		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6866) #	bset		&z_bit, FPSR_CC(%a6)	# yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6867) 	bset		&z_bit, %d0		# yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6869) unf_res_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6871) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6872) # can inex1 also be set along with unfl and inex2???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6873) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6874) # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6875) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6876) 	btst		&inex2_bit, FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6877) 	beq.b		unf_res_end		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6878) 	bset		&aunfl_bit, FPSR_AEXCEPT(%a6) # yes; set aunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6880) unf_res_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6881) 	add.l		&0x4, %sp		# clear stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6882) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6884) # unf_res() for fsglmul() and fsgldiv().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6885) 	global		unf_res4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6886) unf_res4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6887) 	mov.l		%d1,-(%sp)		# save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6889) 	btst		&0x7,FTEMP_EX(%a0)	# make "internal" format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6890) 	sne		FTEMP_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6892) 	mov.w		FTEMP_EX(%a0),%d1	# extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6893) 	and.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6894) 	sub.w		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6895) 	mov.w		%d1,FTEMP_EX(%a0)	# insert 16 bit exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6897) 	mov.l		%a0,-(%sp)		# save operand ptr during calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6899) 	clr.l		%d0			# force rnd prec = ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6900) 	bsr.l		_denorm			# denorm result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6902) 	mov.l		(%sp),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6903) 	mov.w		&s_mode,%d1		# force rnd prec = sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6904) 	swap		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6905) 	mov.w		0x6(%sp),%d1		# load rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6906) 	andi.w		&0x30,%d1		# extract rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6907) 	lsr.w		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6908) 	bsr.l		_round			# round the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6910) 	mov.l		(%sp)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6912) # result is now rounded properly. convert back to normal format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6913) 	bclr		&0x7,FTEMP_EX(%a0)	# clear sgn first; may have residue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6914) 	tst.b		FTEMP_SGN(%a0)		# is "internal result" sign set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6915) 	beq.b		unf_res4_chkifzero	# no; result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6916) 	bset		&0x7,FTEMP_EX(%a0)	# set result sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6917) 	clr.b		FTEMP_SGN(%a0)		# clear temp sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6919) # the number may have become zero after rounding. set ccodes accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6920) unf_res4_chkifzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6921) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6922) 	tst.l		FTEMP_HI(%a0)		# is value now a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6923) 	bne.b		unf_res4_cont		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6924) 	tst.l		FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6925) 	bne.b		unf_res4_cont		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6926) #	bset		&z_bit,FPSR_CC(%a6)	# yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6927) 	bset		&z_bit,%d0		# yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6929) unf_res4_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6931) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6932) # can inex1 also be set along with unfl and inex2???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6933) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6934) # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6935) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6936) 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6937) 	beq.b		unf_res4_end		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6938) 	bset		&aunfl_bit,FPSR_AEXCEPT(%a6) # yes; set aunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6940) unf_res4_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6941) 	add.l		&0x4,%sp		# clear stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6942) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6944) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6945) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6946) #	ovf_res(): routine to produce the default overflow result of	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6947) #		   an overflowing number.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6948) #	ovf_res2(): same as above but the rnd mode/prec are passed	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6949) #		    differently.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6950) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6951) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6952) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6953) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6954) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6955) #	d1.b	= '-1' => (-); '0' => (+)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6956) #   ovf_res():								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6957) #	d0	= rnd mode/prec						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6958) #   ovf_res2():								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6959) #	hi(d0)	= rnd prec						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6960) #	lo(d0)	= rnd mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6961) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6962) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6963) #	a0	= points to extended precision result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6964) #	d0.b	= condition code bits					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6965) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6966) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6967) #	The default overflow result can be determined by the sign of	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6968) # the result and the rounding mode/prec in effect. These bits are	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6969) # concatenated together to create an index into the default result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6970) # table. A pointer to the correct result is returned in a0. The		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6971) # resulting condition codes are returned in d0 in case the caller	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6972) # doesn't want FPSR_cc altered (as is the case for fmove out).		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6973) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6974) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6976) 	global		ovf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6977) ovf_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6978) 	andi.w		&0x10,%d1		# keep result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6979) 	lsr.b		&0x4,%d0		# shift prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6980) 	or.b		%d0,%d1			# concat the two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6981) 	mov.w		%d1,%d0			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6982) 	lsl.b		&0x1,%d1		# multiply d1 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6983) 	bra.b		ovf_res_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6985) 	global		ovf_res2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6986) ovf_res2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6987) 	and.w		&0x10, %d1		# keep result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6988) 	or.b		%d0, %d1		# insert rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6989) 	swap		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6990) 	or.b		%d0, %d1		# insert rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6991) 	mov.w		%d1, %d0		# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6992) 	lsl.b		&0x1, %d1		# shift left by 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6994) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6995) # use the rounding mode, precision, and result sign as in index into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6996) # two tables below to fetch the default result and the result ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6997) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6998) ovf_res_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6999) 	mov.b		(tbl_ovfl_cc.b,%pc,%d0.w*1), %d0 # fetch result ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7000) 	lea		(tbl_ovfl_result.b,%pc,%d1.w*8), %a0 # return result ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7002) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7004) tbl_ovfl_cc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7005) 	byte		0x2, 0x0, 0x0, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7006) 	byte		0x2, 0x0, 0x0, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7007) 	byte		0x2, 0x0, 0x0, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7008) 	byte		0x0, 0x0, 0x0, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7009) 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7010) 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7011) 	byte		0x2+0x8, 0x8, 0x2+0x8, 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7013) tbl_ovfl_result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7014) 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7015) 	long		0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7016) 	long		0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7017) 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7019) 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7020) 	long		0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7021) 	long		0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7022) 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7024) 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7025) 	long		0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7026) 	long		0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7027) 	long		0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7029) 	long		0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7030) 	long		0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7031) 	long		0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7032) 	long		0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7034) 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7035) 	long		0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7036) 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7037) 	long		0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7039) 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7040) 	long		0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7041) 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7042) 	long		0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7044) 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7045) 	long		0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7046) 	long		0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7047) 	long		0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7049) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7050) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7051) #	fout(): move from fp register to memory or data register	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7052) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7053) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7054) #	_round() - needed to create EXOP for sgl/dbl precision		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7055) #	norm() - needed to create EXOP for extended precision		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7056) #	ovf_res() - create default overflow result for sgl/dbl precision#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7057) #	unf_res() - create default underflow result for sgl/dbl prec.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7058) #	dst_dbl() - create rounded dbl precision result.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7059) #	dst_sgl() - create rounded sgl precision result.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7060) #	fetch_dreg() - fetch dynamic k-factor reg for packed.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7061) #	bindec() - convert FP binary number to packed number.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7062) #	_mem_write() - write data to memory.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7063) #	_mem_write2() - write data to memory unless supv mode -(a7) exc.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7064) #	_dmem_write_{byte,word,long}() - write data to memory.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7065) #	store_dreg_{b,w,l}() - store data to data register file.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7066) #	facc_out_{b,w,l,d,x}() - data access error occurred.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7067) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7068) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7069) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7070) #	d0 = round prec,mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7071) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7072) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7073) #	fp0 : intermediate underflow or overflow result if		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7074) #	      OVFL/UNFL occurred for a sgl or dbl operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7075) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7076) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7077) #	This routine is accessed by many handlers that need to do an	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7078) # opclass three move of an operand out to memory.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7079) #	Decode an fmove out (opclass 3) instruction to determine if	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7080) # it's b,w,l,s,d,x, or p in size. b,w,l can be stored to either a data	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7081) # register or memory. The algorithm uses a standard "fmove" to create	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7082) # the rounded result. Also, since exceptions are disabled, this also	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7083) # create the correct OPERR default result if appropriate.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7084) #	For sgl or dbl precision, overflow or underflow can occur. If	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7085) # either occurs and is enabled, the EXOP.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7086) #	For extended precision, the stacked <ea> must be fixed along	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7087) # w/ the address index register as appropriate w/ _calc_ea_fout(). If	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7088) # the source is a denorm and if underflow is enabled, an EXOP must be	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7089) # created.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7090) #	For packed, the k-factor must be fetched from the instruction	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7091) # word or a data register. The <ea> must be fixed as w/ extended	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7092) # precision. Then, bindec() is called to create the appropriate		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7093) # packed result.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7094) #	If at any time an access error is flagged by one of the move-	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7095) # to-memory routines, then a special exit must be made so that the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7096) # access error can be handled properly.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7097) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7098) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7100) 	global		fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7101) fout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7102) 	bfextu		EXC_CMDREG(%a6){&3:&3},%d1 # extract dst fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7103) 	mov.w		(tbl_fout.b,%pc,%d1.w*2),%a1 # use as index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7104) 	jmp		(tbl_fout.b,%pc,%a1)	# jump to routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7106) 	swbeg		&0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7107) tbl_fout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7108) 	short		fout_long	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7109) 	short		fout_sgl	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7110) 	short		fout_ext	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7111) 	short		fout_pack	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7112) 	short		fout_word	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7113) 	short		fout_dbl	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7114) 	short		fout_byte	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7115) 	short		fout_pack	-	tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7117) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7118) # fmove.b out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7119) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7121) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7122) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7123) fout_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7124) 	tst.b		STAG(%a6)		# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7125) 	bne.b		fout_byte_denorm	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7127) 	fmovm.x		SRC(%a0),&0x80		# load value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7129) fout_byte_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7130) 	fmov.l		%d0,%fpcr		# insert rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7132) 	fmov.b		%fp0,%d0		# exec move out w/ correct rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7134) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7135) 	fmov.l		%fpsr,%d1		# fetch FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7136) 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7138) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7139) 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7140) 	beq.b		fout_byte_dn		# must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7142) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7143) 	bsr.l		_dmem_write_byte	# write byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7145) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7146) 	bne.l		facc_out_b		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7148) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7150) fout_byte_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7151) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7152) 	andi.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7153) 	bsr.l		store_dreg_b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7154) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7156) fout_byte_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7157) 	mov.l		SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7158) 	andi.l		&0x80000000,%d1		# keep DENORM sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7159) 	ori.l		&0x00800000,%d1		# make smallest sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7160) 	fmov.s		%d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7161) 	bra.b		fout_byte_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7163) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7164) # fmove.w out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7165) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7167) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7168) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7169) fout_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7170) 	tst.b		STAG(%a6)		# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7171) 	bne.b		fout_word_denorm	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7173) 	fmovm.x		SRC(%a0),&0x80		# load value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7175) fout_word_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7176) 	fmov.l		%d0,%fpcr		# insert rnd prec:mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7178) 	fmov.w		%fp0,%d0		# exec move out w/ correct rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7180) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7181) 	fmov.l		%fpsr,%d1		# fetch FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7182) 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7184) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7185) 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7186) 	beq.b		fout_word_dn		# must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7188) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7189) 	bsr.l		_dmem_write_word	# write word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7191) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7192) 	bne.l		facc_out_w		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7194) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7196) fout_word_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7197) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7198) 	andi.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7199) 	bsr.l		store_dreg_w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7200) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7202) fout_word_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7203) 	mov.l		SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7204) 	andi.l		&0x80000000,%d1		# keep DENORM sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7205) 	ori.l		&0x00800000,%d1		# make smallest sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7206) 	fmov.s		%d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7207) 	bra.b		fout_word_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7209) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7210) # fmove.l out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7211) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7213) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7214) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7215) fout_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7216) 	tst.b		STAG(%a6)		# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7217) 	bne.b		fout_long_denorm	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7219) 	fmovm.x		SRC(%a0),&0x80		# load value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7221) fout_long_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7222) 	fmov.l		%d0,%fpcr		# insert rnd prec:mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7224) 	fmov.l		%fp0,%d0		# exec move out w/ correct rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7226) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7227) 	fmov.l		%fpsr,%d1		# fetch FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7228) 	or.w		%d1,2+USER_FPSR(%a6)	# save new exc,accrued bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7230) fout_long_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7231) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7232) 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7233) 	beq.b		fout_long_dn		# must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7235) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7236) 	bsr.l		_dmem_write_long	# write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7238) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7239) 	bne.l		facc_out_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7241) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7243) fout_long_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7244) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7245) 	andi.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7246) 	bsr.l		store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7247) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7249) fout_long_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7250) 	mov.l		SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7251) 	andi.l		&0x80000000,%d1		# keep DENORM sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7252) 	ori.l		&0x00800000,%d1		# make smallest sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7253) 	fmov.s		%d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7254) 	bra.b		fout_long_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7256) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7257) # fmove.x out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7258) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7260) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7261) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7262) # The DENORM causes an Underflow exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7263) fout_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7265) # we copy the extended precision result to FP_SCR0 so that the reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7266) # 16-bit field gets zeroed. we do this since we promise not to disturb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7267) # what's at SRC(a0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7268) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7269) 	clr.w		2+FP_SCR0_EX(%a6)	# clear reserved field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7270) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7271) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7273) 	fmovm.x		SRC(%a0),&0x80		# return result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7275) 	bsr.l		_calc_ea_fout		# fix stacked <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7277) 	mov.l		%a0,%a1			# pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7278) 	lea		FP_SCR0(%a6),%a0	# pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7279) 	mov.l		&0xc,%d0		# pass: opsize is 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7281) # we must not yet write the extended precision data to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7282) # in the pre-decrement case from supervisor mode or else we'll corrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7283) # the stack frame. so, leave it in FP_SRC for now and deal with it later...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7284) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7285) 	beq.b		fout_ext_a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7287) 	bsr.l		_dmem_write		# write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7289) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7290) 	bne.w		fout_ext_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7292) 	tst.b		STAG(%a6)		# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7293) 	bne.b		fout_ext_denorm		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7294) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7296) # the number is a DENORM. must set the underflow exception bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7297) fout_ext_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7298) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set underflow exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7300) 	mov.b		FPCR_ENABLE(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7301) 	andi.b		&0x0a,%d0		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7302) 	bne.b		fout_ext_exc		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7303) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7305) # we don't want to do the write if the exception occurred in supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7306) # so _mem_write2() handles this for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7307) fout_ext_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7308) 	bsr.l		_mem_write2		# write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7310) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7311) 	bne.w		fout_ext_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7313) 	tst.b		STAG(%a6)		# is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7314) 	bne.b		fout_ext_denorm		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7315) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7317) fout_ext_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7318) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7319) 	bsr.l		norm			# normalize the mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7320) 	neg.w		%d0			# new exp = -(shft amt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7321) 	andi.w		&0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7322) 	andi.w		&0x8000,FP_SCR0_EX(%a6)	# keep only old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7323) 	or.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7324) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7325) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7327) fout_ext_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7328) 	mov.l		EXC_A6(%a6),(%a6)	# fix stacked a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7329) 	bra.l		facc_out_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7331) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7332) # fmove.s out ###########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7333) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7334) fout_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7335) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7336) 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7337) 	mov.l		%d0,L_SCR3(%a6)		# save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7339) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7340) # operand is a normalized number. first, we check to see if the move out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7341) # would cause either an underflow or overflow. these cases are handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7342) # separately. otherwise, set the FPCR to the proper rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7343) # execute the move.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7344) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7345) 	mov.w		SRC_EX(%a0),%d0		# extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7346) 	andi.w		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7348) 	cmpi.w		%d0,&SGL_HI		# will operand overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7349) 	bgt.w		fout_sgl_ovfl		# yes; go handle OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7350) 	beq.w		fout_sgl_may_ovfl	# maybe; go handle possible OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7351) 	cmpi.w		%d0,&SGL_LO		# will operand underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7352) 	blt.w		fout_sgl_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7354) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7355) # NORMs(in range) can be stored out by a simple "fmov.s"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7356) # Unnormalized inputs can come through this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7357) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7358) fout_sgl_exg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7359) 	fmovm.x		SRC(%a0),&0x80		# fetch fop from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7361) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7362) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7364) 	fmov.s		%fp0,%d0		# store does convert and round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7366) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7367) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7369) 	or.w		%d1,2+USER_FPSR(%a6)	# set possible inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7371) fout_sgl_exg_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7372) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7373) 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7374) 	beq.b		fout_sgl_exg_write_dn	# must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7376) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7377) 	bsr.l		_dmem_write_long	# write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7379) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7380) 	bne.l		facc_out_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7382) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7384) fout_sgl_exg_write_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7385) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7386) 	andi.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7387) 	bsr.l		store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7388) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7390) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7391) # here, we know that the operand would UNFL if moved out to single prec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7392) # so, denorm and round and then use generic store single routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7393) # write the value to memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7394) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7395) fout_sgl_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7396) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7398) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7399) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7400) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7401) 	mov.l		%a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7403) 	clr.l		%d0			# pass: S.F. = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7405) 	cmpi.b		STAG(%a6),&DENORM	# fetch src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7406) 	bne.b		fout_sgl_unfl_cont	# let DENORMs fall through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7408) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7409) 	bsr.l		norm			# normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7411) fout_sgl_unfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7412) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7413) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7414) 	bsr.l		unf_res			# calc default underflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7416) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to fop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7417) 	bsr.l		dst_sgl			# convert to single prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7419) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7420) 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7421) 	beq.b		fout_sgl_unfl_dn	# must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7423) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7424) 	bsr.l		_dmem_write_long	# write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7426) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7427) 	bne.l		facc_out_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7429) 	bra.b		fout_sgl_unfl_chkexc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7431) fout_sgl_unfl_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7432) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7433) 	andi.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7434) 	bsr.l		store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7436) fout_sgl_unfl_chkexc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7437) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7438) 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7439) 	bne.w		fout_sd_exc_unfl	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7440) 	addq.l		&0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7441) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7443) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7444) # it's definitely an overflow so call ovf_res to get the correct answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7445) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7446) fout_sgl_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7447) 	tst.b		3+SRC_HI(%a0)		# is result inexact?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7448) 	bne.b		fout_sgl_ovfl_inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7449) 	tst.l		SRC_LO(%a0)		# is result inexact?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7450) 	bne.b		fout_sgl_ovfl_inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7451) 	ori.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7452) 	bra.b		fout_sgl_ovfl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7453) fout_sgl_ovfl_inex2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7454) 	ori.w		&ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7456) fout_sgl_ovfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7457) 	mov.l		%a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7459) # call ovf_res() w/ sgl prec and the correct rnd mode to create the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7460) # overflow result. DON'T save the returned ccodes from ovf_res() since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7461) # fmove out doesn't alter them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7462) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7463) 	smi		%d1			# set if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7464) 	mov.l		L_SCR3(%a6),%d0		# pass: sgl prec,rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7465) 	bsr.l		ovf_res			# calc OVFL result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7466) 	fmovm.x		(%a0),&0x80		# load default overflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7467) 	fmov.s		%fp0,%d0		# store to single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7469) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7470) 	andi.b		&0x38,%d1		# is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7471) 	beq.b		fout_sgl_ovfl_dn	# must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7473) 	mov.l		EXC_EA(%a6),%a0		# stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7474) 	bsr.l		_dmem_write_long	# write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7476) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7477) 	bne.l		facc_out_l		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7479) 	bra.b		fout_sgl_ovfl_chkexc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7481) fout_sgl_ovfl_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7482) 	mov.b		1+EXC_OPWORD(%a6),%d1	# extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7483) 	andi.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7484) 	bsr.l		store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7486) fout_sgl_ovfl_chkexc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7487) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7488) 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7489) 	bne.w		fout_sd_exc_ovfl	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7490) 	addq.l		&0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7491) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7493) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7494) # move out MAY overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7495) # (1) force the exp to 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7496) # (2) do a move w/ appropriate rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7497) # (3) if exp still equals zero, then insert original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7498) #	for the correct result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7499) #     if exp now equals one, then it overflowed so call ovf_res.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7500) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7501) fout_sgl_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7502) 	mov.w		SRC_EX(%a0),%d1		# fetch current sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7503) 	andi.w		&0x8000,%d1		# keep it,clear exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7504) 	ori.w		&0x3fff,%d1		# insert exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7505) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert scaled exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7506) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7507) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7509) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7511) 	fmov.x		FP_SCR0(%a6),%fp0	# force fop to be rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7512) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7514) 	fabs.x		%fp0			# need absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7515) 	fcmp.b		%fp0,&0x2		# did exponent increase?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7516) 	fblt.w		fout_sgl_exg		# no; go finish NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7517) 	bra.w		fout_sgl_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7519) ################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7521) fout_sd_exc_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7522) 	mov.l		(%sp)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7524) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7525) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7526) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7528) 	cmpi.b		STAG(%a6),&DENORM	# was src a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7529) 	bne.b		fout_sd_exc_cont	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7531) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7532) 	bsr.l		norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7533) 	neg.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7534) 	andi.w		&0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7535) 	bfins		%d0,FP_SCR0_EX(%a6){&1:&15}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7536) 	bra.b		fout_sd_exc_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7538) fout_sd_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7539) fout_sd_exc_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7540) 	mov.l		(%sp)+,%a0		# restore a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7542) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7543) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7544) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7546) fout_sd_exc_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7547) 	bclr		&0x7,FP_SCR0_EX(%a6)	# clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7548) 	sne.b		2+FP_SCR0_EX(%a6)	# set internal sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7549) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7551) 	mov.b		3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7552) 	lsr.b		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7553) 	andi.w		&0x0c,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7554) 	swap		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7555) 	mov.b		3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7556) 	lsr.b		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7557) 	andi.w		&0x03,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7558) 	clr.l		%d0			# pass: zero g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7559) 	bsr.l		_round			# round the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7561) 	tst.b		2+FP_SCR0_EX(%a6)	# is EXOP negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7562) 	beq.b		fout_sd_exc_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7563) 	bset		&0x7,FP_SCR0_EX(%a6)	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7565) fout_sd_exc_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7566) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7567) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7569) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7570) # fmove.d out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7571) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7572) fout_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7573) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7574) 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7575) 	mov.l		%d0,L_SCR3(%a6)		# save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7577) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7578) # operand is a normalized number. first, we check to see if the move out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7579) # would cause either an underflow or overflow. these cases are handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7580) # separately. otherwise, set the FPCR to the proper rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7581) # execute the move.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7582) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7583) 	mov.w		SRC_EX(%a0),%d0		# extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7584) 	andi.w		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7586) 	cmpi.w		%d0,&DBL_HI		# will operand overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7587) 	bgt.w		fout_dbl_ovfl		# yes; go handle OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7588) 	beq.w		fout_dbl_may_ovfl	# maybe; go handle possible OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7589) 	cmpi.w		%d0,&DBL_LO		# will operand underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7590) 	blt.w		fout_dbl_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7592) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7593) # NORMs(in range) can be stored out by a simple "fmov.d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7594) # Unnormalized inputs can come through this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7595) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7596) fout_dbl_exg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7597) 	fmovm.x		SRC(%a0),&0x80		# fetch fop from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7599) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7600) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7602) 	fmov.d		%fp0,L_SCR1(%a6)	# store does convert and round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7604) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7605) 	fmov.l		%fpsr,%d0		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7607) 	or.w		%d0,2+USER_FPSR(%a6)	# set possible inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7609) 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7610) 	lea		L_SCR1(%a6),%a0		# pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7611) 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7612) 	bsr.l		_dmem_write		# store dbl fop to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7614) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7615) 	bne.l		facc_out_d		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7617) 	rts					# no; so we're finished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7619) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7620) # here, we know that the operand would UNFL if moved out to double prec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7621) # so, denorm and round and then use generic store double routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7622) # write the value to memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7623) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7624) fout_dbl_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7625) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7627) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7628) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7629) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7630) 	mov.l		%a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7632) 	clr.l		%d0			# pass: S.F. = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7634) 	cmpi.b		STAG(%a6),&DENORM	# fetch src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7635) 	bne.b		fout_dbl_unfl_cont	# let DENORMs fall through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7637) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7638) 	bsr.l		norm			# normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7640) fout_dbl_unfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7641) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7642) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7643) 	bsr.l		unf_res			# calc default underflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7645) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to fop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7646) 	bsr.l		dst_dbl			# convert to single prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7647) 	mov.l		%d0,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7648) 	mov.l		%d1,L_SCR2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7650) 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7651) 	lea		L_SCR1(%a6),%a0		# pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7652) 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7653) 	bsr.l		_dmem_write		# store dbl fop to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7655) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7656) 	bne.l		facc_out_d		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7658) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7659) 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7660) 	bne.w		fout_sd_exc_unfl	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7661) 	addq.l		&0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7662) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7664) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7665) # it's definitely an overflow so call ovf_res to get the correct answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7666) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7667) fout_dbl_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7668) 	mov.w		2+SRC_LO(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7669) 	andi.w		&0x7ff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7670) 	bne.b		fout_dbl_ovfl_inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7672) 	ori.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7673) 	bra.b		fout_dbl_ovfl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7674) fout_dbl_ovfl_inex2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7675) 	ori.w		&ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7677) fout_dbl_ovfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7678) 	mov.l		%a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7680) # call ovf_res() w/ dbl prec and the correct rnd mode to create the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7681) # overflow result. DON'T save the returned ccodes from ovf_res() since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7682) # fmove out doesn't alter them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7683) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7684) 	smi		%d1			# set if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7685) 	mov.l		L_SCR3(%a6),%d0		# pass: dbl prec,rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7686) 	bsr.l		ovf_res			# calc OVFL result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7687) 	fmovm.x		(%a0),&0x80		# load default overflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7688) 	fmov.d		%fp0,L_SCR1(%a6)	# store to double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7690) 	mov.l		EXC_EA(%a6),%a1		# pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7691) 	lea		L_SCR1(%a6),%a0		# pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7692) 	movq.l		&0x8,%d0		# pass: opsize is 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7693) 	bsr.l		_dmem_write		# store dbl fop to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7695) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7696) 	bne.l		facc_out_d		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7698) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7699) 	andi.b		&0x0a,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7700) 	bne.w		fout_sd_exc_ovfl	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7701) 	addq.l		&0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7702) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7704) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7705) # move out MAY overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7706) # (1) force the exp to 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7707) # (2) do a move w/ appropriate rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7708) # (3) if exp still equals zero, then insert original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7709) #	for the correct result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7710) #     if exp now equals one, then it overflowed so call ovf_res.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7711) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7712) fout_dbl_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7713) 	mov.w		SRC_EX(%a0),%d1		# fetch current sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7714) 	andi.w		&0x8000,%d1		# keep it,clear exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7715) 	ori.w		&0x3fff,%d1		# insert exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7716) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert scaled exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7717) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7718) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7720) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7722) 	fmov.x		FP_SCR0(%a6),%fp0	# force fop to be rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7723) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7725) 	fabs.x		%fp0			# need absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7726) 	fcmp.b		%fp0,&0x2		# did exponent increase?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7727) 	fblt.w		fout_dbl_exg		# no; go finish NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7728) 	bra.w		fout_dbl_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7730) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7731) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7732) #	dst_dbl(): create double precision value from extended prec.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7733) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7734) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7735) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7736) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7737) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7738) #	a0 = pointer to source operand in extended precision		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7739) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7740) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7741) #	d0 = hi(double precision result)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7742) #	d1 = lo(double precision result)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7743) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7744) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7745) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7746) #  Changes extended precision to double precision.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7747) #  Note: no attempt is made to round the extended value to double.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7748) #	dbl_sign = ext_sign						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7749) #	dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7750) #	get rid of ext integer bit					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7751) #	dbl_mant = ext_mant{62:12}					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7752) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7753) #		---------------   ---------------    ---------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7754) #  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7755) #		---------------   ---------------    ---------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7756) #		 95	    64    63 62	      32      31     11	  0	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7757) #				     |			     |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7758) #				     |			     |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7759) #				     |			     |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7760) #			             v			     v		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7761) #			      ---------------   ---------------		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7762) #  double   ->		      |s|exp| mant  |   |  mant       |		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7763) #			      ---------------   ---------------		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7764) #			      63     51   32   31	       0	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7765) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7766) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7768) dst_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7769) 	clr.l		%d0			# clear d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7770) 	mov.w		FTEMP_EX(%a0),%d0	# get exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7771) 	subi.w		&EXT_BIAS,%d0		# subtract extended precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7772) 	addi.w		&DBL_BIAS,%d0		# add double precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7773) 	tst.b		FTEMP_HI(%a0)		# is number a denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7774) 	bmi.b		dst_get_dupper		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7775) 	subq.w		&0x1,%d0		# yes; denorm bias = DBL_BIAS - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7776) dst_get_dupper:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7777) 	swap		%d0			# d0 now in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7778) 	lsl.l		&0x4,%d0		# d0 in proper place for dbl prec exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7779) 	tst.b		FTEMP_EX(%a0)		# test sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7780) 	bpl.b		dst_get_dman		# if positive, go process mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7781) 	bset		&0x1f,%d0		# if negative, set sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7782) dst_get_dman:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7783) 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7784) 	bfextu		%d1{&1:&20},%d1		# get upper 20 bits of ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7785) 	or.l		%d1,%d0			# put these bits in ms word of double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7786) 	mov.l		%d0,L_SCR1(%a6)		# put the new exp back on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7787) 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7788) 	mov.l		&21,%d0			# load shift count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7789) 	lsl.l		%d0,%d1			# put lower 11 bits in upper bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7790) 	mov.l		%d1,L_SCR2(%a6)		# build lower lword in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7791) 	mov.l		FTEMP_LO(%a0),%d1	# get ls mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7792) 	bfextu		%d1{&0:&21},%d0		# get ls 21 bits of double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7793) 	mov.l		L_SCR2(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7794) 	or.l		%d0,%d1			# put them in double result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7795) 	mov.l		L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7796) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7798) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7799) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7800) #	dst_sgl(): create single precision value from extended prec	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7801) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7802) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7803) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7804) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7805) #	a0 = pointer to source operand in extended precision		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7806) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7807) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7808) #	d0 = single precision result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7809) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7810) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7811) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7812) # Changes extended precision to single precision.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7813) #	sgl_sign = ext_sign						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7814) #	sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7815) #	get rid of ext integer bit					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7816) #	sgl_mant = ext_mant{62:12}					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7817) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7818) #		---------------   ---------------    ---------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7819) #  extended ->  |s|    exp    |   |1| ms mant   |    | ls mant     |	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7820) #		---------------   ---------------    ---------------	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7821) #		 95	    64    63 62	   40 32      31     12	  0	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7822) #				     |	   |				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7823) #				     |	   |				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7824) #				     |	   |				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7825) #			             v     v				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7826) #			      ---------------				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7827) #  single   ->		      |s|exp| mant  |				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7828) #			      ---------------				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7829) #			      31     22     0				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7830) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7831) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7833) dst_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7834) 	clr.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7835) 	mov.w		FTEMP_EX(%a0),%d0	# get exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7836) 	subi.w		&EXT_BIAS,%d0		# subtract extended precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7837) 	addi.w		&SGL_BIAS,%d0		# add single precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7838) 	tst.b		FTEMP_HI(%a0)		# is number a denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7839) 	bmi.b		dst_get_supper		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7840) 	subq.w		&0x1,%d0		# yes; denorm bias = SGL_BIAS - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7841) dst_get_supper:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7842) 	swap		%d0			# put exp in upper word of d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7843) 	lsl.l		&0x7,%d0		# shift it into single exp bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7844) 	tst.b		FTEMP_EX(%a0)		# test sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7845) 	bpl.b		dst_get_sman		# if positive, continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7846) 	bset		&0x1f,%d0		# if negative, put in sign first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7847) dst_get_sman:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7848) 	mov.l		FTEMP_HI(%a0),%d1	# get ms mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7849) 	andi.l		&0x7fffff00,%d1		# get upper 23 bits of ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7850) 	lsr.l		&0x8,%d1		# and put them flush right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7851) 	or.l		%d1,%d0			# put these bits in ms word of single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7852) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7854) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7855) fout_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7856) 	bsr.l		_calc_ea_fout		# fetch the <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7857) 	mov.l		%a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7859) 	mov.b		STAG(%a6),%d0		# fetch input type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7860) 	bne.w		fout_pack_not_norm	# input is not NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7862) fout_pack_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7863) 	btst		&0x4,EXC_CMDREG(%a6)	# static or dynamic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7864) 	beq.b		fout_pack_s		# static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7866) fout_pack_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7867) 	mov.b		1+EXC_CMDREG(%a6),%d1	# fetch dynamic reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7868) 	lsr.b		&0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7869) 	andi.w		&0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7871) 	bsr.l		fetch_dreg		# fetch Dn w/ k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7873) 	bra.b		fout_pack_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7874) fout_pack_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7875) 	mov.b		1+EXC_CMDREG(%a6),%d0	# fetch static field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7877) fout_pack_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7878) 	bfexts		%d0{&25:&7},%d0		# extract k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7879) 	mov.l	%d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7881) 	lea		FP_SRC(%a6),%a0		# pass: ptr to input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7883) # bindec is currently scrambling FP_SRC for denorm inputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7884) # we'll have to change this, but for now, tough luck!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7885) 	bsr.l		bindec			# convert xprec to packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7887) #	andi.l		&0xcfff000f,FP_SCR0(%a6) # clear unused fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7888) 	andi.l		&0xcffff00f,FP_SCR0(%a6) # clear unused fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7890) 	mov.l	(%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7892) 	tst.b		3+FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7893) 	bne.b		fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7894) 	tst.l		FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7895) 	bne.b		fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7896) 	tst.l		FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7897) 	bne.b		fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7899) # add the extra condition that only if the k-factor was zero, too, should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7900) # we zero the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7901) 	tst.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7902) 	bne.b		fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7903) # "mantissa" is all zero which means that the answer is zero. but, the '040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7904) # algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7905) # if the mantissa is zero, I will zero the exponent, too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7906) # the question now is whether the exponents sign bit is allowed to be non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7907) # for a zero, also...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7908) 	andi.w		&0xf000,FP_SCR0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7910) fout_pack_set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7912) 	lea		FP_SCR0(%a6),%a0	# pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7914) fout_pack_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7915) 	mov.l		(%sp)+,%a1		# pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7916) 	mov.l		&0xc,%d0		# pass: opsize is 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7918) 	cmpi.b		SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7919) 	beq.b		fout_pack_a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7921) 	bsr.l		_dmem_write		# write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7923) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7924) 	bne.w		fout_ext_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7926) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7928) # we don't want to do the write if the exception occurred in supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7929) # so _mem_write2() handles this for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7930) fout_pack_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7931) 	bsr.l		_mem_write2		# write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7933) 	tst.l		%d1			# did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7934) 	bne.w		fout_ext_err		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7936) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7938) fout_pack_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7939) 	cmpi.b		%d0,&DENORM		# is it a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7940) 	beq.w		fout_pack_norm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7941) 	lea		FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7942) 	clr.w		2+FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7943) 	cmpi.b		%d0,&SNAN		# is it an SNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7944) 	beq.b		fout_pack_snan		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7945) 	bra.b		fout_pack_write		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7947) fout_pack_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7948) 	ori.w		&snaniop2_mask,FPSR_EXCEPT(%a6) # set SNAN/AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7949) 	bset		&0x6,FP_SRC_HI(%a6)	# set snan bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7950) 	bra.b		fout_pack_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7952) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7953) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7954) #	fmul(): emulates the fmul instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7955) #	fsmul(): emulates the fsmul instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7956) #	fdmul(): emulates the fdmul instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7957) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7958) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7959) #	scale_to_zero_src() - scale src exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7960) #	scale_to_zero_dst() - scale dst exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7961) #	unf_res() - return default underflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7962) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7963) #	res_qnan() - return QNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7964) #	res_snan() - return SNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7965) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7966) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7967) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7968) #	a1 = pointer to extended precision destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7969) #	d0  rnd prec,mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7970) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7971) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7972) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7973) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7974) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7975) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7976) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7977) # norms/denorms into ext/sgl/dbl precision.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7978) #	For norms/denorms, scale the exponents such that a multiply	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7979) # instruction won't cause an exception. Use the regular fmul to		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7980) # compute a result. Check if the regular operands would have taken	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7981) # an exception. If so, return the default overflow/underflow result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7982) # and return the EXOP if exceptions are enabled. Else, scale the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7983) # result operand to the proper exponent.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7984) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7985) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7987) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7988) tbl_fmul_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7989) 	long		0x3fff - 0x7ffe		# ext_max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7990) 	long		0x3fff - 0x407e		# sgl_max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7991) 	long		0x3fff - 0x43fe		# dbl_max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7992) tbl_fmul_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7993) 	long		0x3fff + 0x0001		# ext_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7994) 	long		0x3fff - 0x3f80		# sgl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7995) 	long		0x3fff - 0x3c00		# dbl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7997) 	global		fsmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7998) fsmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7999) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8000) 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8001) 	bra.b		fmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8003) 	global		fdmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8004) fdmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8005) 	andi.b		&0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8006) 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8008) 	global		fmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8009) fmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8010) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8012) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8013) 	mov.b		DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8014) 	lsl.b		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8015) 	or.b		STAG(%a6),%d1		# combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8016) 	bne.w		fmul_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8018) fmul_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8019) 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8020) 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8021) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8023) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8024) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8025) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8027) 	bsr.l		scale_to_zero_src	# scale src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8028) 	mov.l		%d0,-(%sp)		# save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8030) 	bsr.l		scale_to_zero_dst	# scale dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8032) 	add.l		%d0,(%sp)		# SCALE_FACTOR = scale1 + scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8034) 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8035) 	lsr.b		&0x6,%d1		# shift to lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8036) 	mov.l		(%sp)+,%d0		# load S.F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8037) 	cmp.l		%d0,(tbl_fmul_ovfl.w,%pc,%d1.w*4) # would result ovfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8038) 	beq.w		fmul_may_ovfl		# result may rnd to overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8039) 	blt.w		fmul_ovfl		# result will overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8041) 	cmp.l		%d0,(tbl_fmul_unfl.w,%pc,%d1.w*4) # would result unfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8042) 	beq.w		fmul_may_unfl		# result may rnd to no unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8043) 	bgt.w		fmul_unfl		# result will underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8045) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8046) # NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8047) # - the result of the multiply operation will neither overflow nor underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8048) # - do the multiply to the proper precision and rounding mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8049) # - scale the result exponent using the scale factor. if both operands were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8050) # normalized then we really don't need to go through this scaling. but for now,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8051) # this will do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8052) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8053) fmul_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8054) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8056) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8057) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8059) 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8061) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8062) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8064) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8066) fmul_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8067) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8068) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8069) 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8070) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8071) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8072) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8073) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8074) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8075) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8076) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8077) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8078) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8080) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8081) # OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8082) # - the result of the multiply operation is an overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8083) # - do the multiply to the proper precision and rounding mode in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8084) # set the inexact bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8085) # - calculate the default result and return it in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8086) # - if overflow or inexact is enabled, we need a multiply result rounded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8087) # extended precision. if the original operation was extended, then we have this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8088) # result. if the original operation was single or double, we have to do another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8089) # multiply using extended precision and the correct rounding mode. the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8090) # of this operation then has its exponent scaled by -0x6000 to create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8091) # exceptional operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8092) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8093) fmul_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8094) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8096) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8097) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8099) 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8101) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8102) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8104) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8106) # save setting this until now because this is where fmul_may_ovfl may jump in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8107) fmul_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8108) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8110) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8111) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8112) 	bne.b		fmul_ovfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8114) # calculate the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8115) fmul_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8116) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8117) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8118) 	mov.l		L_SCR3(%a6),%d0		# pass rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8119) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8120) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8121) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8122) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8124) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8125) # OVFL is enabled; Create EXOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8126) # - if precision is extended, then we have the EXOP. simply bias the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8127) # with an extra -0x6000. if the precision is single or double, we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8128) # calculate a result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8129) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8130) fmul_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8131) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8132) 	andi.b		&0xc0,%d1		# test the rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8133) 	bne.b		fmul_ovfl_ena_sd	# it's sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8135) fmul_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8136) 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8138) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8139) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8140) 	mov.w		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8141) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8142) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8143) 	subi.l		&0x6000,%d1		# subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8144) 	andi.w		&0x7fff,%d1		# clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8145) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8146) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8147) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8148) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8149) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8150) 	bra.b		fmul_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8152) fmul_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8153) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8155) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8156) 	andi.b		&0x30,%d1		# keep rnd mode only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8157) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8159) 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8161) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8162) 	bra.b		fmul_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8164) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8165) # may OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8166) # - the result of the multiply operation MAY overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8167) # - do the multiply to the proper precision and rounding mode in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8168) # set the inexact bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8169) # - calculate the default result and return it in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8170) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8171) fmul_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8172) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8174) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8175) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8177) 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8179) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8180) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8182) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8184) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8185) 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8186) 	fbge.w		fmul_ovfl_tst		# yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8188) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8189) 	bra.w		fmul_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8191) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8192) # UNDERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8193) # - the result of the multiply operation is an underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8194) # - do the multiply to the proper precision and rounding mode in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8195) # set the inexact bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8196) # - calculate the default result and return it in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8197) # - if overflow or inexact is enabled, we need a multiply result rounded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8198) # extended precision. if the original operation was extended, then we have this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8199) # result. if the original operation was single or double, we have to do another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8200) # multiply using extended precision and the correct rounding mode. the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8201) # of this operation then has its exponent scaled by -0x6000 to create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8202) # exceptional operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8203) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8204) fmul_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8205) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8207) # for fun, let's use only extended precision, round to zero. then, let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8208) # the unf_res() routine figure out all the rest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8209) # will we get the correct answer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8210) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8212) 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8213) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8215) 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8217) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8218) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8220) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8222) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8223) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8224) 	bne.b		fmul_unfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8226) fmul_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8227) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8229) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8230) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8231) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8232) 	or.b		%d0,FPSR_CC(%a6)	# unf_res2 may have set 'Z'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8233) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8234) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8236) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8237) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8238) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8239) fmul_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8240) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8242) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8243) 	andi.b		&0xc0,%d1		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8244) 	bne.b		fmul_unfl_ena_sd	# no, sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8246) # if the rnd mode is anything but RZ, then we have to re-do the above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8247) # multiplication because we used RZ for all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8248) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8250) fmul_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8251) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8253) 	fmul.x		FP_SCR0(%a6),%fp1	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8255) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8257) 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8258) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8259) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8260) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8261) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8262) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8263) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8264) 	addi.l		&0x6000,%d1		# add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8265) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8266) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8267) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8268) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8269) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8270) 	bra.w		fmul_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8272) fmul_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8273) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8274) 	andi.b		&0x30,%d1		# use only rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8275) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8277) 	bra.b		fmul_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8279) # MAY UNDERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8280) # -use the correct rounding mode and precision. this code favors operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8281) # that do not underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8282) fmul_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8283) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8285) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8286) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8288) 	fmul.x		FP_SCR0(%a6),%fp0	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8290) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8291) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8293) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8295) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8296) 	fcmp.b		%fp1,&0x2		# is |result| > 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8297) 	fbgt.w		fmul_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8298) 	fblt.w		fmul_unfl		# yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8300) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8301) # we still don't know if underflow occurred. result is ~ equal to 2. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8302) # we don't know if the result was an underflow that rounded up to a 2 or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8303) # a normalized number that rounded down to a 2. so, redo the entire operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8304) # using RZ as the rounding mode to see what the pre-rounded result is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8305) # this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8306) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8307) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8309) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8310) 	andi.b		&0xc0,%d1		# keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8311) 	ori.b		&rz_mode*0x10,%d1	# insert RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8313) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8314) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8316) 	fmul.x		FP_SCR0(%a6),%fp1	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8318) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8319) 	fabs.x		%fp1			# make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8320) 	fcmp.b		%fp1,&0x2		# is |result| < 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8321) 	fbge.w		fmul_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8322) 	bra.w		fmul_unfl		# yes, underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8324) ################################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8326) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8327) # Multiply: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8328) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8329) fmul_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8330) 	mov.w		(tbl_fmul_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8331) 	jmp		(tbl_fmul_op.b,%pc,%d1.w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8333) 	swbeg		&48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8334) tbl_fmul_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8335) 	short		fmul_norm	- tbl_fmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8336) 	short		fmul_zero	- tbl_fmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8337) 	short		fmul_inf_src	- tbl_fmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8338) 	short		fmul_res_qnan	- tbl_fmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8339) 	short		fmul_norm	- tbl_fmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8340) 	short		fmul_res_snan	- tbl_fmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8341) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8342) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8344) 	short		fmul_zero	- tbl_fmul_op # ZERO x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8345) 	short		fmul_zero	- tbl_fmul_op # ZERO x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8346) 	short		fmul_res_operr	- tbl_fmul_op # ZERO x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8347) 	short		fmul_res_qnan	- tbl_fmul_op # ZERO x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8348) 	short		fmul_zero	- tbl_fmul_op # ZERO x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8349) 	short		fmul_res_snan	- tbl_fmul_op # ZERO x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8350) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8351) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8353) 	short		fmul_inf_dst	- tbl_fmul_op # INF x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8354) 	short		fmul_res_operr	- tbl_fmul_op # INF x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8355) 	short		fmul_inf_dst	- tbl_fmul_op # INF x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8356) 	short		fmul_res_qnan	- tbl_fmul_op # INF x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8357) 	short		fmul_inf_dst	- tbl_fmul_op # INF x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8358) 	short		fmul_res_snan	- tbl_fmul_op # INF x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8359) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8360) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8362) 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8363) 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8364) 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8365) 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8366) 	short		fmul_res_qnan	- tbl_fmul_op # QNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8367) 	short		fmul_res_snan	- tbl_fmul_op # QNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8368) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8369) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8371) 	short		fmul_norm	- tbl_fmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8372) 	short		fmul_zero	- tbl_fmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8373) 	short		fmul_inf_src	- tbl_fmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8374) 	short		fmul_res_qnan	- tbl_fmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8375) 	short		fmul_norm	- tbl_fmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8376) 	short		fmul_res_snan	- tbl_fmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8377) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8378) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8380) 	short		fmul_res_snan	- tbl_fmul_op # SNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8381) 	short		fmul_res_snan	- tbl_fmul_op # SNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8382) 	short		fmul_res_snan	- tbl_fmul_op # SNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8383) 	short		fmul_res_snan	- tbl_fmul_op # SNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8384) 	short		fmul_res_snan	- tbl_fmul_op # SNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8385) 	short		fmul_res_snan	- tbl_fmul_op # SNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8386) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8387) 	short		tbl_fmul_op	- tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8389) fmul_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8390) 	bra.l		res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8391) fmul_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8392) 	bra.l		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8393) fmul_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8394) 	bra.l		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8396) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8397) # Multiply: (Zero x Zero) || (Zero x norm) || (Zero x denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8398) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8399) 	global		fmul_zero		# global for fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8400) fmul_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8401) 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8402) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8403) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8404) 	bpl.b		fmul_zero_p		# result ZERO is pos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8405) fmul_zero_n:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8406) 	fmov.s		&0x80000000,%fp0	# load -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8407) 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8408) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8409) fmul_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8410) 	fmov.s		&0x00000000,%fp0	# load +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8411) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8412) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8414) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8415) # Multiply: (inf x inf) || (inf x norm) || (inf x denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8416) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8417) # Note: The j-bit for an infinity is a don't-care. However, to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8418) # strictly compatible w/ the 68881/882, we make sure to return an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8419) # INF w/ the j-bit set if the input INF j-bit was set. Destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8420) # INFs take priority.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8421) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8422) 	global		fmul_inf_dst		# global for fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8423) fmul_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8424) 	fmovm.x		DST(%a1),&0x80		# return INF result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8425) 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8426) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8427) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8428) 	bpl.b		fmul_inf_dst_p		# result INF is pos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8429) fmul_inf_dst_n:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8430) 	fabs.x		%fp0			# clear result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8431) 	fneg.x		%fp0			# set result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8432) 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8433) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8434) fmul_inf_dst_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8435) 	fabs.x		%fp0			# clear result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8436) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8437) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8439) 	global		fmul_inf_src		# global for fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8440) fmul_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8441) 	fmovm.x		SRC(%a0),&0x80		# return INF result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8442) 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8443) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8444) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8445) 	bpl.b		fmul_inf_dst_p		# result INF is pos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8446) 	bra.b		fmul_inf_dst_n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8448) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8449) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8450) #	fin(): emulates the fmove instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8451) #	fsin(): emulates the fsmove instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8452) #	fdin(): emulates the fdmove instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8453) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8454) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8455) #	norm() - normalize mantissa for EXOP on denorm			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8456) #	scale_to_zero_src() - scale src exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8457) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8458) #	unf_res() - return default underflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8459) #	res_qnan_1op() - return QNAN result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8460) #	res_snan_1op() - return SNAN result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8461) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8462) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8463) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8464) #	d0 = round prec/mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8465) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8466) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8467) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8468) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8469) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8470) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8471) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8472) # norms into extended, single, and double precision.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8473) #	Norms can be emulated w/ a regular fmove instruction. For	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8474) # sgl/dbl, must scale exponent and perform an "fmove". Check to see	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8475) # if the result would have overflowed/underflowed. If so, use unf_res()	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8476) # or ovf_res() to return the default result. Also return EXOP if	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8477) # exception is enabled. If no exception, return the default result.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8478) #	Unnorms don't pass through here.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8479) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8480) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8482) 	global		fsin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8483) fsin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8484) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8485) 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8486) 	bra.b		fin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8488) 	global		fdin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8489) fdin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8490) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8491) 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8493) 	global		fin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8494) fin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8495) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8497) 	mov.b		STAG(%a6),%d1		# fetch src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8498) 	bne.w		fin_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8500) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8501) # FP MOVE IN: NORMs and DENORMs ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8502) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8503) fin_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8504) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8505) 	bne.w		fin_not_ext		# no, so go handle dbl or sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8507) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8508) # precision selected is extended. so...we cannot get an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8509) # or overflow because of rounding to the correct precision. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8510) # skip the scaling and unscaling...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8511) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8512) 	tst.b		SRC_EX(%a0)		# is the operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8513) 	bpl.b		fin_norm_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8514) 	bset		&neg_bit,FPSR_CC(%a6)	# yes, so set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8515) fin_norm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8516) 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8517) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8519) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8520) # for an extended precision DENORM, the UNFL exception bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8521) # the accrued bit is NOT set in this instance(no inexactness!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8522) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8523) fin_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8524) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8525) 	bne.w		fin_not_ext		# no, so go handle dbl or sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8527) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8528) 	tst.b		SRC_EX(%a0)		# is the operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8529) 	bpl.b		fin_denorm_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8530) 	bset		&neg_bit,FPSR_CC(%a6)	# yes, so set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8531) fin_denorm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8532) 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8533) 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8534) 	bne.b		fin_denorm_unfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8535) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8537) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8538) # the input is an extended DENORM and underflow is enabled in the FPCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8539) # normalize the mantissa and add the bias of 0x6000 to the resulting negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8540) # exponent and insert back into the operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8541) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8542) fin_denorm_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8543) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8544) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8545) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8546) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8547) 	bsr.l		norm			# normalize result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8548) 	neg.w		%d0			# new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8549) 	addi.w		&0x6000,%d0		# add new bias to exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8550) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8551) 	andi.w		&0x8000,%d1		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8552) 	andi.w		&0x7fff,%d0		# clear sign position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8553) 	or.w		%d1,%d0			# concat new exo,old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8554) 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8555) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8556) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8558) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8559) # operand is to be rounded to single or double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8560) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8561) fin_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8562) 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8563) 	bne.b		fin_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8565) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8566) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8567) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8568) fin_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8569) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8570) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8571) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8572) 	bsr.l		scale_to_zero_src	# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8574) 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8575) 	bge.w		fin_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8576) 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8577) 	beq.w		fin_sd_may_ovfl		# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8578) 	blt.w		fin_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8580) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8581) # operand will NOT overflow or underflow when moved into the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8582) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8583) fin_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8584) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8585) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8587) 	fmov.x		FP_SCR0(%a6),%fp0	# perform move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8589) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8590) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8592) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8594) fin_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8595) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8596) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8597) 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8598) 	mov.w		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8599) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8600) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8601) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8602) 	or.w		%d1,%d2			# concat old sign,new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8603) 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8604) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8605) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8606) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8608) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8609) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8610) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8611) fin_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8612) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8613) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8614) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8615) 	bsr.l		scale_to_zero_src	# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8617) 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8618) 	bge.w		fin_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8619) 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8620) 	beq.w		fin_sd_may_ovfl		# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8621) 	blt.w		fin_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8622) 	bra.w		fin_sd_normal		# no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8624) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8625) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8626) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8627) fin_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8628) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8630) 	tst.b		FP_SCR0_EX(%a6)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8631) 	bpl.b		fin_sd_unfl_tst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8632) 	bset		&neg_bit,FPSR_CC(%a6)	# set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8634) # if underflow or inexact is enabled, then go calculate the EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8635) fin_sd_unfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8636) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8637) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8638) 	bne.b		fin_sd_unfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8640) fin_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8641) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8642) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8643) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8644) 	or.b		%d0,FPSR_CC(%a6)	# unf_res may have set 'Z'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8645) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8646) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8648) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8649) # operand will underflow AND underflow or inexact is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8650) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8651) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8652) fin_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8653) 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8654) 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8655) 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8657) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8658) 	mov.w		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8659) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8660) 	sub.l		%d0,%d1			# subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8661) 	andi.w		&0x8000,%d2		# extract old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8662) 	addi.l		&0x6000,%d1		# add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8663) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8664) 	or.w		%d1,%d2			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8665) 	mov.w		%d2,FP_SCR1_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8666) 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8667) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8668) 	bra.b		fin_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8670) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8671) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8672) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8673) fin_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8674) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8675) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8677) 	fmov.x		FP_SCR0(%a6),%fp0	# perform move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8679) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8680) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8682) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8684) fin_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8685) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8687) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8688) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8689) 	bne.b		fin_sd_ovfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8691) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8692) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8693) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8694) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8695) fin_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8696) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8697) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8698) 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8699) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8700) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8701) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8702) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8704) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8705) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8706) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8707) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8708) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8709) fin_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8710) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8711) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8712) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8713) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8714) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8715) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8716) 	sub.l		&0x6000,%d1		# subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8717) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8718) 	or.w		%d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8719) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8720) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8721) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8722) 	bra.b		fin_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8724) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8725) # the move in MAY overflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8726) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8727) fin_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8728) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8729) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8731) 	fmov.x		FP_SCR0(%a6),%fp0	# perform the move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8733) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8734) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8736) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8738) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8739) 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8740) 	fbge.w		fin_sd_ovfl_tst		# yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8742) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8743) 	bra.w		fin_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8745) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8747) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8748) # operand is not a NORM: check its optype and branch accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8749) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8750) fin_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8751) 	cmpi.b		%d1,&DENORM		# weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8752) 	beq.w		fin_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8753) 	cmpi.b		%d1,&SNAN		# weed out SNANs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8754) 	beq.l		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8755) 	cmpi.b		%d1,&QNAN		# weed out QNANs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8756) 	beq.l		res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8758) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8759) # do the fmove in; at this point, only possible ops are ZERO and INF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8760) # use fmov to determine ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8761) # prec:mode should be zero at this point but it won't affect answer anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8762) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8763) 	fmov.x		SRC(%a0),%fp0		# do fmove in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8764) 	fmov.l		%fpsr,%d0		# no exceptions possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8765) 	rol.l		&0x8,%d0		# put ccodes in lo byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8766) 	mov.b		%d0,FPSR_CC(%a6)	# insert correct ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8767) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8769) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8770) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8771) #	fdiv(): emulates the fdiv instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8772) #	fsdiv(): emulates the fsdiv instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8773) #	fddiv(): emulates the fddiv instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8774) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8775) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8776) #	scale_to_zero_src() - scale src exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8777) #	scale_to_zero_dst() - scale dst exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8778) #	unf_res() - return default underflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8779) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8780) #	res_qnan() - return QNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8781) #	res_snan() - return SNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8782) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8783) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8784) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8785) #	a1 = pointer to extended precision destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8786) #	d0  rnd prec,mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8787) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8788) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8789) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8790) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8791) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8792) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8793) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8794) # norms/denorms into ext/sgl/dbl precision.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8795) #	For norms/denorms, scale the exponents such that a divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8796) # instruction won't cause an exception. Use the regular fdiv to		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8797) # compute a result. Check if the regular operands would have taken	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8798) # an exception. If so, return the default overflow/underflow result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8799) # and return the EXOP if exceptions are enabled. Else, scale the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8800) # result operand to the proper exponent.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8801) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8802) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8804) 	align		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8805) tbl_fdiv_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8806) 	long		0x3fff - 0x0000		# ext_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8807) 	long		0x3fff - 0x3f81		# sgl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8808) 	long		0x3fff - 0x3c01		# dbl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8810) tbl_fdiv_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8811) 	long		0x3fff - 0x7ffe		# ext overflow exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8812) 	long		0x3fff - 0x407e		# sgl overflow exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8813) 	long		0x3fff - 0x43fe		# dbl overflow exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8815) 	global		fsdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8816) fsdiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8817) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8818) 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8819) 	bra.b		fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8821) 	global		fddiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8822) fddiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8823) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8824) 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8826) 	global		fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8827) fdiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8828) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8830) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8831) 	mov.b		DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8832) 	lsl.b		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8833) 	or.b		STAG(%a6),%d1		# combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8835) 	bne.w		fdiv_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8837) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8838) # DIVIDE: NORMs and DENORMs ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8839) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8840) fdiv_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8841) 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8842) 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8843) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8845) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8846) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8847) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8849) 	bsr.l		scale_to_zero_src	# scale src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8850) 	mov.l		%d0,-(%sp)		# save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8852) 	bsr.l		scale_to_zero_dst	# scale dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8854) 	neg.l		(%sp)			# SCALE FACTOR = scale1 - scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8855) 	add.l		%d0,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8857) 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8858) 	lsr.b		&0x6,%d1		# shift to lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8859) 	mov.l		(%sp)+,%d0		# load S.F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8860) 	cmp.l		%d0,(tbl_fdiv_ovfl.b,%pc,%d1.w*4) # will result overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8861) 	ble.w		fdiv_may_ovfl		# result will overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8863) 	cmp.l		%d0,(tbl_fdiv_unfl.w,%pc,%d1.w*4) # will result underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8864) 	beq.w		fdiv_may_unfl		# maybe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8865) 	bgt.w		fdiv_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8867) fdiv_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8868) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8870) 	fmov.l		L_SCR3(%a6),%fpcr	# save FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8871) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8873) 	fdiv.x		FP_SCR0(%a6),%fp0	# perform divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8875) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8876) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8878) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8880) fdiv_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8881) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store result on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8882) 	mov.l		%d2,-(%sp)		# store d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8883) 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8884) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8885) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8886) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8887) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8888) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8889) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8890) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8891) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8892) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8894) tbl_fdiv_ovfl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8895) 	long		0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8896) 	long		0x407f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8897) 	long		0x43ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8899) fdiv_no_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8900) 	mov.l		(%sp)+,%d0		# restore scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8901) 	bra.b		fdiv_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8903) fdiv_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8904) 	mov.l		%d0,-(%sp)		# save scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8906) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8908) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8909) 	fmov.l		&0x0,%fpsr		# set FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8911) 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8913) 	fmov.l		%fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8914) 	fmov.l		&0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8916) 	or.l		%d0,USER_FPSR(%a6)	# save INEX,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8918) 	fmovm.x		&0x01,-(%sp)		# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8919) 	mov.w		(%sp),%d0		# fetch new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8920) 	add.l		&0xc,%sp		# clear result from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8921) 	andi.l		&0x7fff,%d0		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8922) 	sub.l		(%sp),%d0		# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8923) 	cmp.l		%d0,(tbl_fdiv_ovfl2.b,%pc,%d1.w*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8924) 	blt.b		fdiv_no_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8925) 	mov.l		(%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8927) fdiv_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8928) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8930) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8931) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8932) 	bne.b		fdiv_ovfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8934) fdiv_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8935) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8936) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8937) 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8938) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8939) 	or.b		%d0,FPSR_CC(%a6)	# set INF if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8940) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8941) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8943) fdiv_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8944) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8945) 	andi.b		&0xc0,%d1		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8946) 	bne.b		fdiv_ovfl_ena_sd	# no, do sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8948) fdiv_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8949) 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8951) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8952) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8953) 	mov.w		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8954) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8955) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8956) 	subi.l		&0x6000,%d1		# subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8957) 	andi.w		&0x7fff,%d1		# clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8958) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8959) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8960) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8961) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8962) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8963) 	bra.b		fdiv_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8965) fdiv_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8966) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8968) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8969) 	andi.b		&0x30,%d1		# keep rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8970) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8972) 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8974) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8975) 	bra.b		fdiv_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8977) fdiv_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8978) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8980) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8982) 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8983) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8985) 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8987) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8988) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8990) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8992) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8993) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8994) 	bne.b		fdiv_unfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8996) fdiv_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8997) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8999) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9000) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9001) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9002) 	or.b		%d0,FPSR_CC(%a6)	# 'Z' may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9003) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9004) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9006) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9007) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9008) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9009) fdiv_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9010) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9012) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9013) 	andi.b		&0xc0,%d1		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9014) 	bne.b		fdiv_unfl_ena_sd	# no, sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9016) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9018) fdiv_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9019) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9021) 	fdiv.x		FP_SCR0(%a6),%fp1	# execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9023) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9025) 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9026) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9027) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9028) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9029) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9030) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9031) 	sub.l		%d0,%d1			# add scale factoer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9032) 	addi.l		&0x6000,%d1		# add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9033) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9034) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9035) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9036) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9037) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9038) 	bra.w		fdiv_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9040) fdiv_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9041) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9042) 	andi.b		&0x30,%d1		# use only rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9043) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9045) 	bra.b		fdiv_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9047) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9048) # the divide operation MAY underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9049) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9050) fdiv_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9051) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9053) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9054) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9056) 	fdiv.x		FP_SCR0(%a6),%fp0	# execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9058) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9059) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9061) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9063) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9064) 	fcmp.b		%fp1,&0x1		# is |result| > 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9065) 	fbgt.w		fdiv_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9066) 	fblt.w		fdiv_unfl		# yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9068) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9069) # we still don't know if underflow occurred. result is ~ equal to 1. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9070) # we don't know if the result was an underflow that rounded up to a 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9071) # or a normalized number that rounded down to a 1. so, redo the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9072) # operation using RZ as the rounding mode to see what the pre-rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9073) # result is. this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9074) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9075) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9077) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9078) 	andi.b		&0xc0,%d1		# keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9079) 	ori.b		&rz_mode*0x10,%d1	# insert RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9081) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9082) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9084) 	fdiv.x		FP_SCR0(%a6),%fp1	# execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9086) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9087) 	fabs.x		%fp1			# make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9088) 	fcmp.b		%fp1,&0x1		# is |result| < 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9089) 	fbge.w		fdiv_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9090) 	bra.w		fdiv_unfl		# yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9092) ############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9094) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9095) # Divide: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9096) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9097) fdiv_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9098) 	mov.w		(tbl_fdiv_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9099) 	jmp		(tbl_fdiv_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9101) 	swbeg		&48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9102) tbl_fdiv_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9103) 	short		fdiv_norm	- tbl_fdiv_op # NORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9104) 	short		fdiv_inf_load	- tbl_fdiv_op # NORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9105) 	short		fdiv_zero_load	- tbl_fdiv_op # NORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9106) 	short		fdiv_res_qnan	- tbl_fdiv_op # NORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9107) 	short		fdiv_norm	- tbl_fdiv_op # NORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9108) 	short		fdiv_res_snan	- tbl_fdiv_op # NORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9109) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9110) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9112) 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9113) 	short		fdiv_res_operr	- tbl_fdiv_op # ZERO / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9114) 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9115) 	short		fdiv_res_qnan	- tbl_fdiv_op # ZERO / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9116) 	short		fdiv_zero_load	- tbl_fdiv_op # ZERO / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9117) 	short		fdiv_res_snan	- tbl_fdiv_op # ZERO / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9118) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9119) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9121) 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9122) 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9123) 	short		fdiv_res_operr	- tbl_fdiv_op # INF / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9124) 	short		fdiv_res_qnan	- tbl_fdiv_op # INF / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9125) 	short		fdiv_inf_dst	- tbl_fdiv_op # INF / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9126) 	short		fdiv_res_snan	- tbl_fdiv_op # INF / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9127) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9128) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9130) 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9131) 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9132) 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9133) 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9134) 	short		fdiv_res_qnan	- tbl_fdiv_op # QNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9135) 	short		fdiv_res_snan	- tbl_fdiv_op # QNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9136) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9137) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9139) 	short		fdiv_norm	- tbl_fdiv_op # DENORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9140) 	short		fdiv_inf_load	- tbl_fdiv_op # DENORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9141) 	short		fdiv_zero_load	- tbl_fdiv_op # DENORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9142) 	short		fdiv_res_qnan	- tbl_fdiv_op # DENORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9143) 	short		fdiv_norm	- tbl_fdiv_op # DENORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9144) 	short		fdiv_res_snan	- tbl_fdiv_op # DENORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9145) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9146) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9148) 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9149) 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9150) 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9151) 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9152) 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9153) 	short		fdiv_res_snan	- tbl_fdiv_op # SNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9154) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9155) 	short		tbl_fdiv_op	- tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9157) fdiv_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9158) 	bra.l		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9159) fdiv_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9160) 	bra.l		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9161) fdiv_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9162) 	bra.l		res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9164) 	global		fdiv_zero_load		# global for fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9165) fdiv_zero_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9166) 	mov.b		SRC_EX(%a0),%d0		# result sign is exclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9167) 	mov.b		DST_EX(%a1),%d1		# or of input signs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9168) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9169) 	bpl.b		fdiv_zero_load_p	# result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9170) 	fmov.s		&0x80000000,%fp0	# load a -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9171) 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set Z/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9172) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9173) fdiv_zero_load_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9174) 	fmov.s		&0x00000000,%fp0	# load a +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9175) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9176) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9178) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9179) # The destination was In Range and the source was a ZERO. The result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9180) # Therefore, is an INF w/ the proper sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9181) # So, determine the sign and return a new INF (w/ the j-bit cleared).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9182) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9183) 	global		fdiv_inf_load		# global for fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9184) fdiv_inf_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9185) 	ori.w		&dz_mask+adz_mask,2+USER_FPSR(%a6) # no; set DZ/ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9186) 	mov.b		SRC_EX(%a0),%d0		# load both signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9187) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9188) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9189) 	bpl.b		fdiv_inf_load_p		# result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9190) 	fmov.s		&0xff800000,%fp0	# make result -INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9191) 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9192) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9193) fdiv_inf_load_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9194) 	fmov.s		&0x7f800000,%fp0	# make result +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9195) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9196) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9198) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9199) # The destination was an INF w/ an In Range or ZERO source, the result is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9200) # an INF w/ the proper sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9201) # The 68881/882 returns the destination INF w/ the new sign(if the j-bit of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9202) # dst INF is set, then then j-bit of the result INF is also set).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9203) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9204) 	global		fdiv_inf_dst		# global for fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9205) fdiv_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9206) 	mov.b		DST_EX(%a1),%d0		# load both signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9207) 	mov.b		SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9208) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9209) 	bpl.b		fdiv_inf_dst_p		# result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9211) 	fmovm.x		DST(%a1),&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9212) 	fabs.x		%fp0			# clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9213) 	fneg.x		%fp0			# set sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9214) 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9215) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9217) fdiv_inf_dst_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9218) 	fmovm.x		DST(%a1),&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9219) 	fabs.x		%fp0			# return positive INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9220) 	mov.b		&inf_bmask,FPSR_CC(%a6) # set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9221) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9223) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9224) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9225) #	fneg(): emulates the fneg instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9226) #	fsneg(): emulates the fsneg instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9227) #	fdneg(): emulates the fdneg instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9228) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9229) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9230) #	norm() - normalize a denorm to provide EXOP			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9231) #	scale_to_zero_src() - scale sgl/dbl source exponent		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9232) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9233) #	unf_res() - return default underflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9234) #	res_qnan_1op() - return QNAN result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9235) #	res_snan_1op() - return SNAN result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9236) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9237) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9238) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9239) #	d0 = rnd prec,mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9240) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9241) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9242) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9243) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9244) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9245) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9246) #	Handle NANs, zeroes, and infinities as special cases. Separate	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9247) # norms/denorms into ext/sgl/dbl precisions. Extended precision can be	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9248) # emulated by simply setting sign bit. Sgl/dbl operands must be scaled	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9249) # and an actual fneg performed to see if overflow/underflow would have	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9250) # occurred. If so, return default underflow/overflow result. Else,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9251) # scale the result exponent and return result. FPSR gets set based on	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9252) # the result value.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9253) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9254) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9256) 	global		fsneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9257) fsneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9258) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9259) 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9260) 	bra.b		fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9262) 	global		fdneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9263) fdneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9264) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9265) 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9267) 	global		fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9268) fneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9269) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9270) 	mov.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9271) 	bne.w		fneg_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9273) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9274) # NEGATE SIGN : norms and denorms ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9275) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9276) fneg_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9277) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9278) 	bne.w		fneg_not_ext		# no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9280) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9281) # precision selected is extended. so...we can not get an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9282) # or overflow because of rounding to the correct precision. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9283) # skip the scaling and unscaling...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9284) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9285) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9286) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9287) 	mov.w		SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9288) 	eori.w		&0x8000,%d0		# negate sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9289) 	bpl.b		fneg_norm_load		# sign is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9290) 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9291) fneg_norm_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9292) 	mov.w		%d0,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9293) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9294) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9296) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9297) # for an extended precision DENORM, the UNFL exception bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9298) # the accrued bit is NOT set in this instance(no inexactness!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9299) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9300) fneg_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9301) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9302) 	bne.b		fneg_not_ext		# no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9304) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9306) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9307) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9308) 	mov.w		SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9309) 	eori.w		&0x8000,%d0		# negate sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9310) 	bpl.b		fneg_denorm_done	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9311) 	mov.b		&neg_bmask,FPSR_CC(%a6)	# yes, set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9312) fneg_denorm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9313) 	mov.w		%d0,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9314) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9316) 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9317) 	bne.b		fneg_ext_unfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9318) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9320) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9321) # the input is an extended DENORM and underflow is enabled in the FPCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9322) # normalize the mantissa and add the bias of 0x6000 to the resulting negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9323) # exponent and insert back into the operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9324) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9325) fneg_ext_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9326) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9327) 	bsr.l		norm			# normalize result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9328) 	neg.w		%d0			# new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9329) 	addi.w		&0x6000,%d0		# add new bias to exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9330) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9331) 	andi.w		&0x8000,%d1		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9332) 	andi.w		&0x7fff,%d0		# clear sign position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9333) 	or.w		%d1,%d0			# concat old sign, new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9334) 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9335) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9336) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9338) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9339) # operand is either single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9340) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9341) fneg_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9342) 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9343) 	bne.b		fneg_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9345) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9346) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9347) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9348) fneg_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9349) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9350) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9351) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9352) 	bsr.l		scale_to_zero_src	# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9354) 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9355) 	bge.w		fneg_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9356) 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9357) 	beq.w		fneg_sd_may_ovfl	# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9358) 	blt.w		fneg_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9360) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9361) # operand will NOT overflow or underflow when moved in to the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9362) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9363) fneg_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9364) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9365) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9367) 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9369) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9370) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9372) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9374) fneg_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9375) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9376) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9377) 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9378) 	mov.w		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9379) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9380) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9381) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9382) 	or.w		%d1,%d2			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9383) 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9384) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9385) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9386) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9388) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9389) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9390) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9391) fneg_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9392) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9393) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9394) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9395) 	bsr.l		scale_to_zero_src	# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9397) 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9398) 	bge.b		fneg_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9399) 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9400) 	beq.w		fneg_sd_may_ovfl	# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9401) 	blt.w		fneg_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9402) 	bra.w		fneg_sd_normal		# no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9404) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9405) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9406) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9407) fneg_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9408) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9410) 	eori.b		&0x80,FP_SCR0_EX(%a6)	# negate sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9411) 	bpl.b		fneg_sd_unfl_tst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9412) 	bset		&neg_bit,FPSR_CC(%a6)	# set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9414) # if underflow or inexact is enabled, go calculate EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9415) fneg_sd_unfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9416) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9417) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9418) 	bne.b		fneg_sd_unfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9420) fneg_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9421) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9422) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9423) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9424) 	or.b		%d0,FPSR_CC(%a6)	# unf_res may have set 'Z'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9425) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9426) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9428) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9429) # operand will underflow AND underflow is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9430) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9431) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9432) fneg_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9433) 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9434) 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9435) 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9437) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9438) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9439) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9440) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9441) 	sub.l		%d0,%d1			# subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9442) 	addi.l		&0x6000,%d1		# add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9443) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9444) 	or.w		%d2,%d1			# concat new sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9445) 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9446) 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9447) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9448) 	bra.b		fneg_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9450) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9451) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9452) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9453) fneg_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9454) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9455) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9457) 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9459) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9460) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9462) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9464) fneg_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9465) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9467) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9468) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9469) 	bne.b		fneg_sd_ovfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9471) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9472) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9473) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9474) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9475) fneg_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9476) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9477) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9478) 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9479) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9480) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9481) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9482) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9484) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9485) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9486) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9487) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9488) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9489) fneg_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9490) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9491) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9492) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9493) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9494) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9495) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9496) 	subi.l		&0x6000,%d1		# subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9497) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9498) 	or.w		%d2,%d1			# concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9499) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9500) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9501) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9502) 	bra.b		fneg_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9504) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9505) # the move in MAY underflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9506) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9507) fneg_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9508) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9509) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9511) 	fneg.x		FP_SCR0(%a6),%fp0	# perform negation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9513) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9514) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9516) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9518) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9519) 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9520) 	fbge.w		fneg_sd_ovfl_tst	# yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9522) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9523) 	bra.w		fneg_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9525) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9527) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9528) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9529) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9530) fneg_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9531) 	cmpi.b		%d1,&DENORM		# weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9532) 	beq.w		fneg_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9533) 	cmpi.b		%d1,&SNAN		# weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9534) 	beq.l		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9535) 	cmpi.b		%d1,&QNAN		# weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9536) 	beq.l		res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9538) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9539) # do the fneg; at this point, only possible ops are ZERO and INF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9540) # use fneg to determine ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9541) # prec:mode should be zero at this point but it won't affect answer anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9542) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9543) 	fneg.x		SRC_EX(%a0),%fp0	# do fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9544) 	fmov.l		%fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9545) 	rol.l		&0x8,%d0		# put ccodes in lo byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9546) 	mov.b		%d0,FPSR_CC(%a6)	# insert correct ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9547) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9549) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9550) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9551) #	ftst(): emulates the ftest instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9552) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9553) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9554) #	res{s,q}nan_1op() - set NAN result for monadic instruction	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9555) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9556) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9557) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9558) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9559) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9560) #	none								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9561) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9562) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9563) #	Check the source operand tag (STAG) and set the FPCR according	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9564) # to the operand type and sign.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9565) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9566) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9568) 	global		ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9569) ftst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9570) 	mov.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9571) 	bne.b		ftst_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9573) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9574) # Norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9575) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9576) ftst_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9577) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9578) 	bmi.b		ftst_norm_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9579) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9580) ftst_norm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9581) 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9582) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9584) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9585) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9586) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9587) ftst_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9588) 	cmpi.b		%d1,&ZERO		# weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9589) 	beq.b		ftst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9590) 	cmpi.b		%d1,&INF		# weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9591) 	beq.b		ftst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9592) 	cmpi.b		%d1,&SNAN		# weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9593) 	beq.l		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9594) 	cmpi.b		%d1,&QNAN		# weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9595) 	beq.l		res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9597) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9598) # Denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9599) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9600) ftst_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9601) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9602) 	bmi.b		ftst_denorm_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9603) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9604) ftst_denorm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9605) 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9606) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9608) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9609) # Infinity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9610) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9611) ftst_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9612) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9613) 	bmi.b		ftst_inf_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9614) ftst_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9615) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9616) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9617) ftst_inf_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9618) 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'I','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9619) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9621) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9622) # Zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9623) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9624) ftst_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9625) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9626) 	bmi.b		ftst_zero_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9627) ftst_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9628) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9629) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9630) ftst_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9631) 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9632) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9634) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9635) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9636) #	fint(): emulates the fint instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9637) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9638) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9639) #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9640) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9641) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9642) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9643) #	d0 = round precision/mode					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9644) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9645) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9646) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9647) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9648) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9649) #	Separate according to operand type. Unnorms don't pass through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9650) # here. For norms, load the rounding mode/prec, execute a "fint", then	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9651) # store the resulting FPSR bits.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9652) #	For denorms, force the j-bit to a one and do the same as for	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9653) # norms. Denorms are so low that the answer will either be a zero or a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9654) # one.									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9655) #	For zeroes/infs/NANs, return the same while setting the FPSR	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9656) # as appropriate.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9657) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9658) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9660) 	global		fint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9661) fint:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9662) 	mov.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9663) 	bne.b		fint_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9665) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9666) # Norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9667) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9668) fint_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9669) 	andi.b		&0x30,%d0		# set prec = ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9671) 	fmov.l		%d0,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9672) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9674) 	fint.x		SRC(%a0),%fp0		# execute fint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9676) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9677) 	fmov.l		%fpsr,%d0		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9678) 	or.l		%d0,USER_FPSR(%a6)	# set exception bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9680) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9682) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9683) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9684) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9685) fint_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9686) 	cmpi.b		%d1,&ZERO		# weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9687) 	beq.b		fint_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9688) 	cmpi.b		%d1,&INF		# weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9689) 	beq.b		fint_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9690) 	cmpi.b		%d1,&DENORM		# weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9691) 	beq.b		fint_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9692) 	cmpi.b		%d1,&SNAN		# weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9693) 	beq.l		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9694) 	bra.l		res_qnan_1op		# weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9696) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9697) # Denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9698) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9699) # for DENORMs, the result will be either (+/-)ZERO or (+/-)1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9700) # also, the INEX2 and AINEX exception bits will be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9701) # so, we could either set these manually or force the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9702) # to a very small NORM and ship it to the NORM routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9703) # I do the latter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9704) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9705) fint_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9706) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9707) 	mov.b		&0x80,FP_SCR0_HI(%a6)	# force DENORM ==> small NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9708) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9709) 	bra.b		fint_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9711) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9712) # Zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9713) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9714) fint_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9715) 	tst.b		SRC_EX(%a0)		# is ZERO negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9716) 	bmi.b		fint_zero_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9717) fint_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9718) 	fmov.s		&0x00000000,%fp0	# return +ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9719) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9720) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9721) fint_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9722) 	fmov.s		&0x80000000,%fp0	# return -ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9723) 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9724) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9726) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9727) # Infinity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9728) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9729) fint_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9730) 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9731) 	tst.b		SRC_EX(%a0)		# is INF negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9732) 	bmi.b		fint_inf_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9733) fint_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9734) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9735) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9736) fint_inf_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9737) 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9738) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9740) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9741) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9742) #	fintrz(): emulates the fintrz instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9743) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9744) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9745) #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9746) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9747) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9748) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9749) #	d0 = round precision/mode					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9750) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9751) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9752) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9753) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9754) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9755) #	Separate according to operand type. Unnorms don't pass through	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9756) # here. For norms, load the rounding mode/prec, execute a "fintrz",	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9757) # then store the resulting FPSR bits.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9758) #	For denorms, force the j-bit to a one and do the same as for	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9759) # norms. Denorms are so low that the answer will either be a zero or a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9760) # one.									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9761) #	For zeroes/infs/NANs, return the same while setting the FPSR	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9762) # as appropriate.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9763) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9764) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9766) 	global		fintrz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9767) fintrz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9768) 	mov.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9769) 	bne.b		fintrz_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9771) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9772) # Norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9773) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9774) fintrz_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9775) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9777) 	fintrz.x	SRC(%a0),%fp0		# execute fintrz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9779) 	fmov.l		%fpsr,%d0		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9780) 	or.l		%d0,USER_FPSR(%a6)	# set exception bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9782) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9784) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9785) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9786) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9787) fintrz_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9788) 	cmpi.b		%d1,&ZERO		# weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9789) 	beq.b		fintrz_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9790) 	cmpi.b		%d1,&INF		# weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9791) 	beq.b		fintrz_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9792) 	cmpi.b		%d1,&DENORM		# weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9793) 	beq.b		fintrz_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9794) 	cmpi.b		%d1,&SNAN		# weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9795) 	beq.l		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9796) 	bra.l		res_qnan_1op		# weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9798) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9799) # Denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9800) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9801) # for DENORMs, the result will be (+/-)ZERO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9802) # also, the INEX2 and AINEX exception bits will be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9803) # so, we could either set these manually or force the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9804) # to a very small NORM and ship it to the NORM routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9805) # I do the latter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9806) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9807) fintrz_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9808) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9809) 	mov.b		&0x80,FP_SCR0_HI(%a6)	# force DENORM ==> small NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9810) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9811) 	bra.b		fintrz_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9813) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9814) # Zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9815) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9816) fintrz_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9817) 	tst.b		SRC_EX(%a0)		# is ZERO negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9818) 	bmi.b		fintrz_zero_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9819) fintrz_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9820) 	fmov.s		&0x00000000,%fp0	# return +ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9821) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9822) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9823) fintrz_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9824) 	fmov.s		&0x80000000,%fp0	# return -ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9825) 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9826) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9828) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9829) # Infinity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9830) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9831) fintrz_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9832) 	fmovm.x		SRC(%a0),&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9833) 	tst.b		SRC_EX(%a0)		# is INF negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9834) 	bmi.b		fintrz_inf_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9835) fintrz_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9836) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9837) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9838) fintrz_inf_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9839) 	mov.b		&inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9840) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9842) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9843) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9844) #	fabs():  emulates the fabs instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9845) #	fsabs(): emulates the fsabs instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9846) #	fdabs(): emulates the fdabs instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9847) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9848) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9849) #	norm() - normalize denorm mantissa to provide EXOP		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9850) #	scale_to_zero_src() - make exponent. = 0; get scale factor	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9851) #	unf_res() - calculate underflow result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9852) #	ovf_res() - calculate overflow result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9853) #	res_{s,q}nan_1op() - set NAN result for monadic operation	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9854) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9855) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9856) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9857) #	d0 = rnd precision/mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9858) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9859) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9860) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9861) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9862) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9863) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9864) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9865) # norms into extended, single, and double precision.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9866) #	Simply clear sign for extended precision norm. Ext prec denorm	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9867) # gets an EXOP created for it since it's an underflow.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9868) #	Double and single precision can overflow and underflow. First,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9869) # scale the operand such that the exponent is zero. Perform an "fabs"	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9870) # using the correct rnd mode/prec. Check to see if the original		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9871) # exponent would take an exception. If so, use unf_res() or ovf_res()	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9872) # to calculate the default result. Also, create the EXOP for the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9873) # exceptional case. If no exception should occur, insert the correct	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9874) # result exponent and return.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9875) #	Unnorms don't pass through here.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9876) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9877) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9879) 	global		fsabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9880) fsabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9881) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9882) 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9883) 	bra.b		fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9885) 	global		fdabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9886) fdabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9887) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9888) 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9890) 	global		fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9891) fabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9892) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9893) 	mov.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9894) 	bne.w		fabs_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9896) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9897) # ABSOLUTE VALUE: norms and denorms ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9898) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9899) fabs_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9900) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9901) 	bne.b		fabs_not_ext		# no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9903) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9904) # precision selected is extended. so...we can not get an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9905) # or overflow because of rounding to the correct precision. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9906) # skip the scaling and unscaling...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9907) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9908) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9909) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9910) 	mov.w		SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9911) 	bclr		&15,%d1			# force absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9912) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9913) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9914) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9916) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9917) # for an extended precision DENORM, the UNFL exception bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9918) # the accrued bit is NOT set in this instance(no inexactness!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9919) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9920) fabs_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9921) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9922) 	bne.b		fabs_not_ext		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9924) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9926) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9927) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9928) 	mov.w		SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9929) 	bclr		&15,%d0			# clear sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9930) 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9932) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9934) 	btst		&unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9935) 	bne.b		fabs_ext_unfl_ena
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9936) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9938) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9939) # the input is an extended DENORM and underflow is enabled in the FPCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9940) # normalize the mantissa and add the bias of 0x6000 to the resulting negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9941) # exponent and insert back into the operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9942) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9943) fabs_ext_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9944) 	lea		FP_SCR0(%a6),%a0	# pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9945) 	bsr.l		norm			# normalize result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9946) 	neg.w		%d0			# new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9947) 	addi.w		&0x6000,%d0		# add new bias to exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9948) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch old sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9949) 	andi.w		&0x8000,%d1		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9950) 	andi.w		&0x7fff,%d0		# clear sign position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9951) 	or.w		%d1,%d0			# concat old sign, new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9952) 	mov.w		%d0,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9953) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9954) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9956) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9957) # operand is either single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9958) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9959) fabs_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9960) 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9961) 	bne.b		fabs_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9963) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9964) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9965) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9966) fabs_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9967) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9968) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9969) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9970) 	bsr.l		scale_to_zero_src	# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9972) 	cmpi.l		%d0,&0x3fff-0x3f80	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9973) 	bge.w		fabs_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9974) 	cmpi.l		%d0,&0x3fff-0x407e	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9975) 	beq.w		fabs_sd_may_ovfl	# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9976) 	blt.w		fabs_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9978) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9979) # operand will NOT overflow or underflow when moved in to the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9980) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9981) fabs_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9982) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9983) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9985) 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9987) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9988) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9990) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9992) fabs_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9993) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9994) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9995) 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9996) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9997) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9998) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9999) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10000) 	or.w		%d1,%d2			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10001) 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10002) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10003) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10004) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10006) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10007) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10008) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10009) fabs_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10010) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10011) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10012) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10013) 	bsr.l		scale_to_zero_src	# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10015) 	cmpi.l		%d0,&0x3fff-0x3c00	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10016) 	bge.b		fabs_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10017) 	cmpi.l		%d0,&0x3fff-0x43fe	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10018) 	beq.w		fabs_sd_may_ovfl	# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10019) 	blt.w		fabs_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10020) 	bra.w		fabs_sd_normal		# no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10022) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10023) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10024) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10025) fabs_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10026) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10028) 	bclr		&0x7,FP_SCR0_EX(%a6)	# force absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10030) # if underflow or inexact is enabled, go calculate EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10031) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10032) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10033) 	bne.b		fabs_sd_unfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10035) fabs_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10036) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10037) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10038) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10039) 	or.b		%d0,FPSR_CC(%a6)	# set possible 'Z' ccode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10040) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10041) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10043) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10044) # operand will underflow AND underflow is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10045) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10046) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10047) fabs_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10048) 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10049) 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10050) 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10052) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10053) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10054) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10055) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10056) 	sub.l		%d0,%d1			# subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10057) 	addi.l		&0x6000,%d1		# add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10058) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10059) 	or.w		%d2,%d1			# concat new sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10060) 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10061) 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10062) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10063) 	bra.b		fabs_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10065) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10066) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10067) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10068) fabs_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10069) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10070) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10072) 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10074) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10075) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10077) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10079) fabs_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10080) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10082) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10083) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10084) 	bne.b		fabs_sd_ovfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10086) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10087) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10088) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10089) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10090) fabs_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10091) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10092) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10093) 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10094) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10095) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10096) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10097) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10099) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10100) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10101) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10102) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10103) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10104) fabs_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10105) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10106) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10107) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10108) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10109) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10110) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10111) 	subi.l		&0x6000,%d1		# subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10112) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10113) 	or.w		%d2,%d1			# concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10114) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10115) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10116) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10117) 	bra.b		fabs_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10119) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10120) # the move in MAY underflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10121) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10122) fabs_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10123) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10124) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10126) 	fabs.x		FP_SCR0(%a6),%fp0	# perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10128) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10129) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10131) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10133) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10134) 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10135) 	fbge.w		fabs_sd_ovfl_tst	# yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10137) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10138) 	bra.w		fabs_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10140) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10142) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10143) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10144) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10145) fabs_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10146) 	cmpi.b		%d1,&DENORM		# weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10147) 	beq.w		fabs_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10148) 	cmpi.b		%d1,&SNAN		# weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10149) 	beq.l		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10150) 	cmpi.b		%d1,&QNAN		# weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10151) 	beq.l		res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10153) 	fabs.x		SRC(%a0),%fp0		# force absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10155) 	cmpi.b		%d1,&INF		# weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10156) 	beq.b		fabs_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10157) fabs_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10158) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10159) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10160) fabs_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10161) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10162) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10164) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10165) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10166) #	fcmp(): fp compare op routine					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10167) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10168) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10169) #	res_qnan() - return QNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10170) #	res_snan() - return SNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10171) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10172) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10173) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10174) #	a1 = pointer to extended precision destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10175) #	d0 = round prec/mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10176) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10177) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10178) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10179) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10180) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10181) #	Handle NANs and denorms as special cases. For everything else,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10182) # just use the actual fcmp instruction to produce the correct condition	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10183) # codes.								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10184) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10185) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10187) 	global		fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10188) fcmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10189) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10190) 	mov.b		DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10191) 	lsl.b		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10192) 	or.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10193) 	bne.b		fcmp_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10195) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10196) # COMPARE FP OPs : NORMs, ZEROs, INFs, and "corrected" DENORMs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10197) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10198) fcmp_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10199) 	fmovm.x		DST(%a1),&0x80		# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10201) 	fcmp.x		%fp0,SRC(%a0)		# do compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10203) 	fmov.l		%fpsr,%d0		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10204) 	rol.l		&0x8,%d0		# extract ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10205) 	mov.b		%d0,FPSR_CC(%a6)	# set ccode bits(no exc bits are set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10207) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10209) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10210) # fcmp: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10211) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10212) fcmp_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10213) 	mov.w		(tbl_fcmp_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10214) 	jmp		(tbl_fcmp_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10216) 	swbeg		&48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10217) tbl_fcmp_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10218) 	short		fcmp_norm	- tbl_fcmp_op # NORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10219) 	short		fcmp_norm	- tbl_fcmp_op # NORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10220) 	short		fcmp_norm	- tbl_fcmp_op # NORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10221) 	short		fcmp_res_qnan	- tbl_fcmp_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10222) 	short		fcmp_nrm_dnrm	- tbl_fcmp_op # NORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10223) 	short		fcmp_res_snan	- tbl_fcmp_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10224) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10225) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10227) 	short		fcmp_norm	- tbl_fcmp_op # ZERO - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10228) 	short		fcmp_norm	- tbl_fcmp_op # ZERO - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10229) 	short		fcmp_norm	- tbl_fcmp_op # ZERO - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10230) 	short		fcmp_res_qnan	- tbl_fcmp_op # ZERO - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10231) 	short		fcmp_dnrm_s	- tbl_fcmp_op # ZERO - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10232) 	short		fcmp_res_snan	- tbl_fcmp_op # ZERO - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10233) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10234) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10236) 	short		fcmp_norm	- tbl_fcmp_op # INF - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10237) 	short		fcmp_norm	- tbl_fcmp_op # INF - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10238) 	short		fcmp_norm	- tbl_fcmp_op # INF - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10239) 	short		fcmp_res_qnan	- tbl_fcmp_op # INF - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10240) 	short		fcmp_dnrm_s	- tbl_fcmp_op # INF - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10241) 	short		fcmp_res_snan	- tbl_fcmp_op # INF - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10242) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10243) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10245) 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10246) 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10247) 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10248) 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10249) 	short		fcmp_res_qnan	- tbl_fcmp_op # QNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10250) 	short		fcmp_res_snan	- tbl_fcmp_op # QNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10251) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10252) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10254) 	short		fcmp_dnrm_nrm	- tbl_fcmp_op # DENORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10255) 	short		fcmp_dnrm_d	- tbl_fcmp_op # DENORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10256) 	short		fcmp_dnrm_d	- tbl_fcmp_op # DENORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10257) 	short		fcmp_res_qnan	- tbl_fcmp_op # DENORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10258) 	short		fcmp_dnrm_sd	- tbl_fcmp_op # DENORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10259) 	short		fcmp_res_snan	- tbl_fcmp_op # DENORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10260) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10261) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10263) 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10264) 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10265) 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10266) 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10267) 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10268) 	short		fcmp_res_snan	- tbl_fcmp_op # SNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10269) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10270) 	short		tbl_fcmp_op	- tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10272) # unlike all other functions for QNAN and SNAN, fcmp does NOT set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10273) # 'N' bit for a negative QNAN or SNAN input so we must squelch it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10274) fcmp_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10275) 	bsr.l		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10276) 	andi.b		&0xf7,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10277) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10278) fcmp_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10279) 	bsr.l		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10280) 	andi.b		&0xf7,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10281) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10283) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10284) # DENORMs are a little more difficult.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10285) # If you have a 2 DENORMs, then you can just force the j-bit to a one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10286) # and use the fcmp_norm routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10287) # If you have a DENORM and an INF or ZERO, just force the DENORM's j-bit to a one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10288) # and use the fcmp_norm routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10289) # If you have a DENORM and a NORM with opposite signs, then use fcmp_norm, also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10290) # But with a DENORM and a NORM of the same sign, the neg bit is set if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10291) # (1) signs are (+) and the DENORM is the dst or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10292) # (2) signs are (-) and the DENORM is the src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10293) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10295) fcmp_dnrm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10296) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10297) 	mov.l		SRC_HI(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10298) 	bset		&31,%d0			# DENORM src; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10299) 	mov.l		%d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10300) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10301) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10302) 	bra.w		fcmp_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10304) fcmp_dnrm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10305) 	mov.l		DST_EX(%a1),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10306) 	mov.l		DST_HI(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10307) 	bset		&31,%d0			# DENORM src; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10308) 	mov.l		%d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10309) 	mov.l		DST_LO(%a1),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10310) 	lea		FP_SCR0(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10311) 	bra.w		fcmp_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10313) fcmp_dnrm_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10314) 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10315) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10316) 	mov.l		DST_HI(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10317) 	bset		&31,%d0			# DENORM dst; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10318) 	mov.l		%d0,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10319) 	mov.l		SRC_HI(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10320) 	bset		&31,%d0			# DENORM dst; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10321) 	mov.l		%d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10322) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10323) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10324) 	lea		FP_SCR1(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10325) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10326) 	bra.w		fcmp_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10328) fcmp_nrm_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10329) 	mov.b		SRC_EX(%a0),%d0		# determine if like signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10330) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10331) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10332) 	bmi.w		fcmp_dnrm_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10334) # signs are the same, so must determine the answer ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10335) 	tst.b		%d0			# is src op negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10336) 	bmi.b		fcmp_nrm_dnrm_m		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10337) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10338) fcmp_nrm_dnrm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10339) 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10340) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10342) fcmp_dnrm_nrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10343) 	mov.b		SRC_EX(%a0),%d0		# determine if like signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10344) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10345) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10346) 	bmi.w		fcmp_dnrm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10348) # signs are the same, so must determine the answer ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10349) 	tst.b		%d0			# is src op negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10350) 	bpl.b		fcmp_dnrm_nrm_m		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10351) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10352) fcmp_dnrm_nrm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10353) 	mov.b		&neg_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10354) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10356) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10357) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10358) #	fsglmul(): emulates the fsglmul instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10359) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10360) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10361) #	scale_to_zero_src() - scale src exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10362) #	scale_to_zero_dst() - scale dst exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10363) #	unf_res4() - return default underflow result for sglop		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10364) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10365) #	res_qnan() - return QNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10366) #	res_snan() - return SNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10367) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10368) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10369) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10370) #	a1 = pointer to extended precision destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10371) #	d0  rnd prec,mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10372) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10373) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10374) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10375) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10376) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10377) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10378) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10379) # norms/denorms into ext/sgl/dbl precision.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10380) #	For norms/denorms, scale the exponents such that a multiply	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10381) # instruction won't cause an exception. Use the regular fsglmul to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10382) # compute a result. Check if the regular operands would have taken	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10383) # an exception. If so, return the default overflow/underflow result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10384) # and return the EXOP if exceptions are enabled. Else, scale the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10385) # result operand to the proper exponent.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10386) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10387) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10389) 	global		fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10390) fsglmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10391) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10393) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10394) 	mov.b		DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10395) 	lsl.b		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10396) 	or.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10398) 	bne.w		fsglmul_not_norm	# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10400) fsglmul_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10401) 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10402) 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10403) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10405) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10406) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10407) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10409) 	bsr.l		scale_to_zero_src	# scale exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10410) 	mov.l		%d0,-(%sp)		# save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10412) 	bsr.l		scale_to_zero_dst	# scale dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10414) 	add.l		(%sp)+,%d0		# SCALE_FACTOR = scale1 + scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10416) 	cmpi.l		%d0,&0x3fff-0x7ffe	# would result ovfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10417) 	beq.w		fsglmul_may_ovfl	# result may rnd to overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10418) 	blt.w		fsglmul_ovfl		# result will overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10420) 	cmpi.l		%d0,&0x3fff+0x0001	# would result unfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10421) 	beq.w		fsglmul_may_unfl	# result may rnd to no unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10422) 	bgt.w		fsglmul_unfl		# result will underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10424) fsglmul_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10425) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10427) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10428) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10430) 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10432) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10433) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10435) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10437) fsglmul_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10438) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10439) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10440) 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10441) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10442) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10443) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10444) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10445) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10446) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10447) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10448) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10449) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10451) fsglmul_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10452) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10454) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10455) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10457) 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10459) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10460) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10462) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10464) fsglmul_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10466) # save setting this until now because this is where fsglmul_may_ovfl may jump in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10467) 	or.l		&ovfl_inx_mask, USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10469) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10470) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10471) 	bne.b		fsglmul_ovfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10473) fsglmul_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10474) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10475) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10476) 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10477) 	andi.b		&0x30,%d0		# force prec = ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10478) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10479) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10480) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10481) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10483) fsglmul_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10484) 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10486) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10487) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10488) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10489) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10490) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10491) 	subi.l		&0x6000,%d1		# subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10492) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10493) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10494) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10495) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10496) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10497) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10498) 	bra.b		fsglmul_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10500) fsglmul_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10501) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10503) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10504) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10506) 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10508) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10509) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10511) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10513) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10514) 	fcmp.b		%fp1,&0x2		# is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10515) 	fbge.w		fsglmul_ovfl_tst	# yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10517) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10518) 	bra.w		fsglmul_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10520) fsglmul_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10521) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10523) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10525) 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10526) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10528) 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10530) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10531) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10533) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10535) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10536) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10537) 	bne.b		fsglmul_unfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10539) fsglmul_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10540) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10542) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10543) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10544) 	bsr.l		unf_res4		# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10545) 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10546) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10547) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10549) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10550) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10551) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10552) fsglmul_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10553) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10555) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10556) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10558) 	fsglmul.x	FP_SCR0(%a6),%fp1	# execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10560) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10562) 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10563) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10564) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10565) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10566) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10567) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10568) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10569) 	addi.l		&0x6000,%d1		# add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10570) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10571) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10572) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10573) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10574) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10575) 	bra.w		fsglmul_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10577) fsglmul_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10578) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10580) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10581) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10583) 	fsglmul.x	FP_SCR0(%a6),%fp0	# execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10585) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10586) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10588) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10590) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10591) 	fcmp.b		%fp1,&0x2		# is |result| > 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10592) 	fbgt.w		fsglmul_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10593) 	fblt.w		fsglmul_unfl		# yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10595) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10596) # we still don't know if underflow occurred. result is ~ equal to 2. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10597) # we don't know if the result was an underflow that rounded up to a 2 or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10598) # a normalized number that rounded down to a 2. so, redo the entire operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10599) # using RZ as the rounding mode to see what the pre-rounded result is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10600) # this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10601) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10602) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10604) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10605) 	andi.b		&0xc0,%d1		# keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10606) 	ori.b		&rz_mode*0x10,%d1	# insert RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10608) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10609) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10611) 	fsglmul.x	FP_SCR0(%a6),%fp1	# execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10613) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10614) 	fabs.x		%fp1			# make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10615) 	fcmp.b		%fp1,&0x2		# is |result| < 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10616) 	fbge.w		fsglmul_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10617) 	bra.w		fsglmul_unfl		# yes, underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10619) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10621) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10622) # Single Precision Multiply: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10623) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10624) fsglmul_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10625) 	mov.w		(tbl_fsglmul_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10626) 	jmp		(tbl_fsglmul_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10628) 	swbeg		&48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10629) tbl_fsglmul_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10630) 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10631) 	short		fsglmul_zero		- tbl_fsglmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10632) 	short		fsglmul_inf_src		- tbl_fsglmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10633) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10634) 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10635) 	short		fsglmul_res_snan	- tbl_fsglmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10636) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10637) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10639) 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10640) 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10641) 	short		fsglmul_res_operr	- tbl_fsglmul_op # ZERO x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10642) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # ZERO x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10643) 	short		fsglmul_zero		- tbl_fsglmul_op # ZERO x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10644) 	short		fsglmul_res_snan	- tbl_fsglmul_op # ZERO x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10645) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10646) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10648) 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10649) 	short		fsglmul_res_operr	- tbl_fsglmul_op # INF x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10650) 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10651) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # INF x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10652) 	short		fsglmul_inf_dst		- tbl_fsglmul_op # INF x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10653) 	short		fsglmul_res_snan	- tbl_fsglmul_op # INF x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10654) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10655) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10657) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10658) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10659) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10660) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10661) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # QNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10662) 	short		fsglmul_res_snan	- tbl_fsglmul_op # QNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10663) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10664) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10666) 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10667) 	short		fsglmul_zero		- tbl_fsglmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10668) 	short		fsglmul_inf_src		- tbl_fsglmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10669) 	short		fsglmul_res_qnan	- tbl_fsglmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10670) 	short		fsglmul_norm		- tbl_fsglmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10671) 	short		fsglmul_res_snan	- tbl_fsglmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10672) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10673) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10675) 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10676) 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10677) 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10678) 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10679) 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10680) 	short		fsglmul_res_snan	- tbl_fsglmul_op # SNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10681) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10682) 	short		tbl_fsglmul_op		- tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10684) fsglmul_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10685) 	bra.l		res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10686) fsglmul_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10687) 	bra.l		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10688) fsglmul_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10689) 	bra.l		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10690) fsglmul_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10691) 	bra.l		fmul_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10692) fsglmul_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10693) 	bra.l		fmul_inf_src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10694) fsglmul_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10695) 	bra.l		fmul_inf_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10697) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10698) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10699) #	fsgldiv(): emulates the fsgldiv instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10700) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10701) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10702) #	scale_to_zero_src() - scale src exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10703) #	scale_to_zero_dst() - scale dst exponent to zero		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10704) #	unf_res4() - return default underflow result for sglop		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10705) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10706) #	res_qnan() - return QNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10707) #	res_snan() - return SNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10708) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10709) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10710) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10711) #	a1 = pointer to extended precision destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10712) #	d0  rnd prec,mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10713) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10714) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10715) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10716) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10717) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10718) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10719) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10720) # norms/denorms into ext/sgl/dbl precision.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10721) #	For norms/denorms, scale the exponents such that a divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10722) # instruction won't cause an exception. Use the regular fsgldiv to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10723) # compute a result. Check if the regular operands would have taken	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10724) # an exception. If so, return the default overflow/underflow result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10725) # and return the EXOP if exceptions are enabled. Else, scale the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10726) # result operand to the proper exponent.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10727) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10728) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10730) 	global		fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10731) fsgldiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10732) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10734) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10735) 	mov.b		DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10736) 	lsl.b		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10737) 	or.b		STAG(%a6),%d1		# combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10739) 	bne.w		fsgldiv_not_norm	# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10741) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10742) # DIVIDE: NORMs and DENORMs ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10743) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10744) fsgldiv_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10745) 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10746) 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10747) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10749) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10750) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10751) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10753) 	bsr.l		scale_to_zero_src	# calculate scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10754) 	mov.l		%d0,-(%sp)		# save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10756) 	bsr.l		scale_to_zero_dst	# calculate scale factor 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10758) 	neg.l		(%sp)			# S.F. = scale1 - scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10759) 	add.l		%d0,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10761) 	mov.w		2+L_SCR3(%a6),%d1	# fetch precision,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10762) 	lsr.b		&0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10763) 	mov.l		(%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10764) 	cmpi.l		%d0,&0x3fff-0x7ffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10765) 	ble.w		fsgldiv_may_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10767) 	cmpi.l		%d0,&0x3fff-0x0000	# will result underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10768) 	beq.w		fsgldiv_may_unfl	# maybe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10769) 	bgt.w		fsgldiv_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10771) fsgldiv_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10772) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10774) 	fmov.l		L_SCR3(%a6),%fpcr	# save FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10775) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10777) 	fsgldiv.x	FP_SCR0(%a6),%fp0	# perform sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10779) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10780) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10782) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10784) fsgldiv_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10785) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store result on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10786) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10787) 	mov.w		FP_SCR0_EX(%a6),%d1	# load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10788) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10789) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10790) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10791) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10792) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10793) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10794) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10795) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10796) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10798) fsgldiv_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10799) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10801) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10802) 	fmov.l		&0x0,%fpsr		# set FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10804) 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10806) 	fmov.l		%fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10807) 	fmov.l		&0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10809) 	or.l		%d1,USER_FPSR(%a6)	# save INEX,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10811) 	fmovm.x		&0x01,-(%sp)		# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10812) 	mov.w		(%sp),%d1		# fetch new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10813) 	add.l		&0xc,%sp		# clear result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10814) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10815) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10816) 	cmp.l		%d1,&0x7fff		# did divide overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10817) 	blt.b		fsgldiv_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10819) fsgldiv_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10820) 	or.w		&ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10822) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10823) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10824) 	bne.b		fsgldiv_ovfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10826) fsgldiv_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10827) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10828) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10829) 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10830) 	andi.b		&0x30,%d0		# kill precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10831) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10832) 	or.b		%d0,FPSR_CC(%a6)	# set INF if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10833) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10834) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10836) fsgldiv_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10837) 	fmovm.x		&0x80,FP_SCR0(%a6)	# move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10839) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10840) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10841) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10842) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10843) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10844) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10845) 	subi.l		&0x6000,%d1		# subtract new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10846) 	andi.w		&0x7fff,%d1		# clear ms bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10847) 	or.w		%d2,%d1			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10848) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10849) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10850) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10851) 	bra.b		fsgldiv_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10853) fsgldiv_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10854) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10856) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10858) 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10859) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10861) 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10863) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10864) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10866) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10868) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10869) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10870) 	bne.b		fsgldiv_unfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10872) fsgldiv_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10873) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10875) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10876) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10877) 	bsr.l		unf_res4		# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10878) 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10879) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10880) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10882) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10883) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10884) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10885) fsgldiv_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10886) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10888) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10889) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10891) 	fsgldiv.x	FP_SCR0(%a6),%fp1	# execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10893) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10895) 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10896) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10897) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10898) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10899) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10900) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10901) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10902) 	addi.l		&0x6000,%d1		# add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10903) 	andi.w		&0x7fff,%d1		# clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10904) 	or.w		%d2,%d1			# concat old sign, new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10905) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10906) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10907) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10908) 	bra.b		fsgldiv_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10910) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10911) # the divide operation MAY underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10912) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10913) fsgldiv_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10914) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10916) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10917) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10919) 	fsgldiv.x	FP_SCR0(%a6),%fp0	# execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10921) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10922) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10924) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10926) 	fabs.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10927) 	fcmp.b		%fp1,&0x1		# is |result| > 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10928) 	fbgt.w		fsgldiv_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10929) 	fblt.w		fsgldiv_unfl		# yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10931) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10932) # we still don't know if underflow occurred. result is ~ equal to 1. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10933) # we don't know if the result was an underflow that rounded up to a 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10934) # or a normalized number that rounded down to a 1. so, redo the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10935) # operation using RZ as the rounding mode to see what the pre-rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10936) # result is. this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10937) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10938) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into %fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10940) 	clr.l		%d1			# clear scratch register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10941) 	ori.b		&rz_mode*0x10,%d1	# force RZ rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10943) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10944) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10946) 	fsgldiv.x	FP_SCR0(%a6),%fp1	# execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10948) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10949) 	fabs.x		%fp1			# make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10950) 	fcmp.b		%fp1,&0x1		# is |result| < 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10951) 	fbge.w		fsgldiv_normal_exit	# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10952) 	bra.w		fsgldiv_unfl		# yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10954) ############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10956) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10957) # Divide: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10958) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10959) fsgldiv_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10960) 	mov.w		(tbl_fsgldiv_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10961) 	jmp		(tbl_fsgldiv_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10963) 	swbeg		&48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10964) tbl_fsgldiv_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10965) 	short		fsgldiv_norm		- tbl_fsgldiv_op # NORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10966) 	short		fsgldiv_inf_load	- tbl_fsgldiv_op # NORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10967) 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # NORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10968) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # NORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10969) 	short		fsgldiv_norm		- tbl_fsgldiv_op # NORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10970) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # NORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10971) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10972) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10974) 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10975) 	short		fsgldiv_res_operr	- tbl_fsgldiv_op # ZERO / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10976) 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10977) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # ZERO / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10978) 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # ZERO / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10979) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # ZERO / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10980) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10981) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10983) 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10984) 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10985) 	short		fsgldiv_res_operr	- tbl_fsgldiv_op # INF / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10986) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # INF / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10987) 	short		fsgldiv_inf_dst		- tbl_fsgldiv_op # INF / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10988) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # INF / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10989) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10990) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10992) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10993) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10994) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10995) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10996) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # QNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10997) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # QNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10998) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10999) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11001) 	short		fsgldiv_norm		- tbl_fsgldiv_op # DENORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11002) 	short		fsgldiv_inf_load	- tbl_fsgldiv_op # DENORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11003) 	short		fsgldiv_zero_load	- tbl_fsgldiv_op # DENORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11004) 	short		fsgldiv_res_qnan	- tbl_fsgldiv_op # DENORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11005) 	short		fsgldiv_norm		- tbl_fsgldiv_op # DENORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11006) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # DENORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11007) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11008) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11010) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11011) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11012) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11013) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11014) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11015) 	short		fsgldiv_res_snan	- tbl_fsgldiv_op # SNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11016) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11017) 	short		tbl_fsgldiv_op		- tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11019) fsgldiv_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11020) 	bra.l		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11021) fsgldiv_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11022) 	bra.l		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11023) fsgldiv_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11024) 	bra.l		res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11025) fsgldiv_inf_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11026) 	bra.l		fdiv_inf_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11027) fsgldiv_zero_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11028) 	bra.l		fdiv_zero_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11029) fsgldiv_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11030) 	bra.l		fdiv_inf_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11032) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11033) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11034) #	fadd(): emulates the fadd instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11035) #	fsadd(): emulates the fadd instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11036) #	fdadd(): emulates the fdadd instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11037) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11038) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11039) #	addsub_scaler2() - scale the operands so they won't take exc	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11040) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11041) #	unf_res() - return default underflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11042) #	res_qnan() - set QNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11043) #	res_snan() - set SNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11044) #	res_operr() - set OPERR result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11045) #	scale_to_zero_src() - set src operand exponent equal to zero	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11046) #	scale_to_zero_dst() - set dst operand exponent equal to zero	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11047) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11048) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11049) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11050) #	a1 = pointer to extended precision destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11051) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11052) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11053) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11054) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11055) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11056) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11057) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11058) # norms into extended, single, and double precision.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11059) #	Do addition after scaling exponents such that exception won't	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11060) # occur. Then, check result exponent to see if exception would have	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11061) # occurred. If so, return default result and maybe EXOP. Else, insert	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11062) # the correct result exponent and return. Set FPSR bits as appropriate.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11063) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11064) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11066) 	global		fsadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11067) fsadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11068) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11069) 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11070) 	bra.b		fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11072) 	global		fdadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11073) fdadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11074) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11075) 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11077) 	global		fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11078) fadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11079) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11081) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11082) 	mov.b		DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11083) 	lsl.b		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11084) 	or.b		STAG(%a6),%d1		# combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11086) 	bne.w		fadd_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11088) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11089) # ADD: norms and denorms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11090) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11091) fadd_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11092) 	bsr.l		addsub_scaler2		# scale exponents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11094) fadd_zero_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11095) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11097) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11098) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11100) 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11102) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11103) 	fmov.l		%fpsr,%d1		# fetch INEX2,N,Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11105) 	or.l		%d1,USER_FPSR(%a6)	# save exc and ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11107) 	fbeq.w		fadd_zero_exit		# if result is zero, end now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11109) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11111) 	fmovm.x		&0x01,-(%sp)		# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11113) 	mov.w		2+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11114) 	lsr.b		&0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11116) 	mov.w		(%sp),%d2		# fetch new sign, exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11117) 	andi.l		&0x7fff,%d2		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11118) 	sub.l		%d0,%d2			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11120) 	cmp.l		%d2,(tbl_fadd_ovfl.b,%pc,%d1.w*4) # is it an overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11121) 	bge.b		fadd_ovfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11123) 	cmp.l		%d2,(tbl_fadd_unfl.b,%pc,%d1.w*4) # is it an underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11124) 	blt.w		fadd_unfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11125) 	beq.w		fadd_may_unfl		# maybe; go find out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11127) fadd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11128) 	mov.w		(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11129) 	andi.w		&0x8000,%d1		# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11130) 	or.w		%d2,%d1			# concat sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11131) 	mov.w		%d1,(%sp)		# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11133) 	fmovm.x		(%sp)+,&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11135) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11136) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11138) fadd_zero_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11139) #	fmov.s		&0x00000000,%fp0	# return zero in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11140) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11142) tbl_fadd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11143) 	long		0x7fff			# ext ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11144) 	long		0x407f			# sgl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11145) 	long		0x43ff			# dbl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11147) tbl_fadd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11148) 	long	        0x0000			# ext unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11149) 	long		0x3f81			# sgl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11150) 	long		0x3c01			# dbl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11152) fadd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11153) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11155) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11156) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11157) 	bne.b		fadd_ovfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11159) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11160) fadd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11161) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11162) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11163) 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11164) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11165) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11166) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11167) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11168) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11170) fadd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11171) 	mov.b		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11172) 	andi.b		&0xc0,%d1		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11173) 	bne.b		fadd_ovfl_ena_sd	# no; prec = sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11175) fadd_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11176) 	mov.w		(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11177) 	andi.w		&0x8000,%d1		# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11178) 	subi.l		&0x6000,%d2		# add extra bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11179) 	andi.w		&0x7fff,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11180) 	or.w		%d2,%d1			# concat sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11181) 	mov.w		%d1,(%sp)		# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11183) 	fmovm.x		(%sp)+,&0x40		# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11184) 	bra.b		fadd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11186) fadd_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11187) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11189) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11190) 	andi.b		&0x30,%d1		# keep rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11191) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11193) 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11195) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11197) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11198) 	fmovm.x		&0x01,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11199) 	bra.b		fadd_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11201) fadd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11202) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11204) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11206) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11208) 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11209) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11211) 	fadd.x		FP_SCR0(%a6),%fp0	# execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11213) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11214) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11216) 	or.l		%d1,USER_FPSR(%a6)	# save INEX,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11218) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11219) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11220) 	bne.b		fadd_unfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11222) fadd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11223) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11225) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11226) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11227) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11228) 	or.b		%d0,FPSR_CC(%a6)	# 'Z' bit may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11229) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11230) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11231) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11233) fadd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11234) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11236) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11237) 	andi.b		&0xc0,%d1		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11238) 	bne.b		fadd_unfl_ena_sd	# no; sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11240) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11242) fadd_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11243) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11245) 	fadd.x		FP_SCR0(%a6),%fp1	# execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11247) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11249) 	fmovm.x		&0x40,FP_SCR0(%a6)	# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11250) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11251) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11252) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11253) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11254) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11255) 	addi.l		&0x6000,%d1		# add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11256) 	andi.w		&0x7fff,%d1		# clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11257) 	or.w		%d2,%d1			# concat sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11258) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11259) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11260) 	bra.w		fadd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11262) fadd_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11263) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11264) 	andi.b		&0x30,%d1		# use only rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11265) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11267) 	bra.b		fadd_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11269) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11270) # result is equal to the smallest normalized number in the selected precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11271) # if the precision is extended, this result could not have come from an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11272) # underflow that rounded up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11273) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11274) fadd_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11275) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11276) 	andi.b		&0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11277) 	beq.w		fadd_normal		# yes; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11279) 	mov.l		0x4(%sp),%d1		# extract hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11280) 	cmpi.l		%d1,&0x80000000		# is hi(man) = 0x80000000?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11281) 	bne.w		fadd_normal		# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11283) 	tst.l		0x8(%sp)		# is lo(man) = 0x0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11284) 	bne.w		fadd_normal		# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11286) 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11287) 	beq.w		fadd_normal		# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11289) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11290) # ok, so now the result has a exponent equal to the smallest normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11291) # exponent for the selected precision. also, the mantissa is equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11292) # 0x8000000000000000 and this mantissa is the result of rounding non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11293) # g,r,s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11294) # now, we must determine whether the pre-rounded result was an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11295) # rounded "up" or a normalized number rounded "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11296) # so, we do this be re-executing the add using RZ as the rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11297) # seeing if the new result is smaller or equal to the current result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11298) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11299) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11301) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11302) 	andi.b		&0xc0,%d1		# keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11303) 	ori.b		&rz_mode*0x10,%d1	# insert rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11304) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11305) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11307) 	fadd.x		FP_SCR0(%a6),%fp1	# execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11309) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11311) 	fabs.x		%fp0			# compare absolute values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11312) 	fabs.x		%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11313) 	fcmp.x		%fp0,%fp1		# is first result > second?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11315) 	fbgt.w		fadd_unfl		# yes; it's an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11316) 	bra.w		fadd_normal		# no; it's not an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11318) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11320) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11321) # Add: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11322) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11323) fadd_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11324) 	mov.w		(tbl_fadd_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11325) 	jmp		(tbl_fadd_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11327) 	swbeg		&48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11328) tbl_fadd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11329) 	short		fadd_norm	- tbl_fadd_op # NORM + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11330) 	short		fadd_zero_src	- tbl_fadd_op # NORM + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11331) 	short		fadd_inf_src	- tbl_fadd_op # NORM + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11332) 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11333) 	short		fadd_norm	- tbl_fadd_op # NORM + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11334) 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11335) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11336) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11338) 	short		fadd_zero_dst	- tbl_fadd_op # ZERO + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11339) 	short		fadd_zero_2	- tbl_fadd_op # ZERO + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11340) 	short		fadd_inf_src	- tbl_fadd_op # ZERO + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11341) 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11342) 	short		fadd_zero_dst	- tbl_fadd_op # ZERO + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11343) 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11344) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11345) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11347) 	short		fadd_inf_dst	- tbl_fadd_op # INF + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11348) 	short		fadd_inf_dst	- tbl_fadd_op # INF + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11349) 	short		fadd_inf_2	- tbl_fadd_op # INF + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11350) 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11351) 	short		fadd_inf_dst	- tbl_fadd_op # INF + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11352) 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11353) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11354) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11356) 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11357) 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11358) 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11359) 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11360) 	short		fadd_res_qnan	- tbl_fadd_op # QNAN + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11361) 	short		fadd_res_snan	- tbl_fadd_op # QNAN + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11362) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11363) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11365) 	short		fadd_norm	- tbl_fadd_op # DENORM + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11366) 	short		fadd_zero_src	- tbl_fadd_op # DENORM + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11367) 	short		fadd_inf_src	- tbl_fadd_op # DENORM + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11368) 	short		fadd_res_qnan	- tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11369) 	short		fadd_norm	- tbl_fadd_op # DENORM + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11370) 	short		fadd_res_snan	- tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11371) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11372) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11374) 	short		fadd_res_snan	- tbl_fadd_op # SNAN + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11375) 	short		fadd_res_snan	- tbl_fadd_op # SNAN + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11376) 	short		fadd_res_snan	- tbl_fadd_op # SNAN + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11377) 	short		fadd_res_snan	- tbl_fadd_op # SNAN + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11378) 	short		fadd_res_snan	- tbl_fadd_op # SNAN + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11379) 	short		fadd_res_snan	- tbl_fadd_op # SNAN + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11380) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11381) 	short		tbl_fadd_op	- tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11383) fadd_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11384) 	bra.l		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11385) fadd_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11386) 	bra.l		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11388) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11389) # both operands are ZEROes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11390) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11391) fadd_zero_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11392) 	mov.b		SRC_EX(%a0),%d0		# are the signs opposite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11393) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11394) 	eor.b		%d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11395) 	bmi.w		fadd_zero_2_chk_rm	# weed out (-ZERO)+(+ZERO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11397) # the signs are the same. so determine whether they are positive or negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11398) # and return the appropriately signed zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11399) 	tst.b		%d0			# are ZEROes positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11400) 	bmi.b		fadd_zero_rm		# negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11401) 	fmov.s		&0x00000000,%fp0	# return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11402) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11403) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11405) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11406) # the ZEROes have opposite signs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11407) # - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11408) # - -ZERO is returned in the case of RM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11409) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11410) fadd_zero_2_chk_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11411) 	mov.b		3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11412) 	andi.b		&0x30,%d1		# extract rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11413) 	cmpi.b		%d1,&rm_mode*0x10	# is rnd mode == RM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11414) 	beq.b		fadd_zero_rm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11415) 	fmov.s		&0x00000000,%fp0	# return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11416) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11417) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11419) fadd_zero_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11420) 	fmov.s		&0x80000000,%fp0	# return -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11421) 	mov.b		&neg_bmask+z_bmask,FPSR_CC(%a6) # set NEG/Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11422) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11424) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11425) # one operand is a ZERO and the other is a DENORM or NORM. scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11426) # the DENORM or NORM and jump to the regular fadd routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11427) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11428) fadd_zero_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11429) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11430) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11431) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11432) 	bsr.l		scale_to_zero_src	# scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11433) 	clr.w		FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11434) 	clr.l		FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11435) 	clr.l		FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11436) 	bra.w		fadd_zero_entry		# go execute fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11438) fadd_zero_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11439) 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11440) 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11441) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11442) 	bsr.l		scale_to_zero_dst	# scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11443) 	clr.w		FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11444) 	clr.l		FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11445) 	clr.l		FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11446) 	bra.w		fadd_zero_entry		# go execute fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11448) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11449) # both operands are INFs. an OPERR will result if the INFs have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11450) # different signs. else, an INF of the same sign is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11451) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11452) fadd_inf_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11453) 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11454) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11455) 	eor.b		%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11456) 	bmi.l		res_operr		# weed out (-INF)+(+INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11458) # ok, so it's not an OPERR. but, we do have to remember to return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11459) # src INF since that's where the 881/882 gets the j-bit from...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11461) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11462) # operands are INF and one of {ZERO, INF, DENORM, NORM}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11463) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11464) fadd_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11465) 	fmovm.x		SRC(%a0),&0x80		# return src INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11466) 	tst.b		SRC_EX(%a0)		# is INF positive?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11467) 	bpl.b		fadd_inf_done		# yes; we're done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11468) 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11469) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11471) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11472) # operands are INF and one of {ZERO, INF, DENORM, NORM}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11473) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11474) fadd_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11475) 	fmovm.x		DST(%a1),&0x80		# return dst INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11476) 	tst.b		DST_EX(%a1)		# is INF positive?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11477) 	bpl.b		fadd_inf_done		# yes; we're done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11478) 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11479) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11481) fadd_inf_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11482) 	mov.b		&inf_bmask,FPSR_CC(%a6) # set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11483) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11485) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11486) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11487) #	fsub(): emulates the fsub instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11488) #	fssub(): emulates the fssub instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11489) #	fdsub(): emulates the fdsub instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11490) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11491) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11492) #	addsub_scaler2() - scale the operands so they won't take exc	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11493) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11494) #	unf_res() - return default underflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11495) #	res_qnan() - set QNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11496) #	res_snan() - set SNAN result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11497) #	res_operr() - set OPERR result					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11498) #	scale_to_zero_src() - set src operand exponent equal to zero	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11499) #	scale_to_zero_dst() - set dst operand exponent equal to zero	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11500) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11501) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11502) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11503) #	a1 = pointer to extended precision destination operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11504) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11505) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11506) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11507) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11508) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11509) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11510) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11511) # norms into extended, single, and double precision.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11512) #	Do subtraction after scaling exponents such that exception won't#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11513) # occur. Then, check result exponent to see if exception would have	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11514) # occurred. If so, return default result and maybe EXOP. Else, insert	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11515) # the correct result exponent and return. Set FPSR bits as appropriate.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11516) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11517) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11519) 	global		fssub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11520) fssub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11521) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11522) 	ori.b		&s_mode*0x10,%d0	# insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11523) 	bra.b		fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11525) 	global		fdsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11526) fdsub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11527) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11528) 	ori.b		&d_mode*0x10,%d0	# insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11530) 	global		fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11531) fsub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11532) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11534) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11535) 	mov.b		DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11536) 	lsl.b		&0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11537) 	or.b		STAG(%a6),%d1		# combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11539) 	bne.w		fsub_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11541) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11542) # SUB: norms and denorms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11543) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11544) fsub_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11545) 	bsr.l		addsub_scaler2		# scale exponents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11547) fsub_zero_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11548) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11550) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11551) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11553) 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11555) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11556) 	fmov.l		%fpsr,%d1		# fetch INEX2, N, Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11558) 	or.l		%d1,USER_FPSR(%a6)	# save exc and ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11560) 	fbeq.w		fsub_zero_exit		# if result zero, end now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11562) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11564) 	fmovm.x		&0x01,-(%sp)		# save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11566) 	mov.w		2+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11567) 	lsr.b		&0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11569) 	mov.w		(%sp),%d2		# fetch new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11570) 	andi.l		&0x7fff,%d2		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11571) 	sub.l		%d0,%d2			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11573) 	cmp.l		%d2,(tbl_fsub_ovfl.b,%pc,%d1.w*4) # is it an overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11574) 	bge.b		fsub_ovfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11576) 	cmp.l		%d2,(tbl_fsub_unfl.b,%pc,%d1.w*4) # is it an underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11577) 	blt.w		fsub_unfl		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11578) 	beq.w		fsub_may_unfl		# maybe; go find out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11580) fsub_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11581) 	mov.w		(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11582) 	andi.w		&0x8000,%d1		# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11583) 	or.w		%d2,%d1			# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11584) 	mov.w		%d1,(%sp)		# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11586) 	fmovm.x		(%sp)+,&0x80		# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11588) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11589) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11591) fsub_zero_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11592) #	fmov.s		&0x00000000,%fp0	# return zero in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11593) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11595) tbl_fsub_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11596) 	long		0x7fff			# ext ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11597) 	long		0x407f			# sgl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11598) 	long		0x43ff			# dbl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11600) tbl_fsub_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11601) 	long	        0x0000			# ext unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11602) 	long		0x3f81			# sgl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11603) 	long		0x3c01			# dbl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11605) fsub_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11606) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11608) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11609) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11610) 	bne.b		fsub_ovfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11612) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11613) fsub_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11614) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11615) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11616) 	mov.l		L_SCR3(%a6),%d0		# pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11617) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11618) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11619) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11620) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11621) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11623) fsub_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11624) 	mov.b		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11625) 	andi.b		&0xc0,%d1		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11626) 	bne.b		fsub_ovfl_ena_sd	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11628) fsub_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11629) 	mov.w		(%sp),%d1		# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11630) 	andi.w		&0x8000,%d1		# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11631) 	subi.l		&0x6000,%d2		# subtract new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11632) 	andi.w		&0x7fff,%d2		# clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11633) 	or.w		%d2,%d1			# concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11634) 	mov.w		%d1,(%sp)		# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11636) 	fmovm.x		(%sp)+,&0x40		# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11637) 	bra.b		fsub_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11639) fsub_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11640) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11642) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11643) 	andi.b		&0x30,%d1		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11644) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11646) 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11648) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11650) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11651) 	fmovm.x		&0x01,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11652) 	bra.b		fsub_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11654) fsub_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11655) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11657) 	add.l		&0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11659) 	fmovm.x		FP_SCR1(%a6),&0x80	# load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11661) 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11662) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11664) 	fsub.x		FP_SCR0(%a6),%fp0	# execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11666) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11667) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11669) 	or.l		%d1,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11671) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11672) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11673) 	bne.b		fsub_unfl_ena		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11675) fsub_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11676) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11678) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11679) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11680) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11681) 	or.b		%d0,FPSR_CC(%a6)	# 'Z' may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11682) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11683) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11684) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11686) fsub_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11687) 	fmovm.x		FP_SCR1(%a6),&0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11689) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11690) 	andi.b		&0xc0,%d1		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11691) 	bne.b		fsub_unfl_ena_sd	# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11693) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11695) fsub_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11696) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11698) 	fsub.x		FP_SCR0(%a6),%fp1	# execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11700) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11702) 	fmovm.x		&0x40,FP_SCR0(%a6)	# store result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11703) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11704) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11705) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11706) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11707) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11708) 	addi.l		&0x6000,%d1		# subtract new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11709) 	andi.w		&0x7fff,%d1		# clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11710) 	or.w		%d2,%d1			# concat sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11711) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11712) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11713) 	bra.w		fsub_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11715) fsub_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11716) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11717) 	andi.b		&0x30,%d1		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11718) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11720) 	bra.b		fsub_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11722) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11723) # result is equal to the smallest normalized number in the selected precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11724) # if the precision is extended, this result could not have come from an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11725) # underflow that rounded up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11726) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11727) fsub_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11728) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11729) 	andi.b		&0xc0,%d1		# fetch rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11730) 	beq.w		fsub_normal		# yes; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11732) 	mov.l		0x4(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11733) 	cmpi.l		%d1,&0x80000000		# is hi(man) = 0x80000000?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11734) 	bne.w		fsub_normal		# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11736) 	tst.l		0x8(%sp)		# is lo(man) = 0x0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11737) 	bne.w		fsub_normal		# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11739) 	btst		&inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11740) 	beq.w		fsub_normal		# no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11742) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11743) # ok, so now the result has a exponent equal to the smallest normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11744) # exponent for the selected precision. also, the mantissa is equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11745) # 0x8000000000000000 and this mantissa is the result of rounding non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11746) # g,r,s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11747) # now, we must determine whether the pre-rounded result was an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11748) # rounded "up" or a normalized number rounded "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11749) # so, we do this be re-executing the add using RZ as the rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11750) # seeing if the new result is smaller or equal to the current result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11751) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11752) 	fmovm.x		FP_SCR1(%a6),&0x40	# load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11754) 	mov.l		L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11755) 	andi.b		&0xc0,%d1		# keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11756) 	ori.b		&rz_mode*0x10,%d1	# insert rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11757) 	fmov.l		%d1,%fpcr		# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11758) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11760) 	fsub.x		FP_SCR0(%a6),%fp1	# execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11762) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11764) 	fabs.x		%fp0			# compare absolute values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11765) 	fabs.x		%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11766) 	fcmp.x		%fp0,%fp1		# is first result > second?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11768) 	fbgt.w		fsub_unfl		# yes; it's an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11769) 	bra.w		fsub_normal		# no; it's not an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11771) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11773) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11774) # Sub: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11775) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11776) fsub_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11777) 	mov.w		(tbl_fsub_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11778) 	jmp		(tbl_fsub_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11780) 	swbeg		&48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11781) tbl_fsub_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11782) 	short		fsub_norm	- tbl_fsub_op # NORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11783) 	short		fsub_zero_src	- tbl_fsub_op # NORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11784) 	short		fsub_inf_src	- tbl_fsub_op # NORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11785) 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11786) 	short		fsub_norm	- tbl_fsub_op # NORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11787) 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11788) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11789) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11791) 	short		fsub_zero_dst	- tbl_fsub_op # ZERO - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11792) 	short		fsub_zero_2	- tbl_fsub_op # ZERO - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11793) 	short		fsub_inf_src	- tbl_fsub_op # ZERO - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11794) 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11795) 	short		fsub_zero_dst	- tbl_fsub_op # ZERO - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11796) 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11797) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11798) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11800) 	short		fsub_inf_dst	- tbl_fsub_op # INF - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11801) 	short		fsub_inf_dst	- tbl_fsub_op # INF - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11802) 	short		fsub_inf_2	- tbl_fsub_op # INF - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11803) 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11804) 	short		fsub_inf_dst	- tbl_fsub_op # INF - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11805) 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11806) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11807) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11809) 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11810) 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11811) 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11812) 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11813) 	short		fsub_res_qnan	- tbl_fsub_op # QNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11814) 	short		fsub_res_snan	- tbl_fsub_op # QNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11815) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11816) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11818) 	short		fsub_norm	- tbl_fsub_op # DENORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11819) 	short		fsub_zero_src	- tbl_fsub_op # DENORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11820) 	short		fsub_inf_src	- tbl_fsub_op # DENORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11821) 	short		fsub_res_qnan	- tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11822) 	short		fsub_norm	- tbl_fsub_op # DENORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11823) 	short		fsub_res_snan	- tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11824) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11825) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11827) 	short		fsub_res_snan	- tbl_fsub_op # SNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11828) 	short		fsub_res_snan	- tbl_fsub_op # SNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11829) 	short		fsub_res_snan	- tbl_fsub_op # SNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11830) 	short		fsub_res_snan	- tbl_fsub_op # SNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11831) 	short		fsub_res_snan	- tbl_fsub_op # SNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11832) 	short		fsub_res_snan	- tbl_fsub_op # SNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11833) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11834) 	short		tbl_fsub_op	- tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11836) fsub_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11837) 	bra.l		res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11838) fsub_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11839) 	bra.l		res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11841) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11842) # both operands are ZEROes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11843) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11844) fsub_zero_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11845) 	mov.b		SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11846) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11847) 	eor.b		%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11848) 	bpl.b		fsub_zero_2_chk_rm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11850) # the signs are opposite, so, return a ZERO w/ the sign of the dst ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11851) 	tst.b		%d0			# is dst negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11852) 	bmi.b		fsub_zero_2_rm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11853) 	fmov.s		&0x00000000,%fp0	# no; return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11854) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11855) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11857) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11858) # the ZEROes have the same signs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11859) # - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11860) # - -ZERO is returned in the case of RM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11861) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11862) fsub_zero_2_chk_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11863) 	mov.b		3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11864) 	andi.b		&0x30,%d1		# extract rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11865) 	cmpi.b		%d1,&rm_mode*0x10	# is rnd mode = RM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11866) 	beq.b		fsub_zero_2_rm		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11867) 	fmov.s		&0x00000000,%fp0	# no; return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11868) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11869) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11871) fsub_zero_2_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11872) 	fmov.s		&0x80000000,%fp0	# return -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11873) 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set Z/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11874) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11876) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11877) # one operand is a ZERO and the other is a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11878) # scale the DENORM or NORM and jump to the regular fsub routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11879) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11880) fsub_zero_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11881) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11882) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11883) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11884) 	bsr.l		scale_to_zero_src	# scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11885) 	clr.w		FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11886) 	clr.l		FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11887) 	clr.l		FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11888) 	bra.w		fsub_zero_entry		# go execute fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11890) fsub_zero_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11891) 	mov.w		DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11892) 	mov.l		DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11893) 	mov.l		DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11894) 	bsr.l		scale_to_zero_dst	# scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11895) 	clr.w		FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11896) 	clr.l		FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11897) 	clr.l		FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11898) 	bra.w		fsub_zero_entry		# go execute fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11900) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11901) # both operands are INFs. an OPERR will result if the INFs have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11902) # same signs. else,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11903) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11904) fsub_inf_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11905) 	mov.b		SRC_EX(%a0),%d0		# exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11906) 	mov.b		DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11907) 	eor.b		%d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11908) 	bpl.l		res_operr		# weed out (-INF)+(+INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11910) # ok, so it's not an OPERR. but we do have to remember to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11911) # the src INF since that's where the 881/882 gets the j-bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11913) fsub_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11914) 	fmovm.x		SRC(%a0),&0x80		# return src INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11915) 	fneg.x		%fp0			# invert sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11916) 	fbge.w		fsub_inf_done		# sign is now positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11917) 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11918) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11920) fsub_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11921) 	fmovm.x		DST(%a1),&0x80		# return dst INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11922) 	tst.b		DST_EX(%a1)		# is INF negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11923) 	bpl.b		fsub_inf_done		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11924) 	mov.b		&neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11925) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11927) fsub_inf_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11928) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11929) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11931) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11932) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11933) #	fsqrt(): emulates the fsqrt instruction				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11934) #	fssqrt(): emulates the fssqrt instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11935) #	fdsqrt(): emulates the fdsqrt instruction			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11936) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11937) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11938) #	scale_sqrt() - scale the source operand				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11939) #	unf_res() - return default underflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11940) #	ovf_res() - return default overflow result			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11941) #	res_qnan_1op() - return QNAN result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11942) #	res_snan_1op() - return SNAN result				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11943) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11944) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11945) #	a0 = pointer to extended precision source operand		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11946) #	d0  rnd prec,mode						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11947) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11948) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11949) #	fp0 = result							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11950) #	fp1 = EXOP (if exception occurred)				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11951) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11952) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11953) #	Handle NANs, infinities, and zeroes as special cases. Divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11954) # norms/denorms into ext/sgl/dbl precision.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11955) #	For norms/denorms, scale the exponents such that a sqrt		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11956) # instruction won't cause an exception. Use the regular fsqrt to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11957) # compute a result. Check if the regular operands would have taken	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11958) # an exception. If so, return the default overflow/underflow result	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11959) # and return the EXOP if exceptions are enabled. Else, scale the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11960) # result operand to the proper exponent.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11961) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11962) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11964) 	global		fssqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11965) fssqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11966) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11967) 	ori.b		&s_mode*0x10,%d0	# insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11968) 	bra.b		fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11970) 	global		fdsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11971) fdsqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11972) 	andi.b		&0x30,%d0		# clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11973) 	ori.b		&d_mode*0x10,%d0	# insert dbl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11975) 	global		fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11976) fsqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11977) 	mov.l		%d0,L_SCR3(%a6)		# store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11978) 	clr.w		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11979) 	mov.b		STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11980) 	bne.w		fsqrt_not_norm		# optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11982) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11983) # SQUARE ROOT: norms and denorms ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11984) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11985) fsqrt_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11986) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11987) 	bmi.l		res_operr		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11989) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11990) 	bne.b		fsqrt_not_ext		# no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11992) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11993) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11995) 	fsqrt.x		(%a0),%fp0		# execute square root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11997) 	fmov.l		%fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11998) 	or.l		%d1,USER_FPSR(%a6)	# set N,INEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12000) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12002) fsqrt_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12003) 	tst.b		SRC_EX(%a0)		# is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12004) 	bmi.l		res_operr		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12006) 	andi.b		&0xc0,%d0		# is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12007) 	bne.b		fsqrt_not_ext		# no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12009) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12010) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12011) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12013) 	bsr.l		scale_sqrt		# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12015) 	bra.w		fsqrt_sd_normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12017) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12018) # operand is either single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12019) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12020) fsqrt_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12021) 	cmpi.b		%d0,&s_mode*0x10	# separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12022) 	bne.w		fsqrt_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12024) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12025) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12026) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12027) fsqrt_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12028) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12029) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12030) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12032) 	bsr.l		scale_sqrt		# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12034) 	cmpi.l		%d0,&0x3fff-0x3f81	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12035) 	beq.w		fsqrt_sd_may_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12036) 	bgt.w		fsqrt_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12037) 	cmpi.l		%d0,&0x3fff-0x407f	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12038) 	beq.w		fsqrt_sd_may_ovfl	# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12039) 	blt.w		fsqrt_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12041) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12042) # operand will NOT overflow or underflow when moved in to the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12043) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12044) fsqrt_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12045) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12046) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12048) 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12050) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12051) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12053) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12055) fsqrt_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12056) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12057) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12058) 	mov.w		FP_SCR0_EX(%a6),%d1	# load sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12059) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12060) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12061) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12062) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12063) 	or.w		%d1,%d2			# concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12064) 	mov.w		%d2,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12065) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12066) 	fmovm.x		FP_SCR0(%a6),&0x80	# return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12067) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12069) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12070) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12071) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12072) fsqrt_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12073) 	mov.w		SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12074) 	mov.l		SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12075) 	mov.l		SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12077) 	bsr.l		scale_sqrt		# calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12079) 	cmpi.l		%d0,&0x3fff-0x3c01	# will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12080) 	beq.w		fsqrt_sd_may_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12081) 	bgt.b		fsqrt_sd_unfl		# yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12082) 	cmpi.l		%d0,&0x3fff-0x43ff	# will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12083) 	beq.w		fsqrt_sd_may_ovfl	# maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12084) 	blt.w		fsqrt_sd_ovfl		# yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12085) 	bra.w		fsqrt_sd_normal		# no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12087) # we're on the line here and the distinguising characteristic is whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12088) # the exponent is 3fff or 3ffe. if it's 3ffe, then it's a safe number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12089) # elsewise fall through to underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12090) fsqrt_sd_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12091) 	btst		&0x0,1+FP_SCR0_EX(%a6)	# is exponent 0x3fff?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12092) 	bne.w		fsqrt_sd_normal		# yes, so no underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12094) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12095) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12096) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12097) fsqrt_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12098) 	bset		&unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12100) 	fmov.l		&rz_mode*0x10,%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12101) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12103) 	fsqrt.x		FP_SCR0(%a6),%fp0	# execute square root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12105) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12106) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12108) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12110) # if underflow or inexact is enabled, go calculate EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12111) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12112) 	andi.b		&0x0b,%d1		# is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12113) 	bne.b		fsqrt_sd_unfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12115) fsqrt_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12116) 	fmovm.x		&0x80,FP_SCR0(%a6)	# store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12118) 	lea		FP_SCR0(%a6),%a0	# pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12119) 	mov.l		L_SCR3(%a6),%d1		# pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12120) 	bsr.l		unf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12121) 	or.b		%d0,FPSR_CC(%a6)	# set possible 'Z' ccode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12122) 	fmovm.x		FP_SCR0(%a6),&0x80	# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12123) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12125) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12126) # operand will underflow AND underflow is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12127) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12128) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12129) fsqrt_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12130) 	mov.l		FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12131) 	mov.l		FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12132) 	mov.w		FP_SCR0_EX(%a6),%d1	# load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12134) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12135) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12136) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12137) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12138) 	sub.l		%d0,%d1			# subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12139) 	addi.l		&0x6000,%d1		# add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12140) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12141) 	or.w		%d2,%d1			# concat new sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12142) 	mov.w		%d1,FP_SCR1_EX(%a6)	# insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12143) 	fmovm.x		FP_SCR1(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12144) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12145) 	bra.b		fsqrt_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12147) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12148) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12149) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12150) fsqrt_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12151) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12152) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12154) 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform square root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12156) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12157) 	fmov.l		%fpsr,%d1		# save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12159) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12161) fsqrt_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12162) 	or.l		&ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12164) 	mov.b		FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12165) 	andi.b		&0x13,%d1		# is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12166) 	bne.b		fsqrt_sd_ovfl_ena	# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12168) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12169) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12170) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12171) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12172) fsqrt_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12173) 	btst		&neg_bit,FPSR_CC(%a6)	# is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12174) 	sne		%d1			# set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12175) 	mov.l		L_SCR3(%a6),%d0		# pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12176) 	bsr.l		ovf_res			# calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12177) 	or.b		%d0,FPSR_CC(%a6)	# set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12178) 	fmovm.x		(%a0),&0x80		# return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12179) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12181) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12182) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12183) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12184) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12185) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12186) fsqrt_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12187) 	mov.l		%d2,-(%sp)		# save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12188) 	mov.w		FP_SCR0_EX(%a6),%d1	# fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12189) 	mov.l		%d1,%d2			# make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12190) 	andi.l		&0x7fff,%d1		# strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12191) 	andi.w		&0x8000,%d2		# keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12192) 	sub.l		%d0,%d1			# add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12193) 	subi.l		&0x6000,%d1		# subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12194) 	andi.w		&0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12195) 	or.w		%d2,%d1			# concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12196) 	mov.w		%d1,FP_SCR0_EX(%a6)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12197) 	fmovm.x		FP_SCR0(%a6),&0x40	# return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12198) 	mov.l		(%sp)+,%d2		# restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12199) 	bra.b		fsqrt_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12201) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12202) # the move in MAY underflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12203) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12204) fsqrt_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12205) 	btst		&0x0,1+FP_SCR0_EX(%a6)	# is exponent 0x3fff?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12206) 	bne.w		fsqrt_sd_ovfl		# yes, so overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12208) 	fmov.l		&0x0,%fpsr		# clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12209) 	fmov.l		L_SCR3(%a6),%fpcr	# set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12211) 	fsqrt.x		FP_SCR0(%a6),%fp0	# perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12213) 	fmov.l		%fpsr,%d1		# save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12214) 	fmov.l		&0x0,%fpcr		# clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12216) 	or.l		%d1,USER_FPSR(%a6)	# save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12218) 	fmov.x		%fp0,%fp1		# make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12219) 	fcmp.b		%fp1,&0x1		# is |result| >= 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12220) 	fbge.w		fsqrt_sd_ovfl_tst	# yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12222) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12223) 	bra.w		fsqrt_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12225) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12227) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12228) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12229) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12230) fsqrt_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12231) 	cmpi.b		%d1,&DENORM		# weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12232) 	beq.w		fsqrt_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12233) 	cmpi.b		%d1,&ZERO		# weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12234) 	beq.b		fsqrt_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12235) 	cmpi.b		%d1,&INF		# weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12236) 	beq.b		fsqrt_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12237) 	cmpi.b		%d1,&SNAN		# weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12238) 	beq.l		res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12239) 	bra.l		res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12241) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12242) #	fsqrt(+0) = +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12243) #	fsqrt(-0) = -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12244) #	fsqrt(+INF) = +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12245) #	fsqrt(-INF) = OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12246) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12247) fsqrt_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12248) 	tst.b		SRC_EX(%a0)		# is ZERO positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12249) 	bmi.b		fsqrt_zero_m		# negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12250) fsqrt_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12251) 	fmov.s		&0x00000000,%fp0	# return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12252) 	mov.b		&z_bmask,FPSR_CC(%a6)	# set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12253) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12254) fsqrt_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12255) 	fmov.s		&0x80000000,%fp0	# return -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12256) 	mov.b		&z_bmask+neg_bmask,FPSR_CC(%a6)	# set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12257) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12259) fsqrt_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12260) 	tst.b		SRC_EX(%a0)		# is INF positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12261) 	bmi.l		res_operr		# negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12262) fsqrt_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12263) 	fmovm.x		SRC(%a0),&0x80		# return +INF in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12264) 	mov.b		&inf_bmask,FPSR_CC(%a6)	# set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12265) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12267) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12268) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12269) #	fetch_dreg(): fetch register according to index in d1		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12270) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12271) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12272) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12273) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12274) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12275) #	d1 = index of register to fetch from				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12276) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12277) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12278) #	d0 = value of register fetched					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12279) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12280) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12281) #	According to the index value in d1 which can range from zero	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12282) # to fifteen, load the corresponding register file value (where		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12283) # address register indexes start at 8). D0/D1/A0/A1/A6/A7 are on the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12284) # stack. The rest should still be in their original places.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12285) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12286) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12288) # this routine leaves d1 intact for subsequent store_dreg calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12289) 	global		fetch_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12290) fetch_dreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12291) 	mov.w		(tbl_fdreg.b,%pc,%d1.w*2),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12292) 	jmp		(tbl_fdreg.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12294) tbl_fdreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12295) 	short		fdreg0 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12296) 	short		fdreg1 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12297) 	short		fdreg2 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12298) 	short		fdreg3 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12299) 	short		fdreg4 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12300) 	short		fdreg5 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12301) 	short		fdreg6 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12302) 	short		fdreg7 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12303) 	short		fdreg8 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12304) 	short		fdreg9 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12305) 	short		fdrega - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12306) 	short		fdregb - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12307) 	short		fdregc - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12308) 	short		fdregd - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12309) 	short		fdrege - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12310) 	short		fdregf - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12312) fdreg0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12313) 	mov.l		EXC_DREGS+0x0(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12314) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12315) fdreg1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12316) 	mov.l		EXC_DREGS+0x4(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12317) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12318) fdreg2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12319) 	mov.l		%d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12320) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12321) fdreg3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12322) 	mov.l		%d3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12323) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12324) fdreg4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12325) 	mov.l		%d4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12326) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12327) fdreg5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12328) 	mov.l		%d5,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12329) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12330) fdreg6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12331) 	mov.l		%d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12332) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12333) fdreg7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12334) 	mov.l		%d7,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12335) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12336) fdreg8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12337) 	mov.l		EXC_DREGS+0x8(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12338) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12339) fdreg9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12340) 	mov.l		EXC_DREGS+0xc(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12341) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12342) fdrega:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12343) 	mov.l		%a2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12344) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12345) fdregb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12346) 	mov.l		%a3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12347) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12348) fdregc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12349) 	mov.l		%a4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12350) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12351) fdregd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12352) 	mov.l		%a5,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12353) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12354) fdrege:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12355) 	mov.l		(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12356) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12357) fdregf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12358) 	mov.l		EXC_A7(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12359) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12361) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12362) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12363) #	store_dreg_l(): store longword to data register specified by d1	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12364) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12365) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12366) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12367) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12368) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12369) #	d0 = longowrd value to store					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12370) #	d1 = index of register to fetch from				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12371) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12372) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12373) #	(data register is updated)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12374) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12375) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12376) #	According to the index value in d1, store the longword value	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12377) # in d0 to the corresponding data register. D0/D1 are on the stack	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12378) # while the rest are in their initial places.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12379) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12380) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12382) 	global		store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12383) store_dreg_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12384) 	mov.w		(tbl_sdregl.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12385) 	jmp		(tbl_sdregl.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12387) tbl_sdregl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12388) 	short		sdregl0 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12389) 	short		sdregl1 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12390) 	short		sdregl2 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12391) 	short		sdregl3 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12392) 	short		sdregl4 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12393) 	short		sdregl5 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12394) 	short		sdregl6 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12395) 	short		sdregl7 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12397) sdregl0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12398) 	mov.l		%d0,EXC_DREGS+0x0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12399) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12400) sdregl1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12401) 	mov.l		%d0,EXC_DREGS+0x4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12402) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12403) sdregl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12404) 	mov.l		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12405) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12406) sdregl3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12407) 	mov.l		%d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12408) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12409) sdregl4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12410) 	mov.l		%d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12411) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12412) sdregl5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12413) 	mov.l		%d0,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12414) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12415) sdregl6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12416) 	mov.l		%d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12417) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12418) sdregl7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12419) 	mov.l		%d0,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12420) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12422) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12423) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12424) #	store_dreg_w(): store word to data register specified by d1	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12425) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12426) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12427) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12428) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12429) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12430) #	d0 = word value to store					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12431) #	d1 = index of register to fetch from				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12432) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12433) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12434) #	(data register is updated)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12435) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12436) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12437) #	According to the index value in d1, store the word value	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12438) # in d0 to the corresponding data register. D0/D1 are on the stack	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12439) # while the rest are in their initial places.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12440) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12441) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12443) 	global		store_dreg_w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12444) store_dreg_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12445) 	mov.w		(tbl_sdregw.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12446) 	jmp		(tbl_sdregw.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12448) tbl_sdregw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12449) 	short		sdregw0 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12450) 	short		sdregw1 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12451) 	short		sdregw2 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12452) 	short		sdregw3 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12453) 	short		sdregw4 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12454) 	short		sdregw5 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12455) 	short		sdregw6 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12456) 	short		sdregw7 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12458) sdregw0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12459) 	mov.w		%d0,2+EXC_DREGS+0x0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12460) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12461) sdregw1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12462) 	mov.w		%d0,2+EXC_DREGS+0x4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12463) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12464) sdregw2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12465) 	mov.w		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12466) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12467) sdregw3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12468) 	mov.w		%d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12469) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12470) sdregw4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12471) 	mov.w		%d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12472) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12473) sdregw5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12474) 	mov.w		%d0,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12475) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12476) sdregw6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12477) 	mov.w		%d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12478) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12479) sdregw7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12480) 	mov.w		%d0,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12481) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12483) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12484) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12485) #	store_dreg_b(): store byte to data register specified by d1	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12486) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12487) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12488) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12489) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12490) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12491) #	d0 = byte value to store					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12492) #	d1 = index of register to fetch from				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12493) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12494) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12495) #	(data register is updated)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12496) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12497) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12498) #	According to the index value in d1, store the byte value	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12499) # in d0 to the corresponding data register. D0/D1 are on the stack	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12500) # while the rest are in their initial places.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12501) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12502) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12504) 	global		store_dreg_b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12505) store_dreg_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12506) 	mov.w		(tbl_sdregb.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12507) 	jmp		(tbl_sdregb.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12509) tbl_sdregb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12510) 	short		sdregb0 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12511) 	short		sdregb1 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12512) 	short		sdregb2 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12513) 	short		sdregb3 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12514) 	short		sdregb4 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12515) 	short		sdregb5 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12516) 	short		sdregb6 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12517) 	short		sdregb7 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12519) sdregb0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12520) 	mov.b		%d0,3+EXC_DREGS+0x0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12521) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12522) sdregb1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12523) 	mov.b		%d0,3+EXC_DREGS+0x4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12524) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12525) sdregb2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12526) 	mov.b		%d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12527) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12528) sdregb3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12529) 	mov.b		%d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12530) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12531) sdregb4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12532) 	mov.b		%d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12533) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12534) sdregb5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12535) 	mov.b		%d0,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12536) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12537) sdregb6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12538) 	mov.b		%d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12539) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12540) sdregb7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12541) 	mov.b		%d0,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12542) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12544) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12545) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12546) #	inc_areg(): increment an address register by the value in d0	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12547) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12548) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12549) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12550) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12551) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12552) #	d0 = amount to increment by					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12553) #	d1 = index of address register to increment			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12554) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12555) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12556) #	(address register is updated)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12557) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12558) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12559) #	Typically used for an instruction w/ a post-increment <ea>,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12560) # this routine adds the increment value in d0 to the address register	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12561) # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12562) # in their original places.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12563) #	For a7, if the increment amount is one, then we have to		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12564) # increment by two. For any a7 update, set the mia7_flag so that if	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12565) # an access error exception occurs later in emulation, this address	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12566) # register update can be undone.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12567) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12568) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12570) 	global		inc_areg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12571) inc_areg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12572) 	mov.w		(tbl_iareg.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12573) 	jmp		(tbl_iareg.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12575) tbl_iareg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12576) 	short		iareg0 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12577) 	short		iareg1 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12578) 	short		iareg2 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12579) 	short		iareg3 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12580) 	short		iareg4 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12581) 	short		iareg5 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12582) 	short		iareg6 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12583) 	short		iareg7 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12585) iareg0:	add.l		%d0,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12586) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12587) iareg1:	add.l		%d0,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12588) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12589) iareg2:	add.l		%d0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12590) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12591) iareg3:	add.l		%d0,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12592) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12593) iareg4:	add.l		%d0,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12594) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12595) iareg5:	add.l		%d0,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12596) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12597) iareg6:	add.l		%d0,(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12598) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12599) iareg7:	mov.b		&mia7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12600) 	cmpi.b		%d0,&0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12601) 	beq.b		iareg7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12602) 	add.l		%d0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12603) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12604) iareg7b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12605) 	addq.l		&0x2,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12606) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12608) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12609) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12610) #	dec_areg(): decrement an address register by the value in d0	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12611) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12612) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12613) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12614) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12615) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12616) #	d0 = amount to decrement by					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12617) #	d1 = index of address register to decrement			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12618) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12619) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12620) #	(address register is updated)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12621) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12622) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12623) #	Typically used for an instruction w/ a pre-decrement <ea>,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12624) # this routine adds the decrement value in d0 to the address register	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12625) # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12626) # in their original places.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12627) #	For a7, if the decrement amount is one, then we have to		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12628) # decrement by two. For any a7 update, set the mda7_flag so that if	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12629) # an access error exception occurs later in emulation, this address	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12630) # register update can be undone.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12631) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12632) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12634) 	global		dec_areg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12635) dec_areg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12636) 	mov.w		(tbl_dareg.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12637) 	jmp		(tbl_dareg.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12639) tbl_dareg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12640) 	short		dareg0 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12641) 	short		dareg1 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12642) 	short		dareg2 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12643) 	short		dareg3 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12644) 	short		dareg4 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12645) 	short		dareg5 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12646) 	short		dareg6 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12647) 	short		dareg7 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12649) dareg0:	sub.l		%d0,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12650) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12651) dareg1:	sub.l		%d0,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12652) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12653) dareg2:	sub.l		%d0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12654) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12655) dareg3:	sub.l		%d0,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12656) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12657) dareg4:	sub.l		%d0,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12658) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12659) dareg5:	sub.l		%d0,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12660) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12661) dareg6:	sub.l		%d0,(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12662) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12663) dareg7:	mov.b		&mda7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12664) 	cmpi.b		%d0,&0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12665) 	beq.b		dareg7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12666) 	sub.l		%d0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12667) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12668) dareg7b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12669) 	subq.l		&0x2,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12670) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12672) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12674) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12675) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12676) #	load_fpn1(): load FP register value into FP_SRC(a6).		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12677) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12678) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12679) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12680) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12681) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12682) #	d0 = index of FP register to load				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12683) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12684) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12685) #	FP_SRC(a6) = value loaded from FP register file			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12686) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12687) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12688) #	Using the index in d0, load FP_SRC(a6) with a number from the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12689) # FP register file.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12690) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12691) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12693) 	global		load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12694) load_fpn1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12695) 	mov.w		(tbl_load_fpn1.b,%pc,%d0.w*2), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12696) 	jmp		(tbl_load_fpn1.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12698) tbl_load_fpn1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12699) 	short		load_fpn1_0 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12700) 	short		load_fpn1_1 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12701) 	short		load_fpn1_2 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12702) 	short		load_fpn1_3 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12703) 	short		load_fpn1_4 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12704) 	short		load_fpn1_5 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12705) 	short		load_fpn1_6 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12706) 	short		load_fpn1_7 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12708) load_fpn1_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12709) 	mov.l		0+EXC_FP0(%a6), 0+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12710) 	mov.l		4+EXC_FP0(%a6), 4+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12711) 	mov.l		8+EXC_FP0(%a6), 8+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12712) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12713) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12714) load_fpn1_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12715) 	mov.l		0+EXC_FP1(%a6), 0+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12716) 	mov.l		4+EXC_FP1(%a6), 4+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12717) 	mov.l		8+EXC_FP1(%a6), 8+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12718) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12719) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12720) load_fpn1_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12721) 	fmovm.x		&0x20, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12722) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12723) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12724) load_fpn1_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12725) 	fmovm.x		&0x10, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12726) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12727) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12728) load_fpn1_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12729) 	fmovm.x		&0x08, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12730) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12731) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12732) load_fpn1_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12733) 	fmovm.x		&0x04, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12734) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12735) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12736) load_fpn1_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12737) 	fmovm.x		&0x02, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12738) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12739) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12740) load_fpn1_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12741) 	fmovm.x		&0x01, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12742) 	lea		FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12743) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12745) #############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12747) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12748) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12749) #	load_fpn2(): load FP register value into FP_DST(a6).		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12750) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12751) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12752) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12753) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12754) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12755) #	d0 = index of FP register to load				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12756) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12757) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12758) #	FP_DST(a6) = value loaded from FP register file			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12759) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12760) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12761) #	Using the index in d0, load FP_DST(a6) with a number from the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12762) # FP register file.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12763) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12764) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12766) 	global		load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12767) load_fpn2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12768) 	mov.w		(tbl_load_fpn2.b,%pc,%d0.w*2), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12769) 	jmp		(tbl_load_fpn2.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12771) tbl_load_fpn2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12772) 	short		load_fpn2_0 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12773) 	short		load_fpn2_1 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12774) 	short		load_fpn2_2 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12775) 	short		load_fpn2_3 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12776) 	short		load_fpn2_4 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12777) 	short		load_fpn2_5 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12778) 	short		load_fpn2_6 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12779) 	short		load_fpn2_7 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12781) load_fpn2_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12782) 	mov.l		0+EXC_FP0(%a6), 0+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12783) 	mov.l		4+EXC_FP0(%a6), 4+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12784) 	mov.l		8+EXC_FP0(%a6), 8+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12785) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12786) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12787) load_fpn2_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12788) 	mov.l		0+EXC_FP1(%a6), 0+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12789) 	mov.l		4+EXC_FP1(%a6), 4+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12790) 	mov.l		8+EXC_FP1(%a6), 8+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12791) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12792) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12793) load_fpn2_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12794) 	fmovm.x		&0x20, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12795) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12796) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12797) load_fpn2_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12798) 	fmovm.x		&0x10, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12799) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12800) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12801) load_fpn2_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12802) 	fmovm.x		&0x08, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12803) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12804) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12805) load_fpn2_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12806) 	fmovm.x		&0x04, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12807) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12808) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12809) load_fpn2_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12810) 	fmovm.x		&0x02, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12811) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12812) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12813) load_fpn2_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12814) 	fmovm.x		&0x01, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12815) 	lea		FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12816) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12818) #############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12820) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12821) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12822) #	store_fpreg(): store an fp value to the fpreg designated d0.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12823) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12824) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12825) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12826) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12827) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12828) #	fp0 = extended precision value to store				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12829) #	d0  = index of floating-point register				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12830) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12831) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12832) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12833) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12834) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12835) #	Store the value in fp0 to the FP register designated by the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12836) # value in d0. The FP number can be DENORM or SNAN so we have to be	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12837) # careful that we don't take an exception here.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12838) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12839) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12841) 	global		store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12842) store_fpreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12843) 	mov.w		(tbl_store_fpreg.b,%pc,%d0.w*2), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12844) 	jmp		(tbl_store_fpreg.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12846) tbl_store_fpreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12847) 	short		store_fpreg_0 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12848) 	short		store_fpreg_1 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12849) 	short		store_fpreg_2 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12850) 	short		store_fpreg_3 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12851) 	short		store_fpreg_4 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12852) 	short		store_fpreg_5 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12853) 	short		store_fpreg_6 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12854) 	short		store_fpreg_7 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12856) store_fpreg_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12857) 	fmovm.x		&0x80, EXC_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12858) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12859) store_fpreg_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12860) 	fmovm.x		&0x80, EXC_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12861) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12862) store_fpreg_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12863) 	fmovm.x		&0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12864) 	fmovm.x		(%sp)+, &0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12865) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12866) store_fpreg_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12867) 	fmovm.x		&0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12868) 	fmovm.x		(%sp)+, &0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12869) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12870) store_fpreg_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12871) 	fmovm.x		&0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12872) 	fmovm.x		(%sp)+, &0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12873) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12874) store_fpreg_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12875) 	fmovm.x		&0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12876) 	fmovm.x		(%sp)+, &0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12877) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12878) store_fpreg_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12879) 	fmovm.x		&0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12880) 	fmovm.x		(%sp)+, &0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12881) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12882) store_fpreg_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12883) 	fmovm.x		&0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12884) 	fmovm.x		(%sp)+, &0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12885) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12887) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12888) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12889) #	get_packed(): fetch a packed operand from memory and then	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12890) #		      convert it to a floating-point binary number.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12891) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12892) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12893) #	_dcalc_ea() - calculate the correct <ea>			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12894) #	_mem_read() - fetch the packed operand from memory		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12895) #	facc_in_x() - the fetch failed so jump to special exit code	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12896) #	decbin()    - convert packed to binary extended precision	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12897) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12898) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12899) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12900) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12901) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12902) #	If no failure on _mem_read():					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12903) #	FP_SRC(a6) = packed operand now as a binary FP number		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12904) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12905) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12906) #	Get the correct <ea> which is the value on the exception stack	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12907) # frame w/ maybe a correction factor if the <ea> is -(an) or (an)+.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12908) # Then, fetch the operand from memory. If the fetch fails, exit		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12909) # through facc_in_x().							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12910) #	If the packed operand is a ZERO,NAN, or INF, convert it to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12911) # its binary representation here. Else, call decbin() which will	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12912) # convert the packed value to an extended precision binary value.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12913) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12914) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12916) # the stacked <ea> for packed is correct except for -(An).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12917) # the base reg must be updated for both -(An) and (An)+.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12918) 	global		get_packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12919) get_packed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12920) 	mov.l		&0xc,%d0		# packed is 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12921) 	bsr.l		_dcalc_ea		# fetch <ea>; correct An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12923) 	lea		FP_SRC(%a6),%a1		# pass: ptr to super dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12924) 	mov.l		&0xc,%d0		# pass: 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12925) 	bsr.l		_dmem_read		# read packed operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12927) 	tst.l		%d1			# did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12928) 	bne.l		facc_in_x		# yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12930) # The packed operand is an INF or a NAN if the exponent field is all ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12931) 	bfextu		FP_SRC(%a6){&1:&15},%d0	# get exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12932) 	cmpi.w		%d0,&0x7fff		# INF or NAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12933) 	bne.b		gp_try_zero		# no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12934) 	rts					# operand is an INF or NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12936) # The packed operand is a zero if the mantissa is all zero, else it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12937) # a normal packed op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12938) gp_try_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12939) 	mov.b		3+FP_SRC(%a6),%d0	# get byte 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12940) 	andi.b		&0x0f,%d0		# clear all but last nybble
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12941) 	bne.b		gp_not_spec		# not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12942) 	tst.l		FP_SRC_HI(%a6)		# is lw 2 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12943) 	bne.b		gp_not_spec		# not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12944) 	tst.l		FP_SRC_LO(%a6)		# is lw 3 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12945) 	bne.b		gp_not_spec		# not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12946) 	rts					# operand is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12947) gp_not_spec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12948) 	lea		FP_SRC(%a6),%a0		# pass: ptr to packed op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12949) 	bsr.l		decbin			# convert to extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12950) 	fmovm.x		&0x80,FP_SRC(%a6)	# make this the srcop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12951) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12953) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12954) # decbin(): Converts normalized packed bcd value pointed to by register	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12955) #	    a0 to extended-precision value in fp0.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12956) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12957) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12958) #	a0 = pointer to normalized packed bcd value			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12959) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12960) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12961) #	fp0 = exact fp representation of the packed bcd value.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12962) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12963) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12964) #	Expected is a normal bcd (i.e. non-exceptional; all inf, zero,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12965) #	and NaN operands are dispatched without entering this routine)	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12966) #	value in 68881/882 format at location (a0).			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12967) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12968) #	A1. Convert the bcd exponent to binary by successive adds and	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12969) #	muls. Set the sign according to SE. Subtract 16 to compensate	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12970) #	for the mantissa which is to be interpreted as 17 integer	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12971) #	digits, rather than 1 integer and 16 fraction digits.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12972) #	Note: this operation can never overflow.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12973) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12974) #	A2. Convert the bcd mantissa to binary by successive		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12975) #	adds and muls in FP0. Set the sign according to SM.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12976) #	The mantissa digits will be converted with the decimal point	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12977) #	assumed following the least-significant digit.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12978) #	Note: this operation can never overflow.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12979) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12980) #	A3. Count the number of leading/trailing zeros in the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12981) #	bcd string.  If SE is positive, count the leading zeros;	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12982) #	if negative, count the trailing zeros.  Set the adjusted	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12983) #	exponent equal to the exponent from A1 and the zero count	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12984) #	added if SM = 1 and subtracted if SM = 0.  Scale the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12985) #	mantissa the equivalent of forcing in the bcd value:		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12986) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12987) #	SM = 0	a non-zero digit in the integer position		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12988) #	SM = 1	a non-zero digit in Mant0, lsd of the fraction		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12989) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12990) #	this will insure that any value, regardless of its		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12991) #	representation (ex. 0.1E2, 1E1, 10E0, 100E-1), is converted	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12992) #	consistently.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12993) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12994) #	A4. Calculate the factor 10^exp in FP1 using a table of		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12995) #	10^(2^n) values.  To reduce the error in forming factors	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12996) #	greater than 10^27, a directed rounding scheme is used with	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12997) #	tables rounded to RN, RM, and RP, according to the table	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12998) #	in the comments of the pwrten section.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12999) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13000) #	A5. Form the final binary number by scaling the mantissa by	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13001) #	the exponent factor.  This is done by multiplying the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13002) #	mantissa in FP0 by the factor in FP1 if the adjusted		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13003) #	exponent sign is positive, and dividing FP0 by FP1 if		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13004) #	it is negative.							#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13005) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13006) #	Clean up and return. Check if the final mul or div was inexact.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13007) #	If so, set INEX1 in USER_FPSR.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13008) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13009) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13011) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13012) #	PTENRN, PTENRM, and PTENRP are arrays of powers of 10 rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13013) #	to nearest, minus, and plus, respectively.  The tables include
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13014) #	10**{1,2,4,8,16,32,64,128,256,512,1024,2048,4096}.  No rounding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13015) #	is required until the power is greater than 27, however, all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13016) #	tables include the first 5 for ease of indexing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13017) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13018) RTABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13019) 	byte		0,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13020) 	byte		2,3,2,3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13021) 	byte		2,3,3,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13022) 	byte		3,2,2,3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13024) 	set		FNIBS,7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13025) 	set		FSTRT,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13027) 	set		ESTRT,4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13028) 	set		EDIGITS,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13030) 	global		decbin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13031) decbin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13032) 	mov.l		0x0(%a0),FP_SCR0_EX(%a6) # make a copy of input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13033) 	mov.l		0x4(%a0),FP_SCR0_HI(%a6) # so we don't alter it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13034) 	mov.l		0x8(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13036) 	lea		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13038) 	movm.l		&0x3c00,-(%sp)		# save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13039) 	fmovm.x		&0x1,-(%sp)		# save fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13040) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13041) # Calculate exponent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13042) #  1. Copy bcd value in memory for use as a working copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13043) #  2. Calculate absolute value of exponent in d1 by mul and add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13044) #  3. Correct for exponent sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13045) #  4. Subtract 16 to compensate for interpreting the mant as all integer digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13046) #     (i.e., all digits assumed left of the decimal point.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13047) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13048) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13049) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13050) #  calc_e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13051) #	(*)  d0: temp digit storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13052) #	(*)  d1: accumulator for binary exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13053) #	(*)  d2: digit count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13054) #	(*)  d3: offset pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13055) #	( )  d4: first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13056) #	( )  a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13057) #	( )  a6: pointer to original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13058) #	(*)  FP_SCR1: working copy of original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13059) #	(*)  L_SCR1: copy of original exponent word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13060) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13061) calc_e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13062) 	mov.l		&EDIGITS,%d2		# # of nibbles (digits) in fraction part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13063) 	mov.l		&ESTRT,%d3		# counter to pick up digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13064) 	mov.l		(%a0),%d4		# get first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13065) 	clr.l		%d1			# zero d1 for accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13066) e_gd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13067) 	mulu.l		&0xa,%d1		# mul partial product by one digit place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13068) 	bfextu		%d4{%d3:&4},%d0		# get the digit and zero extend into d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13069) 	add.l		%d0,%d1			# d1 = d1 + d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13070) 	addq.b		&4,%d3			# advance d3 to the next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13071) 	dbf.w		%d2,e_gd		# if we have used all 3 digits, exit loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13072) 	btst		&30,%d4			# get SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13073) 	beq.b		e_pos			# don't negate if pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13074) 	neg.l		%d1			# negate before subtracting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13075) e_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13076) 	sub.l		&16,%d1			# sub to compensate for shift of mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13077) 	bge.b		e_save			# if still pos, do not neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13078) 	neg.l		%d1			# now negative, make pos and set SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13079) 	or.l		&0x40000000,%d4		# set SE in d4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13080) 	or.l		&0x40000000,(%a0)	# and in working bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13081) e_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13082) 	mov.l		%d1,-(%sp)		# save exp on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13083) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13084) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13085) # Calculate mantissa:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13086) #  1. Calculate absolute value of mantissa in fp0 by mul and add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13087) #  2. Correct for mantissa sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13088) #     (i.e., all digits assumed left of the decimal point.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13089) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13090) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13091) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13092) #  calc_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13093) #	(*)  d0: temp digit storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13094) #	(*)  d1: lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13095) #	(*)  d2: digit count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13096) #	(*)  d3: offset pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13097) #	( )  d4: words 2 and 3 of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13098) #	( )  a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13099) #	( )  a6: pointer to original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13100) #	(*) fp0: mantissa accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13101) #	( )  FP_SCR1: working copy of original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13102) #	( )  L_SCR1: copy of original exponent word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13103) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13104) calc_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13105) 	mov.l		&1,%d1			# word counter, init to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13106) 	fmov.s		&0x00000000,%fp0	# accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13107) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13108) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13109) #  Since the packed number has a long word between the first & second parts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13110) #  get the integer digit then skip down & get the rest of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13111) #  mantissa.  We will unroll the loop once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13112) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13113) 	bfextu		(%a0){&28:&4},%d0	# integer part is ls digit in long word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13114) 	fadd.b		%d0,%fp0		# add digit to sum in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13115) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13116) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13117) #  Get the rest of the mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13118) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13119) loadlw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13120) 	mov.l		(%a0,%d1.L*4),%d4	# load mantissa lonqword into d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13121) 	mov.l		&FSTRT,%d3		# counter to pick up digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13122) 	mov.l		&FNIBS,%d2		# reset number of digits per a0 ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13123) md2b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13124) 	fmul.s		&0x41200000,%fp0	# fp0 = fp0 * 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13125) 	bfextu		%d4{%d3:&4},%d0		# get the digit and zero extend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13126) 	fadd.b		%d0,%fp0		# fp0 = fp0 + digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13127) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13128) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13129) #  If all the digits (8) in that long word have been converted (d2=0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13130) #  then inc d1 (=2) to point to the next long word and reset d3 to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13131) #  to initialize the digit offset, and set d2 to 7 for the digit count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13132) #  else continue with this long word.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13133) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13134) 	addq.b		&4,%d3			# advance d3 to the next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13135) 	dbf.w		%d2,md2b		# check for last digit in this lw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13136) nextlw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13137) 	addq.l		&1,%d1			# inc lw pointer in mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13138) 	cmp.l		%d1,&2			# test for last lw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13139) 	ble.b		loadlw			# if not, get last one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13140) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13141) #  Check the sign of the mant and make the value in fp0 the same sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13142) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13143) m_sign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13144) 	btst		&31,(%a0)		# test sign of the mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13145) 	beq.b		ap_st_z			# if clear, go to append/strip zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13146) 	fneg.x		%fp0			# if set, negate fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13147) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13148) # Append/strip zeros:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13149) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13150) #  For adjusted exponents which have an absolute value greater than 27*,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13151) #  this routine calculates the amount needed to normalize the mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13152) #  for the adjusted exponent.  That number is subtracted from the exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13153) #  if the exp was positive, and added if it was negative.  The purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13154) #  of this is to reduce the value of the exponent and the possibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13155) #  of error in calculation of pwrten.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13156) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13157) #  1. Branch on the sign of the adjusted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13158) #  2p.(positive exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13159) #   2. Check M16 and the digits in lwords 2 and 3 in descending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13160) #   3. Add one for each zero encountered until a non-zero digit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13161) #   4. Subtract the count from the exp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13162) #   5. Check if the exp has crossed zero in #3 above; make the exp abs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13163) #	   and set SE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13164) #	6. Multiply the mantissa by 10**count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13165) #  2n.(negative exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13166) #   2. Check the digits in lwords 3 and 2 in descending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13167) #   3. Add one for each zero encountered until a non-zero digit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13168) #   4. Add the count to the exp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13169) #   5. Check if the exp has crossed zero in #3 above; clear SE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13170) #   6. Divide the mantissa by 10**count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13171) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13172) #  *Why 27?  If the adjusted exponent is within -28 < expA < 28, than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13173) #   any adjustment due to append/strip zeros will drive the resultane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13174) #   exponent towards zero.  Since all pwrten constants with a power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13175) #   of 27 or less are exact, there is no need to use this routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13176) #   attempt to lessen the resultant exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13177) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13178) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13179) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13180) #  ap_st_z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13181) #	(*)  d0: temp digit storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13182) #	(*)  d1: zero count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13183) #	(*)  d2: digit count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13184) #	(*)  d3: offset pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13185) #	( )  d4: first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13186) #	(*)  d5: lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13187) #	( )  a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13188) #	( )  FP_SCR1: working copy of original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13189) #	( )  L_SCR1: copy of original exponent word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13190) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13191) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13192) # First check the absolute value of the exponent to see if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13193) # routine is necessary.  If so, then check the sign of the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13194) # and do append (+) or strip (-) zeros accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13195) # This section handles a positive adjusted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13196) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13197) ap_st_z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13198) 	mov.l		(%sp),%d1		# load expA for range test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13199) 	cmp.l		%d1,&27			# test is with 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13200) 	ble.w		pwrten			# if abs(expA) <28, skip ap/st zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13201) 	btst		&30,(%a0)		# check sign of exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13202) 	bne.b		ap_st_n			# if neg, go to neg side
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13203) 	clr.l		%d1			# zero count reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13204) 	mov.l		(%a0),%d4		# load lword 1 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13205) 	bfextu		%d4{&28:&4},%d0		# get M16 in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13206) 	bne.b		ap_p_fx			# if M16 is non-zero, go fix exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13207) 	addq.l		&1,%d1			# inc zero count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13208) 	mov.l		&1,%d5			# init lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13209) 	mov.l		(%a0,%d5.L*4),%d4	# get lword 2 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13210) 	bne.b		ap_p_cl			# if lw 2 is zero, skip it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13211) 	addq.l		&8,%d1			# and inc count by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13212) 	addq.l		&1,%d5			# inc lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13213) 	mov.l		(%a0,%d5.L*4),%d4	# get lword 3 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13214) ap_p_cl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13215) 	clr.l		%d3			# init offset reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13216) 	mov.l		&7,%d2			# init digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13217) ap_p_gd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13218) 	bfextu		%d4{%d3:&4},%d0		# get digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13219) 	bne.b		ap_p_fx			# if non-zero, go to fix exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13220) 	addq.l		&4,%d3			# point to next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13221) 	addq.l		&1,%d1			# inc digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13222) 	dbf.w		%d2,ap_p_gd		# get next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13223) ap_p_fx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13224) 	mov.l		%d1,%d0			# copy counter to d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13225) 	mov.l		(%sp),%d1		# get adjusted exp from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13226) 	sub.l		%d0,%d1			# subtract count from exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13227) 	bge.b		ap_p_fm			# if still pos, go to pwrten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13228) 	neg.l		%d1			# now its neg; get abs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13229) 	mov.l		(%a0),%d4		# load lword 1 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13230) 	or.l		&0x40000000,%d4		# and set SE in d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13231) 	or.l		&0x40000000,(%a0)	# and in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13232) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13233) # Calculate the mantissa multiplier to compensate for the striping of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13234) # zeros from the mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13235) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13236) ap_p_fm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13237) 	lea.l		PTENRN(%pc),%a1		# get address of power-of-ten table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13238) 	clr.l		%d3			# init table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13239) 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13240) 	mov.l		&3,%d2			# init d2 to count bits in counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13241) ap_p_el:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13242) 	asr.l		&1,%d0			# shift lsb into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13243) 	bcc.b		ap_p_en			# if 1, mul fp1 by pwrten factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13244) 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13245) ap_p_en:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13246) 	add.l		&12,%d3			# inc d3 to next rtable entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13247) 	tst.l		%d0			# check if d0 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13248) 	bne.b		ap_p_el			# if not, get next bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13249) 	fmul.x		%fp1,%fp0		# mul mantissa by 10**(no_bits_shifted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13250) 	bra.b		pwrten			# go calc pwrten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13251) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13252) # This section handles a negative adjusted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13253) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13254) ap_st_n:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13255) 	clr.l		%d1			# clr counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13256) 	mov.l		&2,%d5			# set up d5 to point to lword 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13257) 	mov.l		(%a0,%d5.L*4),%d4	# get lword 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13258) 	bne.b		ap_n_cl			# if not zero, check digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13259) 	sub.l		&1,%d5			# dec d5 to point to lword 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13260) 	addq.l		&8,%d1			# inc counter by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13261) 	mov.l		(%a0,%d5.L*4),%d4	# get lword 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13262) ap_n_cl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13263) 	mov.l		&28,%d3			# point to last digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13264) 	mov.l		&7,%d2			# init digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13265) ap_n_gd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13266) 	bfextu		%d4{%d3:&4},%d0		# get digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13267) 	bne.b		ap_n_fx			# if non-zero, go to exp fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13268) 	subq.l		&4,%d3			# point to previous digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13269) 	addq.l		&1,%d1			# inc digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13270) 	dbf.w		%d2,ap_n_gd		# get next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13271) ap_n_fx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13272) 	mov.l		%d1,%d0			# copy counter to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13273) 	mov.l		(%sp),%d1		# get adjusted exp from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13274) 	sub.l		%d0,%d1			# subtract count from exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13275) 	bgt.b		ap_n_fm			# if still pos, go fix mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13276) 	neg.l		%d1			# take abs of exp and clr SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13277) 	mov.l		(%a0),%d4		# load lword 1 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13278) 	and.l		&0xbfffffff,%d4		# and clr SE in d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13279) 	and.l		&0xbfffffff,(%a0)	# and in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13280) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13281) # Calculate the mantissa multiplier to compensate for the appending of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13282) # zeros to the mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13283) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13284) ap_n_fm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13285) 	lea.l		PTENRN(%pc),%a1		# get address of power-of-ten table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13286) 	clr.l		%d3			# init table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13287) 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13288) 	mov.l		&3,%d2			# init d2 to count bits in counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13289) ap_n_el:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13290) 	asr.l		&1,%d0			# shift lsb into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13291) 	bcc.b		ap_n_en			# if 1, mul fp1 by pwrten factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13292) 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13293) ap_n_en:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13294) 	add.l		&12,%d3			# inc d3 to next rtable entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13295) 	tst.l		%d0			# check if d0 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13296) 	bne.b		ap_n_el			# if not, get next bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13297) 	fdiv.x		%fp1,%fp0		# div mantissa by 10**(no_bits_shifted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13298) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13299) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13300) # Calculate power-of-ten factor from adjusted and shifted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13301) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13302) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13303) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13304) #  pwrten:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13305) #	(*)  d0: temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13306) #	( )  d1: exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13307) #	(*)  d2: {FPCR[6:5],SM,SE} as index in RTABLE; temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13308) #	(*)  d3: FPCR work copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13309) #	( )  d4: first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13310) #	(*)  a1: RTABLE pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13311) #  calc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13312) #	(*)  d0: temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13313) #	( )  d1: exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13314) #	(*)  d3: PWRTxx table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13315) #	( )  a0: pointer to working copy of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13316) #	(*)  a1: PWRTxx pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13317) #	(*) fp1: power-of-ten accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13318) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13319) # Pwrten calculates the exponent factor in the selected rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13320) # according to the following table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13321) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13322) #	Sign of Mant  Sign of Exp  Rounding Mode  PWRTEN Rounding Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13323) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13324) #	ANY	  ANY	RN	RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13325) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13326) #	 +	   +	RP	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13327) #	 -	   +	RP	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13328) #	 +	   -	RP	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13329) #	 -	   -	RP	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13330) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13331) #	 +	   +	RM	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13332) #	 -	   +	RM	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13333) #	 +	   -	RM	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13334) #	 -	   -	RM	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13335) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13336) #	 +	   +	RZ	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13337) #	 -	   +	RZ	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13338) #	 +	   -	RZ	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13339) #	 -	   -	RZ	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13340) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13341) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13342) pwrten:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13343) 	mov.l		USER_FPCR(%a6),%d3	# get user's FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13344) 	bfextu		%d3{&26:&2},%d2		# isolate rounding mode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13345) 	mov.l		(%a0),%d4		# reload 1st bcd word to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13346) 	asl.l		&2,%d2			# format d2 to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13347) 	bfextu		%d4{&0:&2},%d0		# {FPCR[6],FPCR[5],SM,SE}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13348) 	add.l		%d0,%d2			# in d2 as index into RTABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13349) 	lea.l		RTABLE(%pc),%a1		# load rtable base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13350) 	mov.b		(%a1,%d2),%d0		# load new rounding bits from table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13351) 	clr.l		%d3			# clear d3 to force no exc and extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13352) 	bfins		%d0,%d3{&26:&2}		# stuff new rounding bits in FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13353) 	fmov.l		%d3,%fpcr		# write new FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13354) 	asr.l		&1,%d0			# write correct PTENxx table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13355) 	bcc.b		not_rp			# to a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13356) 	lea.l		PTENRP(%pc),%a1		# it is RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13357) 	bra.b		calc_p			# go to init section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13358) not_rp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13359) 	asr.l		&1,%d0			# keep checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13360) 	bcc.b		not_rm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13361) 	lea.l		PTENRM(%pc),%a1		# it is RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13362) 	bra.b		calc_p			# go to init section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13363) not_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13364) 	lea.l		PTENRN(%pc),%a1		# it is RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13365) calc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13366) 	mov.l		%d1,%d0			# copy exp to d0;use d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13367) 	bpl.b		no_neg			# if exp is negative,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13368) 	neg.l		%d0			# invert it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13369) 	or.l		&0x40000000,(%a0)	# and set SE bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13370) no_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13371) 	clr.l		%d3			# table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13372) 	fmov.s		&0x3f800000,%fp1	# init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13373) e_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13374) 	asr.l		&1,%d0			# shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13375) 	bcc.b		e_next			# if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13376) 	fmul.x		(%a1,%d3),%fp1		# mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13377) e_next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13378) 	add.l		&12,%d3			# inc d3 to next rtable entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13379) 	tst.l		%d0			# check if d0 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13380) 	bne.b		e_loop			# not zero, continue shifting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13381) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13382) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13383) #  Check the sign of the adjusted exp and make the value in fp0 the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13384) #  same sign. If the exp was pos then multiply fp1*fp0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13385) #  else divide fp0/fp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13386) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13387) # Register Usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13388) #  norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13389) #	( )  a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13390) #	(*) fp0: mantissa accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13391) #	( ) fp1: scaling factor - 10**(abs(exp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13392) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13393) pnorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13394) 	btst		&30,(%a0)		# test the sign of the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13395) 	beq.b		mul			# if clear, go to multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13396) div:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13397) 	fdiv.x		%fp1,%fp0		# exp is negative, so divide mant by exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13398) 	bra.b		end_dec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13399) mul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13400) 	fmul.x		%fp1,%fp0		# exp is positive, so multiply by exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13401) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13402) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13403) # Clean up and return with result in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13404) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13405) # If the final mul/div in decbin incurred an inex exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13406) # it will be inex2, but will be reported as inex1 by get_op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13407) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13408) end_dec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13409) 	fmov.l		%fpsr,%d0		# get status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13410) 	bclr		&inex2_bit+8,%d0	# test for inex2 and clear it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13411) 	beq.b		no_exc			# skip this if no exc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13412) 	ori.w		&inx1a_mask,2+USER_FPSR(%a6) # set INEX1/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13413) no_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13414) 	add.l		&0x4,%sp		# clear 1 lw param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13415) 	fmovm.x		(%sp)+,&0x40		# restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13416) 	movm.l		(%sp)+,&0x3c		# restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13417) 	fmov.l		&0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13418) 	fmov.l		&0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13419) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13421) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13422) # bindec(): Converts an input in extended precision format to bcd format#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13423) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13424) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13425) #	a0 = pointer to the input extended precision value in memory.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13426) #	     the input may be either normalized, unnormalized, or	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13427) #	     denormalized.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13428) #	d0 = contains the k-factor sign-extended to 32-bits.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13429) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13430) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13431) #	FP_SCR0(a6) = bcd format result on the stack.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13432) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13433) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13434) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13435) #	A1.	Set RM and size ext;  Set SIGMA = sign of input.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13436) #		The k-factor is saved for use in d7. Clear the		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13437) #		BINDEC_FLG for separating normalized/denormalized	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13438) #		input.  If input is unnormalized or denormalized,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13439) #		normalize it.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13440) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13441) #	A2.	Set X = abs(input).					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13442) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13443) #	A3.	Compute ILOG.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13444) #		ILOG is the log base 10 of the input value.  It is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13445) #		approximated by adding e + 0.f when the original	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13446) #		value is viewed as 2^^e * 1.f in extended precision.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13447) #		This value is stored in d6.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13448) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13449) #	A4.	Clr INEX bit.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13450) #		The operation in A3 above may have set INEX2.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13451) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13452) #	A5.	Set ICTR = 0;						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13453) #		ICTR is a flag used in A13.  It must be set before the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13454) #		loop entry A6.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13455) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13456) #	A6.	Calculate LEN.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13457) #		LEN is the number of digits to be displayed.  The	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13458) #		k-factor can dictate either the total number of digits,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13459) #		if it is a positive number, or the number of digits	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13460) #		after the decimal point which are to be included as	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13461) #		significant.  See the 68882 manual for examples.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13462) #		If LEN is computed to be greater than 17, set OPERR in	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13463) #		USER_FPSR.  LEN is stored in d4.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13464) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13465) #	A7.	Calculate SCALE.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13466) #		SCALE is equal to 10^ISCALE, where ISCALE is the number	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13467) #		of decimal places needed to insure LEN integer digits	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13468) #		in the output before conversion to bcd. LAMBDA is the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13469) #		sign of ISCALE, used in A9. Fp1 contains		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13470) #		10^^(abs(ISCALE)) using a rounding mode which is a	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13471) #		function of the original rounding mode and the signs	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13472) #		of ISCALE and X.  A table is given in the code.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13473) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13474) #	A8.	Clr INEX; Force RZ.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13475) #		The operation in A3 above may have set INEX2.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13476) #		RZ mode is forced for the scaling operation to insure	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13477) #		only one rounding error.  The grs bits are collected in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13478) #		the INEX flag for use in A10.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13479) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13480) #	A9.	Scale X -> Y.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13481) #		The mantissa is scaled to the desired number of		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13482) #		significant digits.  The excess digits are collected	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13483) #		in INEX2.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13484) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13485) #	A10.	Or in INEX.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13486) #		If INEX is set, round error occurred.  This is		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13487) #		compensated for by 'or-ing' in the INEX2 flag to	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13488) #		the lsb of Y.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13489) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13490) #	A11.	Restore original FPCR; set size ext.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13491) #		Perform FINT operation in the user's rounding mode.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13492) #		Keep the size to extended.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13493) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13494) #	A12.	Calculate YINT = FINT(Y) according to user's rounding	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13495) #		mode.  The FPSP routine sintd0 is used.  The output	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13496) #		is in fp0.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13497) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13498) #	A13.	Check for LEN digits.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13499) #		If the int operation results in more than LEN digits,	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13500) #		or less than LEN -1 digits, adjust ILOG and repeat from	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13501) #		A6.  This test occurs only on the first pass.  If the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13502) #		result is exactly 10^LEN, decrement ILOG and divide	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13503) #		the mantissa by 10.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13504) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13505) #	A14.	Convert the mantissa to bcd.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13506) #		The binstr routine is used to convert the LEN digit	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13507) #		mantissa to bcd in memory.  The input to binstr is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13508) #		to be a fraction; i.e. (mantissa)/10^LEN and adjusted	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13509) #		such that the decimal point is to the left of bit 63.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13510) #		The bcd digits are stored in the correct position in	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13511) #		the final string area in memory.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13512) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13513) #	A15.	Convert the exponent to bcd.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13514) #		As in A14 above, the exp is converted to bcd and the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13515) #		digits are stored in the final string.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13516) #		Test the length of the final exponent string.  If the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13517) #		length is 4, set operr.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13518) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13519) #	A16.	Write sign bits to final string.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13520) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13521) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13523) set	BINDEC_FLG,	EXC_TEMP	# DENORM flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13525) # Constants in extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13526) PLOG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13527) 	long		0x3FFD0000,0x9A209A84,0xFBCFF798,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13528) PLOG2UP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13529) 	long		0x3FFD0000,0x9A209A84,0xFBCFF799,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13531) # Constants in single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13532) FONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13533) 	long		0x3F800000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13534) FTWO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13535) 	long		0x40000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13536) FTEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13537) 	long		0x41200000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13538) F4933:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13539) 	long		0x459A2800,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13541) RBDTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13542) 	byte		0,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13543) 	byte		3,3,2,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13544) 	byte		3,2,2,3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13545) 	byte		2,3,3,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13547) #	Implementation Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13548) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13549) #	The registers are used as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13550) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13551) #		d0: scratch; LEN input to binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13552) #		d1: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13553) #		d2: upper 32-bits of mantissa for binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13554) #		d3: scratch;lower 32-bits of mantissa for binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13555) #		d4: LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13556) #		d5: LAMBDA/ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13557) #		d6: ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13558) #		d7: k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13559) #		a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13560) #		a1: scratch pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13561) #		a2: pointer to FP_X; abs(original value) in ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13562) #		fp0: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13563) #		fp1: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13564) #		fp2: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13565) #		F_SCR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13566) #		F_SCR2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13567) #		L_SCR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13568) #		L_SCR2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13570) 	global		bindec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13571) bindec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13572) 	movm.l		&0x3f20,-(%sp)	#  {%d2-%d7/%a2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13573) 	fmovm.x		&0x7,-(%sp)	#  {%fp0-%fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13575) # A1. Set RM and size ext. Set SIGMA = sign input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13576) #     The k-factor is saved for use in d7.  Clear BINDEC_FLG for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13577) #     separating  normalized/denormalized input.  If the input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13578) #     is a denormalized number, set the BINDEC_FLG memory word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13579) #     to signal denorm.  If the input is unnormalized, normalize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13580) #     the input and test for denormalized result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13581) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13582) 	fmov.l		&rm_mode*0x10,%fpcr	# set RM and ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13583) 	mov.l		(%a0),L_SCR2(%a6)	# save exponent for sign check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13584) 	mov.l		%d0,%d7		# move k-factor to d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13586) 	clr.b		BINDEC_FLG(%a6)	# clr norm/denorm flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13587) 	cmpi.b		STAG(%a6),&DENORM # is input a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13588) 	bne.w		A2_str		# no; input is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13590) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13591) # Normalize the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13592) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13593) un_de_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13594) 	mov.w		(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13595) 	and.w		&0x7fff,%d0	# strip sign of normalized exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13596) 	mov.l		4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13597) 	mov.l		8(%a0),%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13598) norm_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13599) 	sub.w		&1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13600) 	lsl.l		&1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13601) 	roxl.l		&1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13602) 	tst.l		%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13603) 	bge.b		norm_loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13604) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13605) # Test if the normalized input is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13606) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13607) 	tst.w		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13608) 	bgt.b		pos_exp		# if greater than zero, it is a norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13609) 	st		BINDEC_FLG(%a6)	# set flag for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13610) pos_exp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13611) 	and.w		&0x7fff,%d0	# strip sign of normalized exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13612) 	mov.w		%d0,(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13613) 	mov.l		%d1,4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13614) 	mov.l		%d2,8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13616) # A2. Set X = abs(input).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13617) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13618) A2_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13619) 	mov.l		(%a0),FP_SCR1(%a6)	# move input to work space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13620) 	mov.l		4(%a0),FP_SCR1+4(%a6)	# move input to work space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13621) 	mov.l		8(%a0),FP_SCR1+8(%a6)	# move input to work space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13622) 	and.l		&0x7fffffff,FP_SCR1(%a6)	# create abs(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13624) # A3. Compute ILOG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13625) #     ILOG is the log base 10 of the input value.  It is approx-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13626) #     imated by adding e + 0.f when the original value is viewed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13627) #     as 2^^e * 1.f in extended precision.  This value is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13628) #     in d6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13629) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13630) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13631) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13632) #	d0: k-factor/exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13633) #	d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13634) #	d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13635) #	d4: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13636) #	d5: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13637) #	d6: x/ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13638) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13639) #	a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13640) #	a1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13641) #	a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13642) #	fp0: x/float(ILOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13643) #	fp1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13644) #	fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13645) #	F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13646) #	F_SCR2:Abs(X)/Abs(X) with $3fff exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13647) #	L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13648) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13650) 	tst.b		BINDEC_FLG(%a6)	# check for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13651) 	beq.b		A3_cont		# if clr, continue with norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13652) 	mov.l		&-4933,%d6	# force ILOG = -4933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13653) 	bra.b		A4_str
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13654) A3_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13655) 	mov.w		FP_SCR1(%a6),%d0	# move exp to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13656) 	mov.w		&0x3fff,FP_SCR1(%a6)	# replace exponent with 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13657) 	fmov.x		FP_SCR1(%a6),%fp0	# now fp0 has 1.f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13658) 	sub.w		&0x3fff,%d0	# strip off bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13659) 	fadd.w		%d0,%fp0	# add in exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13660) 	fsub.s		FONE(%pc),%fp0	# subtract off 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13661) 	fbge.w		pos_res		# if pos, branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13662) 	fmul.x		PLOG2UP1(%pc),%fp0	# if neg, mul by LOG2UP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13663) 	fmov.l		%fp0,%d6	# put ILOG in d6 as a lword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13664) 	bra.b		A4_str		# go move out ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13665) pos_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13666) 	fmul.x		PLOG2(%pc),%fp0	# if pos, mul by LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13667) 	fmov.l		%fp0,%d6	# put ILOG in d6 as a lword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13670) # A4. Clr INEX bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13671) #     The operation in A3 above may have set INEX2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13673) A4_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13674) 	fmov.l		&0,%fpsr	# zero all of fpsr - nothing needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13677) # A5. Set ICTR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13678) #     ICTR is a flag used in A13.  It must be set before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13679) #     loop entry A6. The lower word of d5 is used for ICTR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13681) 	clr.w		%d5		# clear ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13683) # A6. Calculate LEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13684) #     LEN is the number of digits to be displayed.  The k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13685) #     can dictate either the total number of digits, if it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13686) #     a positive number, or the number of digits after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13687) #     original decimal point which are to be included as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13688) #     significant.  See the 68882 manual for examples.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13689) #     If LEN is computed to be greater than 17, set OPERR in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13690) #     USER_FPSR.  LEN is stored in d4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13691) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13692) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13693) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13694) #	d0: exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13695) #	d2: x/x/scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13696) #	d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13697) #	d4: exc picture/LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13698) #	d5: ICTR/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13699) #	d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13700) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13701) #	a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13702) #	a1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13703) #	a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13704) #	fp0: float(ILOG)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13705) #	fp1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13706) #	fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13707) #	F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13708) #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13709) #	L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13710) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13712) A6_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13713) 	tst.l		%d7		# branch on sign of k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13714) 	ble.b		k_neg		# if k <= 0, LEN = ILOG + 1 - k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13715) 	mov.l		%d7,%d4		# if k > 0, LEN = k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13716) 	bra.b		len_ck		# skip to LEN check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13717) k_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13718) 	mov.l		%d6,%d4		# first load ILOG to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13719) 	sub.l		%d7,%d4		# subtract off k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13720) 	addq.l		&1,%d4		# add in the 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13721) len_ck:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13722) 	tst.l		%d4		# LEN check: branch on sign of LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13723) 	ble.b		LEN_ng		# if neg, set LEN = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13724) 	cmp.l		%d4,&17		# test if LEN > 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13725) 	ble.b		A7_str		# if not, forget it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13726) 	mov.l		&17,%d4		# set max LEN = 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13727) 	tst.l		%d7		# if negative, never set OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13728) 	ble.b		A7_str		# if positive, continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13729) 	or.l		&opaop_mask,USER_FPSR(%a6)	# set OPERR & AIOP in USER_FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13730) 	bra.b		A7_str		# finished here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13731) LEN_ng:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13732) 	mov.l		&1,%d4		# min LEN is 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13735) # A7. Calculate SCALE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13736) #     SCALE is equal to 10^ISCALE, where ISCALE is the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13737) #     of decimal places needed to insure LEN integer digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13738) #     in the output before conversion to bcd. LAMBDA is the sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13739) #     of ISCALE, used in A9.  Fp1 contains 10^^(abs(ISCALE)) using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13740) #     the rounding mode as given in the following table (see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13741) #     Coonen, p. 7.23 as ref.; however, the SCALE variable is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13742) #     of opposite sign in bindec.sa from Coonen).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13743) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13744) #	Initial					USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13745) #	FPCR[6:5]	LAMBDA	SIGN(X)		FPCR[6:5]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13746) #	----------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13747) #	 RN	00	   0	   0		00/0	RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13748) #	 RN	00	   0	   1		00/0	RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13749) #	 RN	00	   1	   0		00/0	RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13750) #	 RN	00	   1	   1		00/0	RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13751) #	 RZ	01	   0	   0		11/3	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13752) #	 RZ	01	   0	   1		11/3	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13753) #	 RZ	01	   1	   0		10/2	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13754) #	 RZ	01	   1	   1		10/2	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13755) #	 RM	10	   0	   0		11/3	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13756) #	 RM	10	   0	   1		10/2	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13757) #	 RM	10	   1	   0		10/2	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13758) #	 RM	10	   1	   1		11/3	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13759) #	 RP	11	   0	   0		10/2	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13760) #	 RP	11	   0	   1		11/3	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13761) #	 RP	11	   1	   0		11/3	RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13762) #	 RP	11	   1	   1		10/2	RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13763) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13764) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13765) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13766) #	d0: exponent/scratch - final is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13767) #	d2: x/0 or 24 for A9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13768) #	d3: x/scratch - offset ptr into PTENRM array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13769) #	d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13770) #	d5: 0/ICTR:LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13771) #	d6: ILOG/ILOG or k if ((k<=0)&(ILOG<k))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13772) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13773) #	a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13774) #	a1: x/ptr to PTENRM array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13775) #	a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13776) #	fp0: float(ILOG)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13777) #	fp1: x/10^ISCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13778) #	fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13779) #	F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13780) #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13781) #	L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13782) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13784) A7_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13785) 	tst.l		%d7		# test sign of k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13786) 	bgt.b		k_pos		# if pos and > 0, skip this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13787) 	cmp.l		%d7,%d6		# test k - ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13788) 	blt.b		k_pos		# if ILOG >= k, skip this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13789) 	mov.l		%d7,%d6		# if ((k<0) & (ILOG < k)) ILOG = k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13790) k_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13791) 	mov.l		%d6,%d0		# calc ILOG + 1 - LEN in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13792) 	addq.l		&1,%d0		# add the 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13793) 	sub.l		%d4,%d0		# sub off LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13794) 	swap		%d5		# use upper word of d5 for LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13795) 	clr.w		%d5		# set it zero initially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13796) 	clr.w		%d2		# set up d2 for very small case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13797) 	tst.l		%d0		# test sign of ISCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13798) 	bge.b		iscale		# if pos, skip next inst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13799) 	addq.w		&1,%d5		# if neg, set LAMBDA true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13800) 	cmp.l		%d0,&0xffffecd4	# test iscale <= -4908
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13801) 	bgt.b		no_inf		# if false, skip rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13802) 	add.l		&24,%d0		# add in 24 to iscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13803) 	mov.l		&24,%d2		# put 24 in d2 for A9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13804) no_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13805) 	neg.l		%d0		# and take abs of ISCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13806) iscale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13807) 	fmov.s		FONE(%pc),%fp1	# init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13808) 	bfextu		USER_FPCR(%a6){&26:&2},%d1	# get initial rmode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13809) 	lsl.w		&1,%d1		# put them in bits 2:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13810) 	add.w		%d5,%d1		# add in LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13811) 	lsl.w		&1,%d1		# put them in bits 3:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13812) 	tst.l		L_SCR2(%a6)	# test sign of original x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13813) 	bge.b		x_pos		# if pos, don't set bit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13814) 	addq.l		&1,%d1		# if neg, set bit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13815) x_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13816) 	lea.l		RBDTBL(%pc),%a2	# load rbdtbl base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13817) 	mov.b		(%a2,%d1),%d3	# load d3 with new rmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13818) 	lsl.l		&4,%d3		# put bits in proper position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13819) 	fmov.l		%d3,%fpcr	# load bits into fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13820) 	lsr.l		&4,%d3		# put bits in proper position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13821) 	tst.b		%d3		# decode new rmode for pten table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13822) 	bne.b		not_rn		# if zero, it is RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13823) 	lea.l		PTENRN(%pc),%a1	# load a1 with RN table base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13824) 	bra.b		rmode		# exit decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13825) not_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13826) 	lsr.b		&1,%d3		# get lsb in carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13827) 	bcc.b		not_rp2		# if carry clear, it is RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13828) 	lea.l		PTENRP(%pc),%a1	# load a1 with RP table base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13829) 	bra.b		rmode		# exit decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13830) not_rp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13831) 	lea.l		PTENRM(%pc),%a1	# load a1 with RM table base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13832) rmode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13833) 	clr.l		%d3		# clr table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13834) e_loop2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13835) 	lsr.l		&1,%d0		# shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13836) 	bcc.b		e_next2		# if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13837) 	fmul.x		(%a1,%d3),%fp1	# mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13838) e_next2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13839) 	add.l		&12,%d3		# inc d3 to next pwrten table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13840) 	tst.l		%d0		# test if ISCALE is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13841) 	bne.b		e_loop2		# if not, loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13843) # A8. Clr INEX; Force RZ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13844) #     The operation in A3 above may have set INEX2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13845) #     RZ mode is forced for the scaling operation to insure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13846) #     only one rounding error.  The grs bits are collected in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13847) #     the INEX flag for use in A10.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13848) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13849) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13850) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13852) 	fmov.l		&0,%fpsr	# clr INEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13853) 	fmov.l		&rz_mode*0x10,%fpcr	# set RZ rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13855) # A9. Scale X -> Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13856) #     The mantissa is scaled to the desired number of significant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13857) #     digits.  The excess digits are collected in INEX2. If mul,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13858) #     Check d2 for excess 10 exponential value.  If not zero,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13859) #     the iscale value would have caused the pwrten calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13860) #     to overflow.  Only a negative iscale can cause this, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13861) #     multiply by 10^(d2), which is now only allowed to be 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13862) #     with a multiply by 10^8 and 10^16, which is exact since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13863) #     10^24 is exact.  If the input was denormalized, we must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13864) #     create a busy stack frame with the mul command and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13865) #     two operands, and allow the fpu to complete the multiply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13866) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13867) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13868) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13869) #	d0: FPCR with RZ mode/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13870) #	d2: 0 or 24/unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13871) #	d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13872) #	d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13873) #	d5: ICTR:LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13874) #	d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13875) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13876) #	a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13877) #	a1: ptr to PTENRM array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13878) #	a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13879) #	fp0: float(ILOG)/X adjusted for SCALE (Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13880) #	fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13881) #	fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13882) #	F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13883) #	F_SCR2:Abs(X) with $3fff exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13884) #	L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13885) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13887) A9_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13888) 	fmov.x		(%a0),%fp0	# load X from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13889) 	fabs.x		%fp0		# use abs(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13890) 	tst.w		%d5		# LAMBDA is in lower word of d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13891) 	bne.b		sc_mul		# if neg (LAMBDA = 1), scale by mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13892) 	fdiv.x		%fp1,%fp0	# calculate X / SCALE -> Y to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13893) 	bra.w		A10_st		# branch to A10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13895) sc_mul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13896) 	tst.b		BINDEC_FLG(%a6)	# check for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13897) 	beq.w		A9_norm		# if norm, continue with mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13899) # for DENORM, we must calculate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13900) #	fp0 = input_op * 10^ISCALE * 10^24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13901) # since the input operand is a DENORM, we can't multiply it directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13902) # so, we do the multiplication of the exponents and mantissas separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13903) # in this way, we avoid underflow on intermediate stages of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13904) # multiplication and guarantee a result without exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13905) 	fmovm.x		&0x2,-(%sp)	# save 10^ISCALE to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13907) 	mov.w		(%sp),%d3	# grab exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13908) 	andi.w		&0x7fff,%d3	# clear sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13909) 	ori.w		&0x8000,(%a0)	# make DENORM exp negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13910) 	add.w		(%a0),%d3	# add DENORM exp to 10^ISCALE exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13911) 	subi.w		&0x3fff,%d3	# subtract BIAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13912) 	add.w		36(%a1),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13913) 	subi.w		&0x3fff,%d3	# subtract BIAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13914) 	add.w		48(%a1),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13915) 	subi.w		&0x3fff,%d3	# subtract BIAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13917) 	bmi.w		sc_mul_err	# is result is DENORM, punt!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13919) 	andi.w		&0x8000,(%sp)	# keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13920) 	or.w		%d3,(%sp)	# insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13921) 	andi.w		&0x7fff,(%a0)	# clear sign bit on DENORM again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13922) 	mov.l		0x8(%a0),-(%sp) # put input op mantissa on stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13923) 	mov.l		0x4(%a0),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13924) 	mov.l		&0x3fff0000,-(%sp) # force exp to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13925) 	fmovm.x		(%sp)+,&0x80	# load normalized DENORM into fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13926) 	fmul.x		(%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13928) #	fmul.x	36(%a1),%fp0	# multiply fp0 by 10^8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13929) #	fmul.x	48(%a1),%fp0	# multiply fp0 by 10^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13930) 	mov.l		36+8(%a1),-(%sp) # get 10^8 mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13931) 	mov.l		36+4(%a1),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13932) 	mov.l		&0x3fff0000,-(%sp) # force exp to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13933) 	mov.l		48+8(%a1),-(%sp) # get 10^16 mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13934) 	mov.l		48+4(%a1),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13935) 	mov.l		&0x3fff0000,-(%sp)# force exp to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13936) 	fmul.x		(%sp)+,%fp0	# multiply fp0 by 10^8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13937) 	fmul.x		(%sp)+,%fp0	# multiply fp0 by 10^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13938) 	bra.b		A10_st
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13940) sc_mul_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13941) 	bra.b		sc_mul_err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13943) A9_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13944) 	tst.w		%d2		# test for small exp case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13945) 	beq.b		A9_con		# if zero, continue as normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13946) 	fmul.x		36(%a1),%fp0	# multiply fp0 by 10^8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13947) 	fmul.x		48(%a1),%fp0	# multiply fp0 by 10^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13948) A9_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13949) 	fmul.x		%fp1,%fp0	# calculate X * SCALE -> Y to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13951) # A10. Or in INEX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13952) #      If INEX is set, round error occurred.  This is compensated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13953) #      for by 'or-ing' in the INEX2 flag to the lsb of Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13954) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13955) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13956) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13957) #	d0: FPCR with RZ mode/FPSR with INEX2 isolated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13958) #	d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13959) #	d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13960) #	d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13961) #	d5: ICTR:LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13962) #	d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13963) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13964) #	a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13965) #	a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13966) #	a2: x/ptr to FP_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13967) #	fp0: Y/Y with lsb adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13968) #	fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13969) #	fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13971) A10_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13972) 	fmov.l		%fpsr,%d0	# get FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13973) 	fmov.x		%fp0,FP_SCR1(%a6)	# move Y to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13974) 	lea.l		FP_SCR1(%a6),%a2	# load a2 with ptr to FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13975) 	btst		&9,%d0		# check if INEX2 set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13976) 	beq.b		A11_st		# if clear, skip rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13977) 	or.l		&1,8(%a2)	# or in 1 to lsb of mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13978) 	fmov.x		FP_SCR1(%a6),%fp0	# write adjusted Y back to fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13981) # A11. Restore original FPCR; set size ext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13982) #      Perform FINT operation in the user's rounding mode.  Keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13983) #      the size to extended.  The sintdo entry point in the sint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13984) #      routine expects the FPCR value to be in USER_FPCR for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13985) #      mode and precision.  The original FPCR is saved in L_SCR1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13987) A11_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13988) 	mov.l		USER_FPCR(%a6),L_SCR1(%a6)	# save it for later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13989) 	and.l		&0x00000030,USER_FPCR(%a6)	# set size to ext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13990) #					;block exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13993) # A12. Calculate YINT = FINT(Y) according to user's rounding mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13994) #      The FPSP routine sintd0 is used.  The output is in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13995) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13996) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13997) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13998) #	d0: FPSR with AINEX cleared/FPCR with size set to ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13999) #	d2: x/x/scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14000) #	d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14001) #	d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14002) #	d5: ICTR:LAMBDA/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14003) #	d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14004) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14005) #	a0: ptr for original operand/src ptr for sintdo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14006) #	a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14007) #	a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14008) #	a6: temp pointer to FP_SCR1(a6) - orig value saved and restored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14009) #	fp0: Y/YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14010) #	fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14011) #	fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14012) #	F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14013) #	F_SCR2:Y adjusted for inex/Y with original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14014) #	L_SCR1:x/original USER_FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14015) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14017) A12_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14018) 	movm.l	&0xc0c0,-(%sp)	# save regs used by sintd0	 {%d0-%d1/%a0-%a1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14019) 	mov.l	L_SCR1(%a6),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14020) 	mov.l	L_SCR2(%a6),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14022) 	lea.l		FP_SCR1(%a6),%a0	# a0 is ptr to FP_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14023) 	fmov.x		%fp0,(%a0)	# move Y to memory at FP_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14024) 	tst.l		L_SCR2(%a6)	# test sign of original operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14025) 	bge.b		do_fint12		# if pos, use Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14026) 	or.l		&0x80000000,(%a0)	# if neg, use -Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14027) do_fint12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14028) 	mov.l	USER_FPSR(%a6),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14029) #	bsr	sintdo		# sint routine returns int in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14031) 	fmov.l	USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14032) 	fmov.l	&0x0,%fpsr			# clear the AEXC bits!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14033) ##	mov.l		USER_FPCR(%a6),%d0	# ext prec/keep rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14034) ##	andi.l		&0x00000030,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14035) ##	fmov.l		%d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14036) 	fint.x		FP_SCR1(%a6),%fp0	# do fint()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14037) 	fmov.l	%fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14038) 	or.w	%d0,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14039) ##	fmov.l		&0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14040) ##	fmov.l		%fpsr,%d0		# don't keep ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14041) ##	or.w		%d0,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14043) 	mov.b	(%sp),USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14044) 	add.l	&4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14046) 	mov.l	(%sp)+,L_SCR2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14047) 	mov.l	(%sp)+,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14048) 	movm.l	(%sp)+,&0x303	# restore regs used by sint	 {%d0-%d1/%a0-%a1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14050) 	mov.l	L_SCR2(%a6),FP_SCR1(%a6)	# restore original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14051) 	mov.l	L_SCR1(%a6),USER_FPCR(%a6)	# restore user's FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14053) # A13. Check for LEN digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14054) #      If the int operation results in more than LEN digits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14055) #      or less than LEN -1 digits, adjust ILOG and repeat from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14056) #      A6.  This test occurs only on the first pass.  If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14057) #      result is exactly 10^LEN, decrement ILOG and divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14058) #      the mantissa by 10.  The calculation of 10^LEN cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14059) #      be inexact, since all powers of ten up to 10^27 are exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14060) #      in extended precision, so the use of a previous power-of-ten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14061) #      table will introduce no error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14062) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14063) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14064) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14065) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14066) #	d0: FPCR with size set to ext/scratch final = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14067) #	d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14068) #	d3: x/scratch final = x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14069) #	d4: LEN/LEN adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14070) #	d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14071) #	d6: ILOG/ILOG adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14072) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14073) #	a0: pointer into memory for packed bcd string formation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14074) #	a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14075) #	a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14076) #	fp0: int portion of Y/abs(YINT) adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14077) #	fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14078) #	fp2: x/10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14079) #	F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14080) #	F_SCR2:Y with original exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14081) #	L_SCR1:original USER_FPCR/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14082) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14084) A13_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14085) 	swap		%d5		# put ICTR in lower word of d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14086) 	tst.w		%d5		# check if ICTR = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14087) 	bne		not_zr		# if non-zero, go to second test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14088) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14089) # Compute 10^(LEN-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14090) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14091) 	fmov.s		FONE(%pc),%fp2	# init fp2 to 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14092) 	mov.l		%d4,%d0		# put LEN in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14093) 	subq.l		&1,%d0		# d0 = LEN -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14094) 	clr.l		%d3		# clr table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14095) l_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14096) 	lsr.l		&1,%d0		# shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14097) 	bcc.b		l_next		# if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14098) 	fmul.x		(%a1,%d3),%fp2	# mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14099) l_next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14100) 	add.l		&12,%d3		# inc d3 to next pwrten table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14101) 	tst.l		%d0		# test if LEN is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14102) 	bne.b		l_loop		# if not, loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14103) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14104) # 10^LEN-1 is computed for this test and A14.  If the input was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14105) # denormalized, check only the case in which YINT > 10^LEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14106) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14107) 	tst.b		BINDEC_FLG(%a6)	# check if input was norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14108) 	beq.b		A13_con		# if norm, continue with checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14109) 	fabs.x		%fp0		# take abs of YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14110) 	bra		test_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14111) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14112) # Compare abs(YINT) to 10^(LEN-1) and 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14113) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14114) A13_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14115) 	fabs.x		%fp0		# take abs of YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14116) 	fcmp.x		%fp0,%fp2	# compare abs(YINT) with 10^(LEN-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14117) 	fbge.w		test_2		# if greater, do next test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14118) 	subq.l		&1,%d6		# subtract 1 from ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14119) 	mov.w		&1,%d5		# set ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14120) 	fmov.l		&rm_mode*0x10,%fpcr	# set rmode to RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14121) 	fmul.s		FTEN(%pc),%fp2	# compute 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14122) 	bra.w		A6_str		# return to A6 and recompute YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14123) test_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14124) 	fmul.s		FTEN(%pc),%fp2	# compute 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14125) 	fcmp.x		%fp0,%fp2	# compare abs(YINT) with 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14126) 	fblt.w		A14_st		# if less, all is ok, go to A14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14127) 	fbgt.w		fix_ex		# if greater, fix and redo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14128) 	fdiv.s		FTEN(%pc),%fp0	# if equal, divide by 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14129) 	addq.l		&1,%d6		# and inc ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14130) 	bra.b		A14_st		# and continue elsewhere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14131) fix_ex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14132) 	addq.l		&1,%d6		# increment ILOG by 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14133) 	mov.w		&1,%d5		# set ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14134) 	fmov.l		&rm_mode*0x10,%fpcr	# set rmode to RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14135) 	bra.w		A6_str		# return to A6 and recompute YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14136) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14137) # Since ICTR <> 0, we have already been through one adjustment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14138) # and shouldn't have another; this is to check if abs(YINT) = 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14139) # 10^LEN is again computed using whatever table is in a1 since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14140) # value calculated cannot be inexact.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14141) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14142) not_zr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14143) 	fmov.s		FONE(%pc),%fp2	# init fp2 to 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14144) 	mov.l		%d4,%d0		# put LEN in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14145) 	clr.l		%d3		# clr table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14146) z_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14147) 	lsr.l		&1,%d0		# shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14148) 	bcc.b		z_next		# if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14149) 	fmul.x		(%a1,%d3),%fp2	# mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14150) z_next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14151) 	add.l		&12,%d3		# inc d3 to next pwrten table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14152) 	tst.l		%d0		# test if LEN is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14153) 	bne.b		z_loop		# if not, loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14154) 	fabs.x		%fp0		# get abs(YINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14155) 	fcmp.x		%fp0,%fp2	# check if abs(YINT) = 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14156) 	fbneq.w		A14_st		# if not, skip this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14157) 	fdiv.s		FTEN(%pc),%fp0	# divide abs(YINT) by 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14158) 	addq.l		&1,%d6		# and inc ILOG by 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14159) 	addq.l		&1,%d4		# and inc LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14160) 	fmul.s		FTEN(%pc),%fp2	# if LEN++, the get 10^^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14162) # A14. Convert the mantissa to bcd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14163) #      The binstr routine is used to convert the LEN digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14164) #      mantissa to bcd in memory.  The input to binstr is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14165) #      to be a fraction; i.e. (mantissa)/10^LEN and adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14166) #      such that the decimal point is to the left of bit 63.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14167) #      The bcd digits are stored in the correct position in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14168) #      the final string area in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14169) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14170) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14171) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14172) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14173) #	d0: x/LEN call to binstr - final is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14174) #	d1: x/0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14175) #	d2: x/ms 32-bits of mant of abs(YINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14176) #	d3: x/ls 32-bits of mant of abs(YINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14177) #	d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14178) #	d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14179) #	d6: ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14180) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14181) #	a0: pointer into memory for packed bcd string formation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14182) #	    /ptr to first mantissa byte in result string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14183) #	a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14184) #	a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14185) #	fp0: int portion of Y/abs(YINT) adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14186) #	fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14187) #	fp2: 10^LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14188) #	F_SCR1:x/Work area for final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14189) #	F_SCR2:Y with original exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14190) #	L_SCR1:original USER_FPCR/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14191) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14193) A14_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14194) 	fmov.l		&rz_mode*0x10,%fpcr	# force rz for conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14195) 	fdiv.x		%fp2,%fp0	# divide abs(YINT) by 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14196) 	lea.l		FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14197) 	fmov.x		%fp0,(%a0)	# move abs(YINT)/10^LEN to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14198) 	mov.l		4(%a0),%d2	# move 2nd word of FP_RES to d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14199) 	mov.l		8(%a0),%d3	# move 3rd word of FP_RES to d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14200) 	clr.l		4(%a0)		# zero word 2 of FP_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14201) 	clr.l		8(%a0)		# zero word 3 of FP_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14202) 	mov.l		(%a0),%d0	# move exponent to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14203) 	swap		%d0		# put exponent in lower word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14204) 	beq.b		no_sft		# if zero, don't shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14205) 	sub.l		&0x3ffd,%d0	# sub bias less 2 to make fract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14206) 	tst.l		%d0		# check if > 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14207) 	bgt.b		no_sft		# if so, don't shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14208) 	neg.l		%d0		# make exp positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14209) m_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14210) 	lsr.l		&1,%d2		# shift d2:d3 right, add 0s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14211) 	roxr.l		&1,%d3		# the number of places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14212) 	dbf.w		%d0,m_loop	# given in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14213) no_sft:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14214) 	tst.l		%d2		# check for mantissa of zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14215) 	bne.b		no_zr		# if not, go on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14216) 	tst.l		%d3		# continue zero check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14217) 	beq.b		zer_m		# if zero, go directly to binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14218) no_zr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14219) 	clr.l		%d1		# put zero in d1 for addx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14220) 	add.l		&0x00000080,%d3	# inc at bit 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14221) 	addx.l		%d1,%d2		# continue inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14222) 	and.l		&0xffffff80,%d3	# strip off lsb not used by 882
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14223) zer_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14224) 	mov.l		%d4,%d0		# put LEN in d0 for binstr call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14225) 	addq.l		&3,%a0		# a0 points to M16 byte in result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14226) 	bsr		binstr		# call binstr to convert mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14229) # A15. Convert the exponent to bcd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14230) #      As in A14 above, the exp is converted to bcd and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14231) #      digits are stored in the final string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14232) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14233) #      Digits are stored in L_SCR1(a6) on return from BINDEC as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14234) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14235) #	 32               16 15                0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14236) #	-----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14237) #	|  0 | e3 | e2 | e1 | e4 |  X |  X |  X |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14238) #	-----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14239) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14240) # And are moved into their proper places in FP_SCR0.  If digit e4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14241) # is non-zero, OPERR is signaled.  In all cases, all 4 digits are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14242) # written as specified in the 881/882 manual for packed decimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14243) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14244) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14245) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14246) #	d0: x/LEN call to binstr - final is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14247) #	d1: x/scratch (0);shift count for final exponent packing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14248) #	d2: x/ms 32-bits of exp fraction/scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14249) #	d3: x/ls 32-bits of exp fraction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14250) #	d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14251) #	d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14252) #	d6: ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14253) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14254) #	a0: ptr to result string/ptr to L_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14255) #	a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14256) #	a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14257) #	fp0: abs(YINT) adjusted/float(ILOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14258) #	fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14259) #	fp2: 10^LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14260) #	F_SCR1:Work area for final result/BCD result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14261) #	F_SCR2:Y with original exponent/ILOG/10^4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14262) #	L_SCR1:original USER_FPCR/Exponent digits on return from binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14263) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14265) A15_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14266) 	tst.b		BINDEC_FLG(%a6)	# check for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14267) 	beq.b		not_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14268) 	ftest.x		%fp0		# test for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14269) 	fbeq.w		den_zero	# if zero, use k-factor or 4933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14270) 	fmov.l		%d6,%fp0	# float ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14271) 	fabs.x		%fp0		# get abs of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14272) 	bra.b		convrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14273) den_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14274) 	tst.l		%d7		# check sign of the k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14275) 	blt.b		use_ilog	# if negative, use ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14276) 	fmov.s		F4933(%pc),%fp0	# force exponent to 4933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14277) 	bra.b		convrt		# do it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14278) use_ilog:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14279) 	fmov.l		%d6,%fp0	# float ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14280) 	fabs.x		%fp0		# get abs of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14281) 	bra.b		convrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14282) not_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14283) 	ftest.x		%fp0		# test for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14284) 	fbneq.w		not_zero	# if zero, force exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14285) 	fmov.s		FONE(%pc),%fp0	# force exponent to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14286) 	bra.b		convrt		# do it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14287) not_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14288) 	fmov.l		%d6,%fp0	# float ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14289) 	fabs.x		%fp0		# get abs of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14290) convrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14291) 	fdiv.x		24(%a1),%fp0	# compute ILOG/10^4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14292) 	fmov.x		%fp0,FP_SCR1(%a6)	# store fp0 in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14293) 	mov.l		4(%a2),%d2	# move word 2 to d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14294) 	mov.l		8(%a2),%d3	# move word 3 to d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14295) 	mov.w		(%a2),%d0	# move exp to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14296) 	beq.b		x_loop_fin	# if zero, skip the shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14297) 	sub.w		&0x3ffd,%d0	# subtract off bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14298) 	neg.w		%d0		# make exp positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14299) x_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14300) 	lsr.l		&1,%d2		# shift d2:d3 right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14301) 	roxr.l		&1,%d3		# the number of places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14302) 	dbf.w		%d0,x_loop	# given in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14303) x_loop_fin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14304) 	clr.l		%d1		# put zero in d1 for addx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14305) 	add.l		&0x00000080,%d3	# inc at bit 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14306) 	addx.l		%d1,%d2		# continue inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14307) 	and.l		&0xffffff80,%d3	# strip off lsb not used by 882
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14308) 	mov.l		&4,%d0		# put 4 in d0 for binstr call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14309) 	lea.l		L_SCR1(%a6),%a0	# a0 is ptr to L_SCR1 for exp digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14310) 	bsr		binstr		# call binstr to convert exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14311) 	mov.l		L_SCR1(%a6),%d0	# load L_SCR1 lword to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14312) 	mov.l		&12,%d1		# use d1 for shift count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14313) 	lsr.l		%d1,%d0		# shift d0 right by 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14314) 	bfins		%d0,FP_SCR0(%a6){&4:&12}	# put e3:e2:e1 in FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14315) 	lsr.l		%d1,%d0		# shift d0 right by 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14316) 	bfins		%d0,FP_SCR0(%a6){&16:&4}	# put e4 in FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14317) 	tst.b		%d0		# check if e4 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14318) 	beq.b		A16_st		# if zero, skip rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14319) 	or.l		&opaop_mask,USER_FPSR(%a6)	# set OPERR & AIOP in USER_FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14322) # A16. Write sign bits to final string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14323) #	   Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14324) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14325) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14326) #	Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14327) #	d0: x/scratch - final is x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14328) #	d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14329) #	d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14330) #	d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14331) #	d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14332) #	d6: ILOG/ILOG adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14333) #	d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14334) #	a0: ptr to L_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14335) #	a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14336) #	a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14337) #	fp0: float(ILOG)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14338) #	fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14339) #	fp2: 10^LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14340) #	F_SCR1:BCD result with correct signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14341) #	F_SCR2:ILOG/10^4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14342) #	L_SCR1:Exponent digits on return from binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14343) #	L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14345) A16_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14346) 	clr.l		%d0		# clr d0 for collection of signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14347) 	and.b		&0x0f,FP_SCR0(%a6)	# clear first nibble of FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14348) 	tst.l		L_SCR2(%a6)	# check sign of original mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14349) 	bge.b		mant_p		# if pos, don't set SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14350) 	mov.l		&2,%d0		# move 2 in to d0 for SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14351) mant_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14352) 	tst.l		%d6		# check sign of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14353) 	bge.b		wr_sgn		# if pos, don't set SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14354) 	addq.l		&1,%d0		# set bit 0 in d0 for SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14355) wr_sgn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14356) 	bfins		%d0,FP_SCR0(%a6){&0:&2}	# insert SM and SE into FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14358) # Clean up and restore all registers used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14360) 	fmov.l		&0,%fpsr	# clear possible inex2/ainex bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14361) 	fmovm.x		(%sp)+,&0xe0	#  {%fp0-%fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14362) 	movm.l		(%sp)+,&0x4fc	#  {%d2-%d7/%a2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14363) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14365) 	global		PTENRN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14366) PTENRN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14367) 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14368) 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14369) 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14370) 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14371) 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14372) 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14373) 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14374) 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14375) 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14376) 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14377) 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14378) 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14379) 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14381) 	global		PTENRP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14382) PTENRP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14383) 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14384) 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14385) 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14386) 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14387) 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14388) 	long		0x40690000,0x9DC5ADA8,0x2B70B59E	# 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14389) 	long		0x40D30000,0xC2781F49,0xFFCFA6D6	# 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14390) 	long		0x41A80000,0x93BA47C9,0x80E98CE0	# 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14391) 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8E	# 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14392) 	long		0x46A30000,0xE319A0AE,0xA60E91C7	# 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14393) 	long		0x4D480000,0xC9767586,0x81750C18	# 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14394) 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE5	# 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14395) 	long		0x75250000,0xC4605202,0x8A20979B	# 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14397) 	global		PTENRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14398) PTENRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14399) 	long		0x40020000,0xA0000000,0x00000000	# 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14400) 	long		0x40050000,0xC8000000,0x00000000	# 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14401) 	long		0x400C0000,0x9C400000,0x00000000	# 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14402) 	long		0x40190000,0xBEBC2000,0x00000000	# 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14403) 	long		0x40340000,0x8E1BC9BF,0x04000000	# 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14404) 	long		0x40690000,0x9DC5ADA8,0x2B70B59D	# 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14405) 	long		0x40D30000,0xC2781F49,0xFFCFA6D5	# 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14406) 	long		0x41A80000,0x93BA47C9,0x80E98CDF	# 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14407) 	long		0x43510000,0xAA7EEBFB,0x9DF9DE8D	# 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14408) 	long		0x46A30000,0xE319A0AE,0xA60E91C6	# 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14409) 	long		0x4D480000,0xC9767586,0x81750C17	# 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14410) 	long		0x5A920000,0x9E8B3B5D,0xC53D5DE4	# 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14411) 	long		0x75250000,0xC4605202,0x8A20979A	# 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14413) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14414) # binstr(): Converts a 64-bit binary integer to bcd.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14415) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14416) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14417) #	d2:d3 = 64-bit binary integer					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14418) #	d0    = desired length (LEN)					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14419) #	a0    = pointer to start in memory for bcd characters		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14420) #		(This pointer must point to byte 4 of the first		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14421) #		 lword of the packed decimal memory string.)		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14422) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14423) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14424) #	a0 = pointer to LEN bcd digits representing the 64-bit integer.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14425) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14426) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14427) #	The 64-bit binary is assumed to have a decimal point before	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14428) #	bit 63.  The fraction is multiplied by 10 using a mul by 2	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14429) #	shift and a mul by 8 shift.  The bits shifted out of the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14430) #	msb form a decimal digit.  This process is iterated until	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14431) #	LEN digits are formed.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14432) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14433) # A1. Init d7 to 1.  D7 is the byte digit counter, and if 1, the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14434) #     digit formed will be assumed the least significant.  This is	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14435) #     to force the first byte formed to have a 0 in the upper 4 bits.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14436) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14437) # A2. Beginning of the loop:						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14438) #     Copy the fraction in d2:d3 to d4:d5.				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14439) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14440) # A3. Multiply the fraction in d2:d3 by 8 using bit-field		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14441) #     extracts and shifts.  The three msbs from d2 will go into d1.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14442) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14443) # A4. Multiply the fraction in d4:d5 by 2 using shifts.  The msb	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14444) #     will be collected by the carry.					#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14445) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14446) # A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14447) #     into d2:d3.  D1 will contain the bcd digit formed.		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14448) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14449) # A6. Test d7.  If zero, the digit formed is the ms digit.  If non-	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14450) #     zero, it is the ls digit.  Put the digit in its place in the	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14451) #     upper word of d0.  If it is the ls digit, write the word		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14452) #     from d0 to memory.						#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14453) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14454) # A7. Decrement d6 (LEN counter) and repeat the loop until zero.	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14455) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14456) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14458) #	Implementation Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14459) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14460) #	The registers are used as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14461) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14462) #		d0: LEN counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14463) #		d1: temp used to form the digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14464) #		d2: upper 32-bits of fraction for mul by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14465) #		d3: lower 32-bits of fraction for mul by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14466) #		d4: upper 32-bits of fraction for mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14467) #		d5: lower 32-bits of fraction for mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14468) #		d6: temp for bit-field extracts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14469) #		d7: byte digit formation word;digit count {0,1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14470) #		a0: pointer into memory for packed bcd string formation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14471) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14473) 	global		binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14474) binstr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14475) 	movm.l		&0xff00,-(%sp)	#  {%d0-%d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14477) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14478) # A1: Init d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14479) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14480) 	mov.l		&1,%d7		# init d7 for second digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14481) 	subq.l		&1,%d0		# for dbf d0 would have LEN+1 passes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14482) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14483) # A2. Copy d2:d3 to d4:d5.  Start loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14484) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14485) loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14486) 	mov.l		%d2,%d4		# copy the fraction before muls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14487) 	mov.l		%d3,%d5		# to d4:d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14488) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14489) # A3. Multiply d2:d3 by 8; extract msbs into d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14490) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14491) 	bfextu		%d2{&0:&3},%d1	# copy 3 msbs of d2 into d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14492) 	asl.l		&3,%d2		# shift d2 left by 3 places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14493) 	bfextu		%d3{&0:&3},%d6	# copy 3 msbs of d3 into d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14494) 	asl.l		&3,%d3		# shift d3 left by 3 places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14495) 	or.l		%d6,%d2		# or in msbs from d3 into d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14496) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14497) # A4. Multiply d4:d5 by 2; add carry out to d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14498) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14499) 	asl.l		&1,%d5		# mul d5 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14500) 	roxl.l		&1,%d4		# mul d4 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14501) 	swap		%d6		# put 0 in d6 lower word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14502) 	addx.w		%d6,%d1		# add in extend from mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14503) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14504) # A5. Add mul by 8 to mul by 2.  D1 contains the digit formed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14505) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14506) 	add.l		%d5,%d3		# add lower 32 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14507) 	nop				# ERRATA FIX #13 (Rev. 1.2 6/6/90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14508) 	addx.l		%d4,%d2		# add with extend upper 32 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14509) 	nop				# ERRATA FIX #13 (Rev. 1.2 6/6/90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14510) 	addx.w		%d6,%d1		# add in extend from add to d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14511) 	swap		%d6		# with d6 = 0; put 0 in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14512) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14513) # A6. Test d7 and branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14514) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14515) 	tst.w		%d7		# if zero, store digit & to loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14516) 	beq.b		first_d		# if non-zero, form byte & write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14517) sec_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14518) 	swap		%d7		# bring first digit to word d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14519) 	asl.w		&4,%d7		# first digit in upper 4 bits d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14520) 	add.w		%d1,%d7		# add in ls digit to d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14521) 	mov.b		%d7,(%a0)+	# store d7b byte in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14522) 	swap		%d7		# put LEN counter in word d7a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14523) 	clr.w		%d7		# set d7a to signal no digits done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14524) 	dbf.w		%d0,loop	# do loop some more!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14525) 	bra.b		end_bstr	# finished, so exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14526) first_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14527) 	swap		%d7		# put digit word in d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14528) 	mov.w		%d1,%d7		# put new digit in d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14529) 	swap		%d7		# put LEN counter in word d7a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14530) 	addq.w		&1,%d7		# set d7a to signal first digit done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14531) 	dbf.w		%d0,loop	# do loop some more!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14532) 	swap		%d7		# put last digit in string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14533) 	lsl.w		&4,%d7		# move it to upper 4 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14534) 	mov.b		%d7,(%a0)+	# store it in memory string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14535) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14536) # Clean up and return with result in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14537) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14538) end_bstr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14539) 	movm.l		(%sp)+,&0xff	#  {%d0-%d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14540) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14542) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14543) # XDEF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14544) #	facc_in_b(): dmem_read_byte failed				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14545) #	facc_in_w(): dmem_read_word failed				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14546) #	facc_in_l(): dmem_read_long failed				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14547) #	facc_in_d(): dmem_read of dbl prec failed			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14548) #	facc_in_x(): dmem_read of ext prec failed			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14549) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14550) #	facc_out_b(): dmem_write_byte failed				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14551) #	facc_out_w(): dmem_write_word failed				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14552) #	facc_out_l(): dmem_write_long failed				#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14553) #	facc_out_d(): dmem_write of dbl prec failed			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14554) #	facc_out_x(): dmem_write of ext prec failed			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14555) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14556) # XREF ****************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14557) #	_real_access() - exit through access error handler		#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14558) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14559) # INPUT ***************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14560) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14561) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14562) # OUTPUT **************************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14563) #	None								#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14564) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14565) # ALGORITHM ***********************************************************	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14566) #	Flow jumps here when an FP data fetch call gets an error	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14567) # result. This means the operating system wants an access error frame	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14568) # made out of the current exception stack frame.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14569) #	So, we first call restore() which makes sure that any updated	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14570) # -(an)+ register gets returned to its pre-exception value and then	#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14571) # we change the stack to an access error stack frame.			#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14572) #									#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14573) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14575) facc_in_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14576) 	movq.l		&0x1,%d0			# one byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14577) 	bsr.w		restore				# fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14579) 	mov.w		&0x0121,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14580) 	bra.w		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14582) facc_in_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14583) 	movq.l		&0x2,%d0			# two bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14584) 	bsr.w		restore				# fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14586) 	mov.w		&0x0141,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14587) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14589) facc_in_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14590) 	movq.l		&0x4,%d0			# four bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14591) 	bsr.w		restore				# fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14593) 	mov.w		&0x0101,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14594) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14596) facc_in_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14597) 	movq.l		&0x8,%d0			# eight bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14598) 	bsr.w		restore				# fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14600) 	mov.w		&0x0161,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14601) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14603) facc_in_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14604) 	movq.l		&0xc,%d0			# twelve bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14605) 	bsr.w		restore				# fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14607) 	mov.w		&0x0161,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14608) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14610) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14612) facc_out_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14613) 	movq.l		&0x1,%d0			# one byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14614) 	bsr.w		restore				# restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14616) 	mov.w		&0x00a1,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14617) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14619) facc_out_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14620) 	movq.l		&0x2,%d0			# two bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14621) 	bsr.w		restore				# restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14623) 	mov.w		&0x00c1,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14624) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14626) facc_out_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14627) 	movq.l		&0x4,%d0			# four bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14628) 	bsr.w		restore				# restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14630) 	mov.w		&0x0081,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14631) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14633) facc_out_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14634) 	movq.l		&0x8,%d0			# eight bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14635) 	bsr.w		restore				# restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14637) 	mov.w		&0x00e1,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14638) 	bra.b		facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14640) facc_out_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14641) 	mov.l		&0xc,%d0			# twelve bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14642) 	bsr.w		restore				# restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14644) 	mov.w		&0x00e1,EXC_VOFF(%a6)		# set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14646) # here's where we actually create the access error frame from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14647) # current exception stack frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14648) facc_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14649) 	mov.l		USER_FPIAR(%a6),EXC_PC(%a6) # store current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14651) 	fmovm.x		EXC_FPREGS(%a6),&0xc0	# restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14652) 	fmovm.l		USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14653) 	movm.l		EXC_DREGS(%a6),&0x0303	# restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14655) 	unlk		%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14657) 	mov.l		(%sp),-(%sp)		# store SR, hi(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14658) 	mov.l		0x8(%sp),0x4(%sp)	# store lo(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14659) 	mov.l		0xc(%sp),0x8(%sp)	# store EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14660) 	mov.l		&0x00000001,0xc(%sp)	# store FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14661) 	mov.w		0x6(%sp),0xc(%sp)	# fix FSLW (size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14662) 	mov.w		&0x4008,0x6(%sp)	# store voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14664) 	btst		&0x5,(%sp)		# supervisor or user mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14665) 	beq.b		facc_out2		# user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14666) 	bset		&0x2,0xd(%sp)		# set supervisor TM bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14668) facc_out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14669) 	bra.l		_real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14671) ##################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14673) # if the effective addressing mode was predecrement or postincrement,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14674) # the emulation has already changed its value to the correct post-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14675) # instruction value. but since we're exiting to the access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14676) # handler, then AN must be returned to its pre-instruction value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14677) # we do that here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14678) restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14679) 	mov.b		EXC_OPWORD+0x1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14680) 	andi.b		&0x38,%d1		# extract opmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14681) 	cmpi.b		%d1,&0x18		# postinc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14682) 	beq.w		rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14683) 	cmpi.b		%d1,&0x20		# predec?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14684) 	beq.w		rest_dec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14685) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14687) rest_inc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14688) 	mov.b		EXC_OPWORD+0x1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14689) 	andi.w		&0x0007,%d1		# fetch An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14691) 	mov.w		(tbl_rest_inc.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14692) 	jmp		(tbl_rest_inc.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14694) tbl_rest_inc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14695) 	short		ri_a0 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14696) 	short		ri_a1 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14697) 	short		ri_a2 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14698) 	short		ri_a3 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14699) 	short		ri_a4 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14700) 	short		ri_a5 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14701) 	short		ri_a6 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14702) 	short		ri_a7 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14704) ri_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14705) 	sub.l		%d0,EXC_DREGS+0x8(%a6)	# fix stacked a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14706) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14707) ri_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14708) 	sub.l		%d0,EXC_DREGS+0xc(%a6)	# fix stacked a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14709) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14710) ri_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14711) 	sub.l		%d0,%a2			# fix a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14712) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14713) ri_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14714) 	sub.l		%d0,%a3			# fix a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14715) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14716) ri_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14717) 	sub.l		%d0,%a4			# fix a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14718) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14719) ri_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14720) 	sub.l		%d0,%a5			# fix a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14721) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14722) ri_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14723) 	sub.l		%d0,(%a6)		# fix stacked a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14724) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14725) # if it's a fmove out instruction, we don't have to fix a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14726) # because we hadn't changed it yet. if it's an opclass two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14727) # instruction (data moved in) and the exception was in supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14728) # mode, then also also wasn't updated. if it was user mode, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14729) # restore the correct a7 which is in the USP currently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14730) ri_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14731) 	cmpi.b		EXC_VOFF(%a6),&0x30	# move in or out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14732) 	bne.b		ri_a7_done		# out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14734) 	btst		&0x5,EXC_SR(%a6)	# user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14735) 	bne.b		ri_a7_done		# supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14736) 	movc		%usp,%a0		# restore USP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14737) 	sub.l		%d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14738) 	movc		%a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14739) ri_a7_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14740) 	rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14742) # need to invert adjustment value if the <ea> was predec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14743) rest_dec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14744) 	neg.l		%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14745) 	bra.b		rest_inc