^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) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) # freal.s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) # This file is appended to the top of the 060FPSP package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) # and contains the entry points into the package. The user, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) # effect, branches to one of the branch table entries located
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) # after _060FPSP_TABLE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) # Also, subroutine stubs exist in this file (_fpsp_done for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) # example) that are referenced by the FPSP package itself in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) # to call a given routine. The stub routine actually performs the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) # callout. The FPSP code does a "bsr" to the stub routine. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) # extra layer of hierarchy adds a slight performance penalty but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) # it makes the FPSP code easier to read and more mainatinable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) set _off_bsun, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) set _off_snan, 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) set _off_operr, 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) set _off_ovfl, 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) set _off_unfl, 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) set _off_dz, 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) set _off_inex, 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) set _off_fline, 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) set _off_fpu_dis, 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) set _off_trap, 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) set _off_trace, 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) set _off_access, 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) set _off_done, 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) set _off_imr, 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) set _off_dmr, 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) set _off_dmw, 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) set _off_irw, 0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) set _off_irl, 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) set _off_drb, 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) set _off_drw, 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) set _off_drl, 0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) set _off_dwb, 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) set _off_dww, 0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) set _off_dwl, 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) _060FPSP_TABLE:
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) # Here's the table of ENTRY POINTS for those linking the package.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) bra.l _fpsp_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bra.l _fpsp_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) bra.l _fpsp_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bra.l _fpsp_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) bra.l _fpsp_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) bra.l _fpsp_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) bra.l _fpsp_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) bra.l _fpsp_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) bra.l _fpsp_effadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) space 56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ###############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) global _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) _fpsp_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) mov.l (_060FPSP_TABLE-0x80+_off_done,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) global _real_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) _real_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) mov.l (_060FPSP_TABLE-0x80+_off_ovfl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) global _real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) _real_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mov.l (_060FPSP_TABLE-0x80+_off_unfl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) global _real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) _real_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mov.l (_060FPSP_TABLE-0x80+_off_inex,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) global _real_bsun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) _real_bsun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mov.l (_060FPSP_TABLE-0x80+_off_bsun,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) global _real_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) _real_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) mov.l (_060FPSP_TABLE-0x80+_off_operr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) global _real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) _real_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) mov.l (_060FPSP_TABLE-0x80+_off_snan,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) global _real_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) _real_dz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mov.l (_060FPSP_TABLE-0x80+_off_dz,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) global _real_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) _real_fline:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) mov.l (_060FPSP_TABLE-0x80+_off_fline,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) global _real_fpu_disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) _real_fpu_disabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mov.l (_060FPSP_TABLE-0x80+_off_fpu_dis,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) global _real_trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) _real_trap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) mov.l (_060FPSP_TABLE-0x80+_off_trap,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) global _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) _real_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mov.l (_060FPSP_TABLE-0x80+_off_trace,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) global _real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) _real_access:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mov.l (_060FPSP_TABLE-0x80+_off_access,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) rtd &0x4
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) global _imem_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) _imem_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) mov.l (_060FPSP_TABLE-0x80+_off_imr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) global _dmem_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) _dmem_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) mov.l (_060FPSP_TABLE-0x80+_off_dmr,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) global _dmem_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) _dmem_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) mov.l (_060FPSP_TABLE-0x80+_off_dmw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) global _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) _imem_read_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mov.l (_060FPSP_TABLE-0x80+_off_irw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) global _imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) _imem_read_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mov.l (_060FPSP_TABLE-0x80+_off_irl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) global _dmem_read_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) _dmem_read_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mov.l (_060FPSP_TABLE-0x80+_off_drb,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) global _dmem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) _dmem_read_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mov.l (_060FPSP_TABLE-0x80+_off_drw,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) global _dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) _dmem_read_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) mov.l (_060FPSP_TABLE-0x80+_off_drl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) global _dmem_write_byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) _dmem_write_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mov.l (_060FPSP_TABLE-0x80+_off_dwb,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) global _dmem_write_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) _dmem_write_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mov.l (_060FPSP_TABLE-0x80+_off_dww,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) global _dmem_write_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) _dmem_write_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mov.l (_060FPSP_TABLE-0x80+_off_dwl,%pc),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pea.l (_060FPSP_TABLE-0x80,%pc,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) mov.l 0x4(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) rtd &0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) # This file contains a set of define statements for constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) # in order to promote readability within the corecode itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) set LOCAL_SIZE, 192 # stack frame size(bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) set LV, -LOCAL_SIZE # stack offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) set EXC_SR, 0x4 # stack status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) set EXC_PC, 0x6 # stack pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) set EXC_VOFF, 0xa # stacked vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) set EXC_EA, 0xc # stacked <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) set EXC_FP, 0x0 # frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) set EXC_AREGS, -68 # offset of all address regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) set EXC_DREGS, -100 # offset of all data regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) set EXC_FPREGS, -36 # offset of all fp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) set EXC_A7, EXC_AREGS+(7*4) # offset of saved a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) set OLD_A7, EXC_AREGS+(6*4) # extra copy of saved a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) set EXC_A6, EXC_AREGS+(6*4) # offset of saved a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) set EXC_A5, EXC_AREGS+(5*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) set EXC_A4, EXC_AREGS+(4*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) set EXC_A3, EXC_AREGS+(3*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) set EXC_A2, EXC_AREGS+(2*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) set EXC_A1, EXC_AREGS+(1*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) set EXC_A0, EXC_AREGS+(0*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) set EXC_D7, EXC_DREGS+(7*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) set EXC_D6, EXC_DREGS+(6*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) set EXC_D5, EXC_DREGS+(5*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) set EXC_D4, EXC_DREGS+(4*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) set EXC_D3, EXC_DREGS+(3*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) set EXC_D2, EXC_DREGS+(2*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) set EXC_D1, EXC_DREGS+(1*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) set EXC_D0, EXC_DREGS+(0*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) set EXC_FP0, EXC_FPREGS+(0*12) # offset of saved fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) set EXC_FP1, EXC_FPREGS+(1*12) # offset of saved fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) set EXC_FP2, EXC_FPREGS+(2*12) # offset of saved fp2 (not used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) set FP_SCR1, LV+80 # fp scratch 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) set FP_SCR1_EX, FP_SCR1+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) set FP_SCR1_SGN, FP_SCR1+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) set FP_SCR1_HI, FP_SCR1+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) set FP_SCR1_LO, FP_SCR1+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) set FP_SCR0, LV+68 # fp scratch 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) set FP_SCR0_EX, FP_SCR0+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) set FP_SCR0_SGN, FP_SCR0+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) set FP_SCR0_HI, FP_SCR0+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) set FP_SCR0_LO, FP_SCR0+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) set FP_DST, LV+56 # fp destination operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) set FP_DST_EX, FP_DST+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) set FP_DST_SGN, FP_DST+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) set FP_DST_HI, FP_DST+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) set FP_DST_LO, FP_DST+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) set FP_SRC, LV+44 # fp source operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) set FP_SRC_EX, FP_SRC+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) set FP_SRC_SGN, FP_SRC+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) set FP_SRC_HI, FP_SRC+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) set FP_SRC_LO, FP_SRC+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) set USER_FPIAR, LV+40 # FP instr address register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) set USER_FPSR, LV+36 # FP status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) set FPSR_CC, USER_FPSR+0 # FPSR condition codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) set FPSR_QBYTE, USER_FPSR+1 # FPSR qoutient byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) set FPSR_EXCEPT, USER_FPSR+2 # FPSR exception status byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) set FPSR_AEXCEPT, USER_FPSR+3 # FPSR accrued exception byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) set USER_FPCR, LV+32 # FP control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) set FPCR_ENABLE, USER_FPCR+2 # FPCR exception enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) set FPCR_MODE, USER_FPCR+3 # FPCR rounding mode control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) set L_SCR3, LV+28 # integer scratch 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) set L_SCR2, LV+24 # integer scratch 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) set L_SCR1, LV+20 # integer scratch 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) set STORE_FLG, LV+19 # flag: operand store (ie. not fcmp/ftst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) set EXC_TEMP2, LV+24 # temporary space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) set EXC_TEMP, LV+16 # temporary space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) set DTAG, LV+15 # destination operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) set STAG, LV+14 # source operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) set SPCOND_FLG, LV+10 # flag: special case (see below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) set EXC_CC, LV+8 # saved condition codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) set EXC_EXTWPTR, LV+4 # saved current PC (active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) set EXC_EXTWORD, LV+2 # saved extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) set EXC_CMDREG, LV+2 # saved extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) set EXC_OPWORD, LV+0 # saved operation word
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) # Helpful macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) set FTEMP, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) set FTEMP_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) set FTEMP_SGN, 2 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) set FTEMP_HI, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) set FTEMP_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) set FTEMP_GRS, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) set LOCAL, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) set LOCAL_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) set LOCAL_SGN, 2 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) set LOCAL_HI, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) set LOCAL_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) set LOCAL_GRS, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) set DST, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) set DST_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) set DST_HI, 4 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) set DST_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) set SRC, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) set SRC_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) set SRC_HI, 4 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) set SRC_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) set SGL_LO, 0x3f81 # min sgl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) set SGL_HI, 0x407e # max sgl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) set DBL_LO, 0x3c01 # min dbl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) set DBL_HI, 0x43fe # max dbl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) set EXT_LO, 0x0 # min ext prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) set EXT_HI, 0x7ffe # max ext prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) set EXT_BIAS, 0x3fff # extended precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) set SGL_BIAS, 0x007f # single precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) set DBL_BIAS, 0x03ff # double precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) set NORM, 0x00 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) set ZERO, 0x01 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) set INF, 0x02 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) set QNAN, 0x03 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) set DENORM, 0x04 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) set SNAN, 0x05 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) set UNNORM, 0x06 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ##################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) # FPSR/FPCR bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ##################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) set neg_bit, 0x3 # negative result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) set z_bit, 0x2 # zero result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) set inf_bit, 0x1 # infinite result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) set nan_bit, 0x0 # NAN result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) set q_sn_bit, 0x7 # sign bit of quotient byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) set bsun_bit, 7 # branch on unordered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) set snan_bit, 6 # signalling NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) set operr_bit, 5 # operand error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) set ovfl_bit, 4 # overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) set unfl_bit, 3 # underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) set dz_bit, 2 # divide by zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) set inex2_bit, 1 # inexact result 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) set inex1_bit, 0 # inexact result 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) set aiop_bit, 7 # accrued inexact operation bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) set aovfl_bit, 6 # accrued overflow bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) set aunfl_bit, 5 # accrued underflow bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) set adz_bit, 4 # accrued dz bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) set ainex_bit, 3 # accrued inexact bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) # FPSR individual bit masks #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) set neg_mask, 0x08000000 # negative bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) set inf_mask, 0x02000000 # infinity bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) set z_mask, 0x04000000 # zero bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) set nan_mask, 0x01000000 # nan bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) set neg_bmask, 0x08 # negative bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) set inf_bmask, 0x02 # infinity bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) set z_bmask, 0x04 # zero bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) set nan_bmask, 0x01 # nan bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) set bsun_mask, 0x00008000 # bsun exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) set snan_mask, 0x00004000 # snan exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) set operr_mask, 0x00002000 # operr exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) set ovfl_mask, 0x00001000 # overflow exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) set unfl_mask, 0x00000800 # underflow exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) set dz_mask, 0x00000400 # dz exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) set inex2_mask, 0x00000200 # inex2 exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) set inex1_mask, 0x00000100 # inex1 exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) set aiop_mask, 0x00000080 # accrued illegal operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) set aovfl_mask, 0x00000040 # accrued overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) set aunfl_mask, 0x00000020 # accrued underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) set adz_mask, 0x00000010 # accrued divide by zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) set ainex_mask, 0x00000008 # accrued inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) # FPSR combinations used in the FPSP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) set dzinf_mask, inf_mask+dz_mask+adz_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) set opnan_mask, nan_mask+operr_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) set nzi_mask, 0x01ffffff #clears N, Z, and I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) set unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) set unf2inx_mask, unfl_mask+inex2_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) set ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) set inx1a_mask, inex1_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) set inx2a_mask, inex2_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) set snaniop_mask, nan_mask+snan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) set snaniop2_mask, snan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) set naniop_mask, nan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) set neginf_mask, neg_mask+inf_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) set infaiop_mask, inf_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) set negz_mask, neg_mask+z_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) set opaop_mask, operr_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) set unfl_inx_mask, unfl_mask+aunfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) set ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) # misc. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) set rnd_stky_bit, 29 # stky bit pos in longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) set sign_bit, 0x7 # sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) set signan_bit, 0x6 # signalling nan bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) set sgl_thresh, 0x3f81 # minimum sgl exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) set dbl_thresh, 0x3c01 # minimum dbl exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) set x_mode, 0x0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) set s_mode, 0x4 # single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) set d_mode, 0x8 # double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) set rn_mode, 0x0 # round-to-nearest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) set rz_mode, 0x1 # round-to-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) set rm_mode, 0x2 # round-tp-minus-infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) set rp_mode, 0x3 # round-to-plus-infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) set mantissalen, 64 # length of mantissa in bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) set BYTE, 1 # len(byte) == 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) set WORD, 2 # len(word) == 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) set LONG, 4 # len(longword) == 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) set BSUN_VEC, 0xc0 # bsun vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) set INEX_VEC, 0xc4 # inexact vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) set DZ_VEC, 0xc8 # dz vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) set UNFL_VEC, 0xcc # unfl vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) set OPERR_VEC, 0xd0 # operr vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) set OVFL_VEC, 0xd4 # ovfl vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) set SNAN_VEC, 0xd8 # snan vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) # SPecial CONDition FLaGs #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) set ftrapcc_flg, 0x01 # flag bit: ftrapcc exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) set fbsun_flg, 0x02 # flag bit: bsun exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) set mia7_flg, 0x04 # flag bit: (a7)+ <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) set mda7_flg, 0x08 # flag bit: -(a7) <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) set fmovm_flg, 0x40 # flag bit: fmovm instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) set immed_flg, 0x80 # flag bit: &<data> <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) set ftrapcc_bit, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) set fbsun_bit, 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) set mia7_bit, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) set mda7_bit, 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) set immed_bit, 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ##################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) # TRANSCENDENTAL "LAST-OP" FLAGS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ##################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) set FMUL_OP, 0x0 # fmul instr performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) set FDIV_OP, 0x1 # fdiv performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) set FADD_OP, 0x2 # fadd performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) set FMOV_OP, 0x3 # fmov performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) # CONSTANTS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) T1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) T2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) PI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) PIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) TWOBYPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) long 0x3FE45F30,0x6DC9C883
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) # _fpsp_ovfl(): 060FPSP entry point for FP Overflow exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) # FP Overflow exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) # _imem_read_long() - read instruction longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) # fix_skewed_ops() - adjust src operand in fsave frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) # set_tag_x() - determine optype of src/dst operands #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) # store_fpreg() - store opclass 0 or 2 result to FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) # unnorm_fix() - change UNNORM operands to NORM or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) # load_fpn2() - load dst operand from FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) # fout() - emulate an opclass 3 instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) # tbl_unsupp - add of table of emulation routines for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) # _fpsp_done() - "callout" for 060FPSP exit (all work done!) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) # _real_ovfl() - "callout" for Overflow exception enabled code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) # _real_inex() - "callout" for Inexact exception enabled code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) # _real_trace() - "callout" for Trace exception code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) # - The system stack contains the FP Ovfl exception stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) # - The fsave frame contains the source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) # Overflow Exception enabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) # - The fsave frame contains the adjusted src op for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) # Overflow Exception disabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) # - The "exception present" flag in the fsave frame is cleared #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) # On the 060, if an FP overflow is present as the result of any #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) # instruction, the 060 will take an overflow exception whether the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) # exception is enabled or disabled in the FPCR. For the disabled case, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) # This handler emulates the instruction to determine what the correct #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) # default result should be for the operation. This default result is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) # then stored in either the FP regfile, data regfile, or memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) # Finally, the handler exits through the "callout" _fpsp_done() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) # denoting that no exceptional conditions exist within the machine. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) # If the exception is enabled, then this handler must create the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) # exceptional operand and plave it in the fsave state frame, and store #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) # the default result (only if the instruction is opclass 3). For #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) # exceptions enabled, this handler must exit through the "callout" #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) # _real_ovfl() so that the operating system enabled overflow handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) # can handle this case. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) # Two other conditions exist. First, if overflow was disabled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) # but the inexact exception was enabled, this handler must exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) # through the "callout" _real_inex() regardless of whether the result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) # was inexact. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) # Also, in the case of an opclass three instruction where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) # overflow was disabled and the trace exception was enabled, this #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) # handler must exit through the "callout" _real_trace(). #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) global _fpsp_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) _fpsp_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #$# sub.l &24,%sp # make room for src/dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) fsave FP_SRC(%a6) # grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) mov.l %d0,EXC_OPWORD(%a6)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) btst &0x5,EXC_CMDREG(%a6) # is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) bne.w fovfl_out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) bsr.l fix_skewed_ops # fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) # since, I believe, only NORMs and DENORMs can come through here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) # maybe we can avoid the subroutine call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) mov.b %d0,STAG(%a6) # maybe NORM,DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) # bit five of the fp extension word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) # that can pass through fpsp_ovfl(). remember that fcmp, ftst, and fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) # will never take this exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) beq.b fovfl_extract # monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) bsr.l load_fpn2 # load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) lea FP_DST(%a6),%a0 # pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) bne.b fovfl_op2_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) fovfl_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) mov.b %d0,DTAG(%a6) # save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) fovfl_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) #$# mov.l FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) #$# mov.l FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) #$# mov.l FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) mov.b 1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) andi.w &0x007f,%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) andi.l &0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) lea FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) # maybe we can make these entry points ONLY the OVFL entry points of each routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) jsr (tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) # the operation has been emulated. the result is in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) # the EXOP, if an exception occurred, is in fp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) # we must save the default result regardless of whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) # traps are enabled or disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) bfextu EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) bsr.l store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) # the exceptional possibilities we have left ourselves with are ONLY overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) # and inexact. and, the inexact is such that overflow occurred and was disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) # but inexact was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) btst &ovfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) bne.b fovfl_ovfl_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) btst &inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) bne.b fovfl_inex_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) #$# add.l &24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) # in fp1. now, simply jump to _real_ovfl()!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) fovfl_ovfl_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) mov.w &0xe005,2+FP_SRC(%a6) # save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) frestore FP_SRC(%a6) # do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) bra.l _real_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) # overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) # we must jump to real_inex().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) fovfl_inex_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) mov.b &0xc4,1+EXC_VOFF(%a6) # vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) mov.w &0xe001,2+FP_SRC(%a6) # save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) frestore FP_SRC(%a6) # do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) bra.l _real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) fovfl_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) # the src operand is definitely a NORM(!), so tag it as such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) mov.b &NORM,STAG(%a6) # set src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) and.l &0xffff00ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) lea FP_SRC(%a6),%a0 # pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) bsr.l fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) btst &ovfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) bne.w fovfl_ovfl_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) btst &inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) bne.w fovfl_inex_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) #$# add.l &24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) beq.l _fpsp_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) fmov.l %fpiar,0x8(%sp) # "Current PC" is in FPIAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) # _fpsp_unfl(): 060FPSP entry point for FP Underflow exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) # FP Underflow exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) # _imem_read_long() - read instruction longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) # fix_skewed_ops() - adjust src operand in fsave frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) # set_tag_x() - determine optype of src/dst operands #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) # store_fpreg() - store opclass 0 or 2 result to FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) # unnorm_fix() - change UNNORM operands to NORM or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) # load_fpn2() - load dst operand from FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) # fout() - emulate an opclass 3 instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) # tbl_unsupp - add of table of emulation routines for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) # _fpsp_done() - "callout" for 060FPSP exit (all work done!) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) # _real_ovfl() - "callout" for Overflow exception enabled code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) # _real_inex() - "callout" for Inexact exception enabled code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) # _real_trace() - "callout" for Trace exception code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) # - The system stack contains the FP Unfl exception stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) # - The fsave frame contains the source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) # Underflow Exception enabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) # - The fsave frame contains the adjusted src op for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) # Underflow Exception disabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) # - The "exception present" flag in the fsave frame is cleared #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) # On the 060, if an FP underflow is present as the result of any #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) # instruction, the 060 will take an underflow exception whether the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) # exception is enabled or disabled in the FPCR. For the disabled case, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) # This handler emulates the instruction to determine what the correct #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) # default result should be for the operation. This default result is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) # then stored in either the FP regfile, data regfile, or memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) # Finally, the handler exits through the "callout" _fpsp_done() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) # denoting that no exceptional conditions exist within the machine. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) # If the exception is enabled, then this handler must create the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) # exceptional operand and plave it in the fsave state frame, and store #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) # the default result (only if the instruction is opclass 3). For #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) # exceptions enabled, this handler must exit through the "callout" #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) # _real_unfl() so that the operating system enabled overflow handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) # can handle this case. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) # Two other conditions exist. First, if underflow was disabled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) # but the inexact exception was enabled and the result was inexact, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) # this handler must exit through the "callout" _real_inex(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) # was inexact. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) # Also, in the case of an opclass three instruction where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) # underflow was disabled and the trace exception was enabled, this #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) # handler must exit through the "callout" _real_trace(). #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) global _fpsp_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) _fpsp_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) #$# sub.l &24,%sp # make room for src/dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) fsave FP_SRC(%a6) # grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) mov.l %d0,EXC_OPWORD(%a6)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) btst &0x5,EXC_CMDREG(%a6) # is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) bne.w funfl_out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) bsr.l fix_skewed_ops # fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) mov.b %d0,STAG(%a6) # maybe NORM,DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) # bit five of the fp ext word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) # that can pass through fpsp_unfl(). remember that fcmp, and ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) # will never take this exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) btst &0x5,1+EXC_CMDREG(%a6) # is op monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) beq.b funfl_extract # monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) # now, what's left that's not dyadic is fsincos. we can distinguish it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) # from all dyadics by the '0110xxx pattern
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) btst &0x4,1+EXC_CMDREG(%a6) # is op an fsincos?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) bne.b funfl_extract # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) bsr.l load_fpn2 # load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) lea FP_DST(%a6),%a0 # pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) bne.b funfl_op2_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) funfl_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) mov.b %d0,DTAG(%a6) # save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) funfl_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) #$# mov.l FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) #$# mov.l FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) #$# mov.l FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) mov.b 1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) andi.w &0x007f,%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) andi.l &0x00ff01ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) lea FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) # maybe we can make these entry points ONLY the OVFL entry points of each routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) jsr (tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) bfextu EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) bsr.l store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) # The `060 FPU multiplier hardware is such that if the result of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) # multiply operation is the smallest possible normalized number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) # (0x00000000_80000000_00000000), then the machine will take an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) # underflow exception. Since this is incorrect, we need to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) # if our emulation, after re-doing the operation, decided that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) # no underflow was called for. We do these checks only in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) # funfl_{unfl,inex}_on() because w/ both exceptions disabled, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) # special case will simply exit gracefully with the correct result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) # the exceptional possibilities we have left ourselves with are ONLY overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) # and inexact. and, the inexact is such that overflow occurred and was disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) # but inexact was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) btst &unfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) bne.b funfl_unfl_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) funfl_chkinex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) btst &inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) bne.b funfl_inex_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) funfl_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) #$# add.l &24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) # in fp1 (don't forget to save fp0). what to do now?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) # well, we simply have to get to go to _real_unfl()!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) funfl_unfl_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) # The `060 FPU multiplier hardware is such that if the result of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) # multiply operation is the smallest possible normalized number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) # (0x00000000_80000000_00000000), then the machine will take an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) # underflow exception. Since this is incorrect, we check here to see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) # if our emulation, after re-doing the operation, decided that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) # no underflow was called for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) btst &unfl_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) beq.w funfl_chkinex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) funfl_unfl_on2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) mov.w &0xe003,2+FP_SRC(%a6) # save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) frestore FP_SRC(%a6) # do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) bra.l _real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) # underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) # we must jump to real_inex().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) funfl_inex_on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) # The `060 FPU multiplier hardware is such that if the result of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) # multiply operation is the smallest possible normalized number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) # (0x00000000_80000000_00000000), then the machine will take an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) # underflow exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) # But, whether bogus or not, if inexact is enabled AND it occurred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) # then we have to branch to real_inex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) btst &inex2_bit,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) beq.w funfl_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) funfl_inex_on2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) fmovm.x &0x40,FP_SRC(%a6) # save EXOP to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) mov.b &0xc4,1+EXC_VOFF(%a6) # vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) mov.w &0xe001,2+FP_SRC(%a6) # save exc status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) frestore FP_SRC(%a6) # do this after fmovm,other f<op>s!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) bra.l _real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #######################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) funfl_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) # the src operand is definitely a NORM(!), so tag it as such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) mov.b &NORM,STAG(%a6) # set src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) and.l &0xffff00ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) lea FP_SRC(%a6),%a0 # pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) bsr.l fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) btst &unfl_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) bne.w funfl_unfl_on2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) btst &inex2_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) bne.w funfl_inex_on2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) #$# add.l &24,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) beq.l _fpsp_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) fmov.l %fpiar,0x8(%sp) # "Current PC" is in FPIAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) # _fpsp_unsupp(): 060FPSP entry point for FP "Unimplemented #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) # Data Type" exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) # FP Unimplemented Data Type exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) # _imem_read_{word,long}() - read instruction word/longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) # fix_skewed_ops() - adjust src operand in fsave frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) # set_tag_x() - determine optype of src/dst operands #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) # store_fpreg() - store opclass 0 or 2 result to FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) # unnorm_fix() - change UNNORM operands to NORM or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) # load_fpn2() - load dst operand from FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) # load_fpn1() - load src operand from FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) # fout() - emulate an opclass 3 instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) # tbl_unsupp - add of table of emulation routines for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) # _real_inex() - "callout" to operating system inexact handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) # _fpsp_done() - "callout" for exit; work all done #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) # _real_trace() - "callout" for Trace enabled exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) # funimp_skew() - adjust fsave src ops to "incorrect" value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) # _real_snan() - "callout" for SNAN exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) # _real_operr() - "callout" for OPERR exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) # _real_ovfl() - "callout" for OVFL exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) # _real_unfl() - "callout" for UNFL exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) # get_packed() - fetch packed operand from memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) # - The system stack contains the "Unimp Data Type" stk frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) # - The fsave frame contains the ssrc op (for UNNORM/DENORM) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) # If Inexact exception (opclass 3): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) # - The system stack is changed to an Inexact exception stk frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) # If SNAN exception (opclass 3): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) # - The system stack is changed to an SNAN exception stk frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) # If OPERR exception (opclass 3): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) # - The system stack is changed to an OPERR exception stk frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) # If OVFL exception (opclass 3): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) # - The system stack is changed to an OVFL exception stk frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) # If UNFL exception (opclass 3): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) # - The system stack is changed to an UNFL exception stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) # If Trace exception enabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) # - The system stack is changed to a Trace exception stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) # Else: (normal case) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) # - Correct result has been stored as appropriate #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) # Two main instruction types can enter here: (1) DENORM or UNNORM #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) # unimplemented data types. These can be either opclass 0,2 or 3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) # instructions, and (2) PACKED unimplemented data format instructions #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) # also of opclasses 0,2, or 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) # For UNNORM/DENORM opclass 0 and 2, the handler fetches the src #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) # operand from the fsave state frame and the dst operand (if dyadic) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) # from the FP register file. The instruction is then emulated by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) # choosing an emulation routine from a table of routines indexed by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) # instruction type. Once the instruction has been emulated and result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) # saved, then we check to see if any enabled exceptions resulted from #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) # instruction emulation. If none, then we exit through the "callout" #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) # _fpsp_done(). If there is an enabled FP exception, then we insert #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) # this exception into the FPU in the fsave state frame and then exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) # through _fpsp_done(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) # PACKED opclass 0 and 2 is similar in how the instruction is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) # emulated and exceptions handled. The differences occur in how the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) # handler loads the packed op (by calling get_packed() routine) and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) # by the fact that a Trace exception could be pending for PACKED ops. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) # If a Trace exception is pending, then the current exception stack #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) # frame is changed to a Trace exception stack frame and an exit is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) # made through _real_trace(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) # For UNNORM/DENORM opclass 3, the actual move out to memory is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) # performed by calling the routine fout(). If no exception should occur #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) # as the result of emulation, then an exit either occurs through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) # _fpsp_done() or through _real_trace() if a Trace exception is pending #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) # (a Trace stack frame must be created here, too). If an FP exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) # should occur, then we must create an exception stack frame of that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) # type and jump to either _real_snan(), _real_operr(), _real_inex(), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) # _real_unfl(), or _real_ovfl() as appropriate. PACKED opclass 3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) # emulation is performed in a similar manner. #
^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) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) # (1) DENORM and UNNORM (unimplemented) data types:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) # post-instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) # * EA *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) # pre-instruction * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) # * 0x0 * 0x0dc * * 0x3 * 0x0dc *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) # * Next * * Next *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) # * PC * * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) # * SR * * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) # (2) PACKED format (unsupported) opclasses two and three:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) # * EA *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) # * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) # * 0x2 * 0x0dc *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) # * Next *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) # * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) # * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) global _fpsp_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) _fpsp_unsupp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) fsave FP_SRC(%a6) # save fp state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) btst &0x5,EXC_SR(%a6) # user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) bne.b fu_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) fu_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) mov.l %usp,%a0 # fetch user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) mov.l %a0,EXC_A7(%a6) # save on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) bra.b fu_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) # if the exception is an opclass zero or two unimplemented data type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) # exception, then the a7' calculated here is wrong since it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) # stack an ea. however, we don't need an a7' for this case anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) fu_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) lea 0x4+EXC_EA(%a6),%a0 # load old a7'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) mov.l %a0,EXC_A7(%a6) # save on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) fu_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) # the FPIAR should be set correctly for ALL exceptions passing through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) # this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) mov.l %d0,EXC_OPWORD(%a6) # store OPWORD and EXTWORD
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) clr.b SPCOND_FLG(%a6) # clear special condition flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) # Separate opclass three (fpn-to-mem) ops since they have a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) # stack frame and protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) btst &0x5,EXC_CMDREG(%a6) # is it an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) bne.w fu_out # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) # Separate packed opclass two instructions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) bfextu EXC_CMDREG(%a6){&0:&6},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) cmpi.b %d0,&0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) beq.w fu_in_pack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) # so, since the emulation routines re-create them anyways, zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) andi.l &0x00ff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) # Opclass two w/ memory-to-fpn operation will have an incorrect extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) # precision format if the src format was single or double and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) # source data type was an INF, NAN, DENORM, or UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) lea FP_SRC(%a6),%a0 # pass ptr to input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) bsr.l fix_skewed_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) # 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 1267) # UNNORM or DENORM. call the function that tags the operand type. if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) # input is an UNNORM, then convert it to a NORM, DENORM, or ZERO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) bne.b fu_op2 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) fu_op2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) mov.b %d0,STAG(%a6) # save src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) # bit five of the fp extension word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) # at this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) beq.b fu_extract # monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) cmpi.b 1+EXC_CMDREG(%a6),&0x3a # is operation an ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) beq.b fu_extract # yes, so it's monadic, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) bsr.l load_fpn2 # load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) lea FP_DST(%a6),%a0 # pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) bne.b fu_op2_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) fu_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) mov.b %d0,DTAG(%a6) # save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) fu_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) bfextu 1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) lea FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) mov.l (tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) jsr (tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) # BSUN : none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) # SNAN : all dyadic ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) # OPERR : fsqrt(-NORM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) # OVFL : all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) # UNFL : all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) # DZ : fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) # INEX2 : all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) # INEX1 : none (packed doesn't go through here)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) # we determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) bne.b fu_in_ena # some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) fu_in_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) # fcmp and ftst do not store any result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) mov.b 1+EXC_CMDREG(%a6),%d0 # fetch extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) andi.b &0x38,%d0 # extract bits 3-5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) cmpi.b %d0,&0x38 # is instr fcmp or ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) beq.b fu_in_exit # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) bsr.l store_fpreg # store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) fu_in_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) fu_in_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) bfffo %d0{&24:&8},%d0 # find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) bne.b fu_in_exc # there is at least one set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) # No exceptions occurred that were also enabled. Now:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) # if (OVFL && ovfl_disabled && inexact_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) # branch to _real_inex() (even if the result was exact!);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) # } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) # save the result in the proper fp reg (unless the op is fcmp or ftst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) # return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) # }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) btst &ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) beq.b fu_in_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) fu_in_ovflchk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) btst &inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) beq.b fu_in_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) bra.w fu_in_exc_ovfl # go insert overflow frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) # An exception occurred and that exception was enabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) # shift enabled exception field into lo byte of d0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) # if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) # ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) # /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) # * this is the case where we must call _real_inex() now or else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) # * there will be no other way to pass it the exceptional operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) # */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) # call _real_inex();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) # } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) # restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) # }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) fu_in_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) subi.l &24,%d0 # fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) cmpi.b %d0,&0x6 # is exception INEX? (6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) bne.b fu_in_exc_exit # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) # the enabled exception was inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) btst &unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) bne.w fu_in_exc_unfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) btst &ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) bne.w fu_in_exc_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) # here, we insert the correct fsave status value into the fsave frame for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) # corresponding exception. the operand in the fsave frame should be the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) # src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) fu_in_exc_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) bsr.l funimp_skew # skew sgl or dbl inputs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 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 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) frestore FP_SRC(%a6) # restore src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) tbl_except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) short 0xe000,0xe006,0xe004,0xe005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) short 0xe003,0xe002,0xe001,0xe001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) fu_in_exc_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) mov.w &0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) bra.b fu_in_exc_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) fu_in_exc_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) mov.w &0x03,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) bra.b fu_in_exc_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) # If the input operand to this operation was opclass two and a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) # or double precision denorm, inf, or nan, the operand needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) # "corrected" in order to have the proper equivalent extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) # number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) global fix_skewed_ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) fix_skewed_ops:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) bfextu EXC_CMDREG(%a6){&0:&6},%d0 # extract opclass,src fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) cmpi.b %d0,&0x11 # is class = 2 & fmt = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) beq.b fso_sgl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) cmpi.b %d0,&0x15 # is class = 2 & fmt = dbl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) beq.b fso_dbl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) rts # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) fso_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) mov.w LOCAL_EX(%a0),%d0 # fetch src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) andi.w &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) cmpi.w %d0,&0x3f80 # is |exp| == $3f80?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) beq.b fso_sgl_dnrm_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) cmpi.w %d0,&0x407f # no; is |exp| == $407f?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) beq.b fso_infnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) rts # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) fso_sgl_dnrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) andi.l &0x7fffffff,LOCAL_HI(%a0) # clear j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) beq.b fso_zero # it's a skewed zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) fso_sgl_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) # here, we count on norm not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) bsr.l norm # normalize mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) neg.w %d0 # -shft amt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) addi.w &0x3f81,%d0 # adjust new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) andi.w &0x8000,LOCAL_EX(%a0) # clear old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) or.w %d0,LOCAL_EX(%a0) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) fso_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) andi.w &0x8000,LOCAL_EX(%a0) # clear bogus exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) fso_infnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) andi.b &0x7f,LOCAL_HI(%a0) # clear j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) ori.w &0x7fff,LOCAL_EX(%a0) # make exponent = $7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) fso_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) mov.w LOCAL_EX(%a0),%d0 # fetch src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) andi.w &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) cmpi.w %d0,&0x3c00 # is |exp| == $3c00?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) beq.b fso_dbl_dnrm_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) cmpi.w %d0,&0x43ff # no; is |exp| == $43ff?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) beq.b fso_infnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) rts # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) fso_dbl_dnrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) andi.l &0x7fffffff,LOCAL_HI(%a0) # clear j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) bne.b fso_dbl_dnrm # it's a skewed denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) tst.l LOCAL_LO(%a0) # is it a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) beq.b fso_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) fso_dbl_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) # here, we count on norm not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) bsr.l norm # normalize mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) neg.w %d0 # -shft amt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) addi.w &0x3c01,%d0 # adjust new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) andi.w &0x8000,LOCAL_EX(%a0) # clear old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) or.w %d0,LOCAL_EX(%a0) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) rts
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) # fmove out took an unimplemented data type exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) # the src operand is in FP_SRC. Call _fout() to write out the result and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) # to determine which exceptions, if any, to take.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) fu_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) # Separate packed move outs from the UNNORM and DENORM move outs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) bfextu EXC_CMDREG(%a6){&3:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) cmpi.b %d0,&0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) beq.w fu_out_pack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) cmpi.b %d0,&0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) beq.w fu_out_pack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) # so, since the emulation routines re-create them anyways, zero exception field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) # fmove out doesn't affect ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) and.l &0xffff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) # 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 1516) # call here. just figure out what it is...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) mov.w FP_SRC_EX(%a6),%d0 # get exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) andi.w &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) beq.b fu_out_denorm # it's a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) bsr.l unnorm_fix # yes; fix it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) bra.b fu_out_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) fu_out_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) mov.b &DENORM,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) fu_out_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) lea FP_SRC(%a6),%a0 # pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) mov.l (%a6),EXC_A6(%a6) # in case a6 changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) bsr.l fout # call fmove out routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) # BSUN : none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) # SNAN : none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) # OPERR : fmove.{b,w,l} out of large UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) # OVFL : fmove.{s,d}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) # UNFL : fmove.{s,d,x}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) # DZ : none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) # INEX2 : all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) # INEX1 : none (packed doesn't travel through here)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) # determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) bne.w fu_out_ena # some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) fu_out_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) mov.l EXC_A6(%a6),(%a6) # in case a6 changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) # on extended precision opclass three instructions using pre-decrement or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) # post-increment addressing mode, the address register is not updated. is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) # address register was the stack pointer used from user mode, then let's update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) # it here. if it was used from supervisor mode, then we have to handle this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) # as a special case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) btst &0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) bne.b fu_out_done_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) mov.l EXC_A7(%a6),%a0 # restore a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) fu_out_done_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) bne.b fu_out_trace # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) # is the ea mode pre-decrement of the stack pointer from supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) # ("fmov.x fpm,-(a7)") if so,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) fu_out_done_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) cmpi.b SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) bne.b fu_out_done_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) # the extended precision result is still in fp0. but, we need to save it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) # somewhere on the stack until we can copy it to its final resting place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) # 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 1590) # for fp0/fp1 which have already been restored. that way, we can write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) # over those destinations with the shifted stack frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) fmovm.x &0x80,FP_SRC(%a6) # put answer on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) mov.l (%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) # now, copy the result to the proper place on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) mov.l LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) mov.l LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) mov.l LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) add.l &LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) btst &0x7,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) bne.b fu_out_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) fu_out_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) bfffo %d0{&24:&8},%d0 # find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) bne.b fu_out_exc # there is at least one set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) # no exceptions were set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) # if a disabled overflow occurred and inexact was enabled but the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) # was exact, then a branch to _real_inex() is made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) btst &ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) beq.w fu_out_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) fu_out_ovflchk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) btst &inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) beq.w fu_out_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) bra.w fu_inex # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) # The fp move out that took the "Unimplemented Data Type" exception was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) # being traced. Since the stack frames are similar, get the "current" PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) # from FPIAR and put it in the trace stack frame then jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) # UNSUPP FRAME TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) # * EA * * Current *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) # * * * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) # * 0x3 * 0x0dc * * 0x2 * 0x024 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) # * Next * * Next *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) # * PC * * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) # * SR * * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) fu_out_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) mov.w &0x2024,0x6(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) fmov.l %fpiar,0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) # an exception occurred and that exception was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) fu_out_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) subi.l &24,%d0 # fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) # we don't mess with the existing fsave frame. just re-insert it and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) # jump to the "_real_{}()" handler...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) mov.w (tbl_fu_out.b,%pc,%d0.w*2),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) jmp (tbl_fu_out.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) swbeg &0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) tbl_fu_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) short tbl_fu_out - tbl_fu_out # BSUN can't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) short tbl_fu_out - tbl_fu_out # SNAN can't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) short fu_operr - tbl_fu_out # OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) short fu_ovfl - tbl_fu_out # OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) short fu_unfl - tbl_fu_out # UNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) short tbl_fu_out - tbl_fu_out # DZ can't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) short fu_inex - tbl_fu_out # INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) short tbl_fu_out - tbl_fu_out # INEX1 won't make it here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) # for snan,operr,ovfl,unfl, src op is still in FP_SRC so just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) # frestore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) fu_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) mov.w &0x30d8,EXC_VOFF(%a6) # vector offset = 0xd8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) mov.w &0xe006,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) frestore FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) bra.l _real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) fu_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) mov.w &0x30d0,EXC_VOFF(%a6) # vector offset = 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) mov.w &0xe004,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) frestore FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) bra.l _real_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) fu_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) fmovm.x &0x40,FP_SRC(%a6) # save EXOP to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) mov.w &0x30d4,EXC_VOFF(%a6) # vector offset = 0xd4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) mov.w &0xe005,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) frestore FP_SRC(%a6) # restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) bra.l _real_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) # underflow can happen for extended precision. extended precision opclass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) # three instruction exceptions don't update the stack pointer. so, if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) # exception occurred from user mode, then simply update a7 and exit normally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) # if the exception occurred from supervisor mode, check if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) fu_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) mov.l EXC_A6(%a6),(%a6) # restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) btst &0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) bne.w fu_unfl_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) mov.l EXC_A7(%a6),%a0 # restore a7 whether we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) mov.l %a0,%usp # to or not...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) fu_unfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) fmovm.x &0x40,FP_SRC(%a6) # save EXOP to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) mov.w &0x30cc,EXC_VOFF(%a6) # vector offset = 0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) mov.w &0xe003,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) frestore FP_SRC(%a6) # restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) bra.l _real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) fu_unfl_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) cmpi.b SPCOND_FLG(%a6),&mda7_flg # was the <ea> mode -(sp)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) bne.b fu_unfl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) # the extended precision result is still in fp0. but, we need to save it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) # somewhere on the stack until we can copy it to its final resting place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) # (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 1758) # frame or it will get overwritten when the exc stack frame is shifted "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) fmovm.x &0x80,FP_SRC(%a6) # put answer on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) fmovm.x &0x40,FP_DST(%a6) # put EXOP on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) mov.w &0x30cc,EXC_VOFF(%a6) # vector offset = 0xcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) mov.w &0xe003,2+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) frestore FP_DST(%a6) # restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) mov.l (%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) # now, copy the result to the proper place on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) mov.l LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) mov.l LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) mov.l LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) add.l &LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) bra.l _real_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) # fmove in and out enter here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) fu_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) fmovm.x &0x40,FP_SRC(%a6) # save EXOP to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) mov.w &0x30c4,EXC_VOFF(%a6) # vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) mov.w &0xe001,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) frestore FP_SRC(%a6) # restore EXOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) bra.l _real_inex
^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) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) fu_in_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) # so, since the emulation routines re-create them anyways, zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) andi.l &0x0ff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) bsr.l get_packed # fetch packed src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) bsr.l set_tag_x # set src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) mov.b %d0,STAG(%a6) # save src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) # bit five of the fp extension word separates the monadic and dyadic operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) # at this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) beq.b fu_extract_p # monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) cmpi.b 1+EXC_CMDREG(%a6),&0x3a # is operation an ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) beq.b fu_extract_p # yes, so it's monadic, too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) bsr.l load_fpn2 # load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) lea FP_DST(%a6),%a0 # pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) bne.b fu_op2_done_p # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) fu_op2_done_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) mov.b %d0,DTAG(%a6) # save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) fu_extract_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) bfextu 1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) lea FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) mov.l (tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) jsr (tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) # BSUN : none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) # SNAN : all dyadic ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) # OPERR : fsqrt(-NORM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) # OVFL : all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) # UNFL : all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) # DZ : fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) # INEX2 : all except ftst,fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) # INEX1 : all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) # we determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) bne.w fu_in_ena_p # some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) fu_in_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) # fcmp and ftst do not store any result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) mov.b 1+EXC_CMDREG(%a6),%d0 # fetch extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) andi.b &0x38,%d0 # extract bits 3-5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) cmpi.b %d0,&0x38 # is instr fcmp or ftst?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) beq.b fu_in_exit_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) bsr.l store_fpreg # store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) fu_in_exit_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) btst &0x5,EXC_SR(%a6) # user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) bne.w fu_in_exit_s_p # supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) mov.l EXC_A7(%a6),%a0 # update user a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) fu_in_exit_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) unlk %a6 # unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) bne.w fu_trace_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) bra.l _fpsp_done # exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) # the exception occurred in supervisor mode. check to see if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) # addressing mode was (a7)+. if so, we'll need to shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) # stack frame "up".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) fu_in_exit_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) btst &mia7_bit,SPCOND_FLG(%a6) # was ea mode (a7)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) beq.b fu_in_exit_cont_p # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) unlk %a6 # unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) # shift the stack frame "up". we don't really care about the <ea> field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) mov.l 0x4(%sp),0x10(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) mov.l 0x0(%sp),0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) bne.w fu_trace_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) bra.l _fpsp_done # exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) fu_in_ena_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled & set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) bfffo %d0{&24:&8},%d0 # find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) bne.b fu_in_exc_p # at least one was set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) # No exceptions occurred that were also enabled. Now:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) # if (OVFL && ovfl_disabled && inexact_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) # branch to _real_inex() (even if the result was exact!);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) # } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) # save the result in the proper fp reg (unless the op is fcmp or ftst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) # return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) # }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) btst &ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) beq.w fu_in_cont_p # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) fu_in_ovflchk_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) btst &inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) beq.w fu_in_cont_p # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) bra.w fu_in_exc_ovfl_p # do _real_inex() now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) # An exception occurred and that exception was enabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) # shift enabled exception field into lo byte of d0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) # if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) # ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) # /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) # * this is the case where we must call _real_inex() now or else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) # * there will be no other way to pass it the exceptional operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) # */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) # call _real_inex();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) # } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) # restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) # }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) fu_in_exc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) subi.l &24,%d0 # fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) cmpi.b %d0,&0x6 # is exception INEX? (6 or 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) blt.b fu_in_exc_exit_p # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) # the enabled exception was inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) btst &unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) bne.w fu_in_exc_unfl_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) btst &ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) bne.w fu_in_exc_ovfl_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) # here, we insert the correct fsave status value into the fsave frame for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) # corresponding exception. the operand in the fsave frame should be the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) # src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) # as a reminder for future predicted pain and agony, we are passing in fsave the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) # "non-skewed" operand for cases of sgl and dbl src INFs,NANs, and DENORMs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) # this is INCORRECT for enabled SNAN which would give to the user the skewed SNAN!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) fu_in_exc_exit_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) btst &0x5,EXC_SR(%a6) # user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) bne.w fu_in_exc_exit_s_p # supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) mov.l EXC_A7(%a6),%a0 # update user a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) fu_in_exc_exit_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) mov.w (tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) frestore FP_SRC(%a6) # restore src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) btst &0x7,(%sp) # is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) bne.w fu_trace_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) tbl_except_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) short 0xe000,0xe006,0xe004,0xe005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) short 0xe003,0xe002,0xe001,0xe001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) fu_in_exc_ovfl_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) mov.w &0x3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) bra.w fu_in_exc_exit_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) fu_in_exc_unfl_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) mov.w &0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) bra.w fu_in_exc_exit_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) fu_in_exc_exit_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) btst &mia7_bit,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) beq.b fu_in_exc_exit_cont_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) mov.w (tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) frestore FP_SRC(%a6) # restore src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) unlk %a6 # unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) # shift stack frame "up". who cares about <ea> field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) mov.l 0x4(%sp),0x10(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) mov.l 0x0(%sp),0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) bne.b fu_trace_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) bra.l _fpsp_done # exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) # The opclass two PACKED instruction that took an "Unimplemented Data Type"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) # exception was being traced. Make the "current" PC the FPIAR and put it in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) # trace stack frame then jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) # UNSUPP FRAME TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) # * EA * * Current *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) # * * * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) # * 0x2 * 0x0dc * * 0x2 * 0x024 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) # * Next * * Next *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) # * PC * * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) # * SR * * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) fu_trace_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) mov.w &0x2024,0x6(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) fmov.l %fpiar,0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) bra.l _real_trace
^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) #########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) fu_out_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) # I'm not sure at this point what FPSR bits are valid for this instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) # so, since the emulation routines re-create them anyways, zero exception field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) # fmove out doesn't affect ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) and.l &0xffff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) bfextu EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) bsr.l load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) # unlike other opclass 3, unimplemented data type exceptions, packed must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) # able to detect all operand types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) bne.b fu_op2_p # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) fu_op2_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) mov.b %d0,STAG(%a6) # save src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) lea FP_SRC(%a6),%a0 # pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) mov.l (%a6),EXC_A6(%a6) # in case a6 changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) bsr.l fout # call fmove out routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) # BSUN : no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) # SNAN : yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) # OPERR : if ((k_factor > +17) || (dec. exp exceeds 3 digits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) # OVFL : no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) # UNFL : no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) # DZ : no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) # INEX2 : yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) # INEX1 : no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) # determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) bne.w fu_out_ena_p # some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) fu_out_exit_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) mov.l EXC_A6(%a6),(%a6) # restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) btst &0x5,EXC_SR(%a6) # user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) bne.b fu_out_exit_s_p # supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) mov.l EXC_A7(%a6),%a0 # update user a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) fu_out_exit_cont_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) unlk %a6 # unravel stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) bne.w fu_trace_p # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) bra.l _fpsp_done # exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) # the exception occurred in supervisor mode. check to see if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) # addressing mode was -(a7). if so, we'll need to shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) # stack frame "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) fu_out_exit_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) btst &mda7_bit,SPCOND_FLG(%a6) # was ea mode -(a7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) beq.b fu_out_exit_cont_p # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) mov.l (%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) # now, copy the result to the proper place on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) add.l &LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) btst &0x7,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) bne.w fu_trace_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) fu_out_ena_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) bfffo %d0{&24:&8},%d0 # find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) beq.w fu_out_exit_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) mov.l EXC_A6(%a6),(%a6) # restore a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) # an exception occurred and that exception was enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) # the only exception possible on packed move out are INEX, OPERR, and SNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) fu_out_exc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) cmpi.b %d0,&0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) bgt.w fu_inex_p2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) beq.w fu_operr_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) fu_snan_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) btst &0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) bne.b fu_snan_s_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) mov.l EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) bra.w fu_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) fu_snan_s_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) cmpi.b SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) bne.w fu_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) # the strategy is to move the exception frame "down" 12 bytes. then, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) # can store the default result where the exception frame was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) mov.w &0x30d8,EXC_VOFF(%a6) # vector offset = 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) mov.w &0xe006,2+FP_SRC(%a6) # set fsave status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) frestore FP_SRC(%a6) # restore src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) mov.l (%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) # now, we copy the default result to its proper location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) add.l &LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) bra.l _real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) fu_operr_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) btst &0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) bne.w fu_operr_p_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) mov.l EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) bra.w fu_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) fu_operr_p_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) cmpi.b SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) bne.w fu_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) # the strategy is to move the exception frame "down" 12 bytes. then, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) # can store the default result where the exception frame was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) mov.w &0x30d0,EXC_VOFF(%a6) # vector offset = 0xd0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) mov.w &0xe004,2+FP_SRC(%a6) # set fsave status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) frestore FP_SRC(%a6) # restore src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) mov.l (%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) # now, we copy the default result to its proper location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) add.l &LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) bra.l _real_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) fu_inex_p2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) btst &0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) bne.w fu_inex_s_p2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) mov.l EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) bra.w fu_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) fu_inex_s_p2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) cmpi.b SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) bne.w fu_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) # the instruction was "fmove.p fpn,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) # the strategy is to move the exception frame "down" 12 bytes. then, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) # can store the default result where the exception frame was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) mov.w &0x30c4,EXC_VOFF(%a6) # vector offset = 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) mov.w &0xe001,2+FP_SRC(%a6) # set fsave status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) frestore FP_SRC(%a6) # restore src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) mov.l (%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) # now, we copy the default result to its proper location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) add.l &LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) bra.l _real_inex
^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) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) # if we're stuffing a source operand back into an fsave frame then we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) # have to make sure that for single or double source operands that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) # format stuffed is as weird as the hardware usually makes it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) global funimp_skew
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) funimp_skew:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) bfextu EXC_EXTWORD(%a6){&3:&3},%d0 # extract src specifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) cmpi.b %d0,&0x1 # was src sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) beq.b funimp_skew_sgl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) cmpi.b %d0,&0x5 # was src dbl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) beq.b funimp_skew_dbl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) funimp_skew_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) mov.w FP_SRC_EX(%a6),%d0 # fetch DENORM exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) andi.w &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) beq.b funimp_skew_sgl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) cmpi.w %d0,&0x3f80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) bgt.b funimp_skew_sgl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) neg.w %d0 # make exponent negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) addi.w &0x3f81,%d0 # find amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) mov.l FP_SRC_HI(%a6),%d1 # fetch DENORM hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) lsr.l %d0,%d1 # shift it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) bset &31,%d1 # set j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) mov.l %d1,FP_SRC_HI(%a6) # insert new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) andi.w &0x8000,FP_SRC_EX(%a6) # clear old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) ori.w &0x3f80,FP_SRC_EX(%a6) # insert new "skewed" exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) funimp_skew_sgl_not:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) funimp_skew_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) mov.w FP_SRC_EX(%a6),%d0 # fetch DENORM exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) andi.w &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) beq.b funimp_skew_dbl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) cmpi.w %d0,&0x3c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) bgt.b funimp_skew_dbl_not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) tst.b FP_SRC_EX(%a6) # make "internal format"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) smi.b 0x2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) mov.w %d0,FP_SRC_EX(%a6) # insert exponent with cleared sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) clr.l %d0 # clear g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) lea FP_SRC(%a6),%a0 # pass ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) mov.w &0x3c01,%d1 # pass denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) bsr.l dnrm_lp # denorm it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) mov.w &0x3c00,%d0 # new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) tst.b 0x2+FP_SRC(%a6) # is sign set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) beq.b fss_dbl_denorm_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) bset &15,%d0 # set sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) fss_dbl_denorm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) bset &0x7,FP_SRC_HI(%a6) # set j-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) mov.w %d0,FP_SRC_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) funimp_skew_dbl_not:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) global _mem_write2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) _mem_write2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) btst &0x5,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) beq.l _dmem_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) mov.l 0x0(%a0),FP_DST_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) mov.l 0x4(%a0),FP_DST_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) mov.l 0x8(%a0),FP_DST_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) clr.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) # _fpsp_effadd(): 060FPSP entry point for FP "Unimplemented #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) # effective address" exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) # FP Unimplemented Effective Address exception in an operating #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) # system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) # _imem_read_long() - read instruction longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) # fix_skewed_ops() - adjust src operand in fsave frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) # set_tag_x() - determine optype of src/dst operands #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) # store_fpreg() - store opclass 0 or 2 result to FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) # unnorm_fix() - change UNNORM operands to NORM or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) # load_fpn2() - load dst operand from FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) # tbl_unsupp - add of table of emulation routines for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) # decbin() - convert packed data to FP binary data #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) # _real_fpu_disabled() - "callout" for "FPU disabled" exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) # _real_access() - "callout" for access error exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) # _mem_read() - read extended immediate operand from memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) # _fpsp_done() - "callout" for exit; work all done #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) # _real_trace() - "callout" for Trace enabled exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) # fmovm_dynamic() - emulate dynamic fmovm instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) # fmovm_ctrl() - emulate fmovm control instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) # - The system stack contains the "Unimplemented <ea>" stk frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) # If access error: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) # - The system stack is changed to an access error stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) # If FPU disabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) # - The system stack is changed to an FPU disabled stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) # If Trace exception enabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) # - The system stack is changed to a Trace exception stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) # Else: (normal case) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) # - None (correct result has been stored as appropriate) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) # This exception handles 3 types of operations: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) # (1) FP Instructions using extended precision or packed immediate #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) # addressing mode. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) # (2) The "fmovm.x" instruction w/ dynamic register specification. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) # (3) The "fmovm.l" instruction w/ 2 or 3 control registers. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) # For immediate data operations, the data is read in w/ a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) # _mem_read() "callout", converted to FP binary (if packed), and used #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) # as the source operand to the instruction specified by the instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) # word. If no FP exception should be reported ads a result of the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) # emulation, then the result is stored to the destination register and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) # the handler exits through _fpsp_done(). If an enabled exc has been #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) # signalled as a result of emulation, then an fsave state frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) # corresponding to the FP exception type must be entered into the 060 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) # FPU before exiting. In either the enabled or disabled cases, we #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) # must also check if a Trace exception is pending, in which case, we #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) # must create a Trace exception stack frame from the current exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) # stack frame. If no Trace is pending, we simply exit through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) # _fpsp_done(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) # For "fmovm.x", call the routine fmovm_dynamic() which will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) # decode and emulate the instruction. No FP exceptions can be pending #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) # as a result of this operation emulation. A Trace exception can be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) # pending, though, which means the current stack frame must be changed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) # to a Trace stack frame and an exit made through _real_trace(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) # For the case of "fmovm.x Dn,-(a7)", where the offending instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) # was executed from supervisor mode, this handler must store the FP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) # register file values to the system stack by itself since #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) # fmovm_dynamic() can't handle this. A normal exit is made through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) # fpsp_done(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) # For "fmovm.l", fmovm_ctrl() is used to emulate the instruction. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) # Again, a Trace exception may be pending and an exit made through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) # _real_trace(). Else, a normal exit is made through _fpsp_done(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) # Before any of the above is attempted, it must be checked to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) # see if the FPU is disabled. Since the "Unimp <ea>" exception is taken #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) # before the "FPU disabled" exception, but the "FPU disabled" exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) # has higher priority, we check the disabled bit in the PCR. If set, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) # then we must create an 8 word "FPU disabled" exception stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) # from the current 4 word exception stack frame. This includes #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) # reproducing the effective address of the instruction to put on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) # new stack frame. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) # In the process of all emulation work, if a _mem_read() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) # "callout" returns a failing result indicating an access error, then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) # we must create an access error stack frame from the current stack #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) # frame. This information includes a faulting address and a fault- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) # status-longword. These are created within this handler. #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) global _fpsp_effadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) _fpsp_effadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) # This exception type takes priority over the "Line F Emulator"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) # exception. Therefore, the FPU could be disabled when entering here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) # So, we must check to see if it's disabled and handle that case separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) movc %pcr,%d0 # load proc cr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) btst &0x1,%d0 # is FPU disabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) bne.w iea_disabled # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) link %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) # PC of instruction that took the exception is the PC in the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) mov.l EXC_PC(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) mov.l %d0,EXC_OPWORD(%a6) # store OPWORD and EXTWORD
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) tst.w %d0 # is operation fmovem?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) bmi.w iea_fmovm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) # here, we will have:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) # fabs fdabs fsabs facos fmod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) # fadd fdadd fsadd fasin frem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) # fcmp fatan fscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) # fdiv fddiv fsdiv fatanh fsin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) # fint fcos fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) # fintrz fcosh fsinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) # fmove fdmove fsmove fetox ftan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) # fmul fdmul fsmul fetoxm1 ftanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) # fneg fdneg fsneg fgetexp ftentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) # fsgldiv fgetman ftwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) # fsglmul flog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) # fsqrt flog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) # fsub fdsub fssub flogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) # ftst flognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) # which can all use f<op>.{x,p}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) # so, now it's immediate data extended precision AND PACKED FORMAT!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) iea_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) btst &0xa,%d0 # is src fmt x or p?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) bne.b iea_op_pack # packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) mov.l EXC_EXTWPTR(%a6),%a0 # pass: ptr to #<data>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) lea FP_SRC(%a6),%a1 # pass: ptr to super addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) mov.l &0xc,%d0 # pass: 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) bsr.l _imem_read # read extended immediate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) bne.w iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) bra.b iea_op_setsrc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) iea_op_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) mov.l EXC_EXTWPTR(%a6),%a0 # pass: ptr to #<data>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) lea FP_SRC(%a6),%a1 # pass: ptr to super dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) mov.l &0xc,%d0 # pass: 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) bsr.l _imem_read # read packed operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) bne.w iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) # 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 2530) bfextu FP_SRC(%a6){&1:&15},%d0 # get exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) cmpi.w %d0,&0x7fff # INF or NAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) beq.b iea_op_setsrc # operand is an INF or NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) # The packed operand is a zero if the mantissa is all zero, else it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) # a normal packed op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) mov.b 3+FP_SRC(%a6),%d0 # get byte 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) andi.b &0x0f,%d0 # clear all but last nybble
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) bne.b iea_op_gp_not_spec # not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) tst.l FP_SRC_HI(%a6) # is lw 2 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) bne.b iea_op_gp_not_spec # not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) tst.l FP_SRC_LO(%a6) # is lw 3 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) beq.b iea_op_setsrc # operand is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) iea_op_gp_not_spec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) lea FP_SRC(%a6),%a0 # pass: ptr to packed op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) bsr.l decbin # convert to extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) fmovm.x &0x80,FP_SRC(%a6) # make this the srcop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) iea_op_setsrc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) addi.l &0xc,EXC_EXTWPTR(%a6) # update extension word pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) # FP_SRC now holds the src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) mov.b %d0,STAG(%a6) # could be ANYTHING!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) bne.b iea_op_getdst # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) bsr.l unnorm_fix # yes; convert to NORM/DENORM/ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) mov.b %d0,STAG(%a6) # set new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) iea_op_getdst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) clr.b STORE_FLG(%a6) # clear "store result" boolean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) beq.b iea_op_extract # monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) btst &0x4,1+EXC_CMDREG(%a6) # is operation fsincos,ftst,fcmp?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) bne.b iea_op_spec # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) iea_op_loaddst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) bsr.l load_fpn2 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) lea FP_DST(%a6),%a0 # pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) mov.b %d0,DTAG(%a6) # could be ANYTHING!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) bne.b iea_op_extract # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) bsr.l unnorm_fix # yes; convert to NORM/DENORM/ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) mov.b %d0,DTAG(%a6) # set new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) bra.b iea_op_extract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) # the operation is fsincos, ftst, or fcmp. only fcmp is dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) iea_op_spec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) btst &0x3,1+EXC_CMDREG(%a6) # is operation fsincos?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) beq.b iea_op_extract # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) # 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 2585) # store a result. then, only fcmp will branch back and pick up a dst operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) st STORE_FLG(%a6) # don't store a final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) btst &0x1,1+EXC_CMDREG(%a6) # is operation fcmp?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) beq.b iea_op_loaddst # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) iea_op_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) mov.b FPCR_MODE(%a6),%d0 # pass: rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) mov.b 1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) andi.w &0x007f,%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) fmov.l &0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) lea FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) jsr (tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) # Exceptions in order of precedence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) # BSUN : none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) # SNAN : all operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) # OPERR : all reg-reg or mem-reg operations that can normally operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) # OVFL : same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) # UNFL : same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) # DZ : same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) # INEX2 : same as OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) # INEX1 : all packed immediate operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) # we determine the highest priority exception(if any) set by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) # emulation routine that has also been enabled by the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) bne.b iea_op_ena # some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) # now, we save the result, unless, of course, the operation was ftst or fcmp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) # these don't save results.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) iea_op_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) tst.b STORE_FLG(%a6) # does this op store a result?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) bne.b iea_op_exit1 # exit with no frestore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) iea_op_store:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) bsr.l store_fpreg # store the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) iea_op_exit1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) mov.l EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) mov.l EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) unlk %a6 # unravel the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) bne.w iea_op_trace # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) bra.l _fpsp_done # exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) iea_op_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enable and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) bfffo %d0{&24:&8},%d0 # find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) bne.b iea_op_exc # at least one was set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) # no exception occurred. now, did a disabled, exact overflow occur with inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) # enabled? if so, then we have to stuff an overflow frame into the FPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) beq.b iea_op_save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) iea_op_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) beq.b iea_op_store # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) bra.b iea_op_exc_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) # an enabled exception occurred. we have to insert the exception type back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) # the machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) iea_op_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) subi.l &24,%d0 # fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) cmpi.b %d0,&0x6 # is exception INEX?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) bne.b iea_op_exc_force # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) # the enabled exception was inexact. so, if it occurs with an overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) # or underflow that was disabled, then we have to force an overflow or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) # underflow frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) bne.b iea_op_exc_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) btst &unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) bne.b iea_op_exc_unfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) iea_op_exc_force:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) mov.w (tbl_iea_except.b,%pc,%d0.w*2),2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) bra.b iea_op_exit2 # exit with frestore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) tbl_iea_except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) short 0xe002, 0xe006, 0xe004, 0xe005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) short 0xe003, 0xe002, 0xe001, 0xe001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) iea_op_exc_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) mov.w &0xe005,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) bra.b iea_op_exit2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) iea_op_exc_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) mov.w &0xe003,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) iea_op_exit2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) mov.l EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) mov.l EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) frestore FP_SRC(%a6) # restore exceptional state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) unlk %a6 # unravel the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) bne.b iea_op_trace # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) bra.l _fpsp_done # exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) # The opclass two instruction that took an "Unimplemented Effective Address"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) # exception was being traced. Make the "current" PC the FPIAR and put it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) # the trace stack frame then jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) # UNIMP EA FRAME TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) # * 0x0 * 0x0f0 * * Current *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) # ***************** * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) # * Current * *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) # * PC * * 0x2 * 0x024 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) # * SR * * Next *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) # ***************** * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) # * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) iea_op_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) mov.l (%sp),-(%sp) # shift stack frame "down"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) mov.w 0x8(%sp),0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) fmov.l %fpiar,0x8(%sp) # "Current PC" is in FPIAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) iea_fmovm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) btst &14,%d0 # ctrl or data reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) beq.w iea_fmovm_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) iea_fmovm_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) btst &0x5,EXC_SR(%a6) # user or supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) bne.b iea_fmovm_data_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) iea_fmovm_data_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) mov.l %usp,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) mov.l %a0,EXC_A7(%a6) # store current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) bsr.l fmovm_dynamic # do dynamic fmovm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) mov.l EXC_A7(%a6),%a0 # load possibly new a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) mov.l %a0,%usp # update usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) bra.w iea_fmovm_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) iea_fmovm_data_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) clr.b SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) lea 0x2+EXC_VOFF(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) mov.l %a0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) bsr.l fmovm_dynamic # do dynamic fmovm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) cmpi.b SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) beq.w iea_fmovm_data_predec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) cmpi.b SPCOND_FLG(%a6),&mia7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) bne.w iea_fmovm_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) # right now, d0 = the size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) # the data has been fetched from the supervisor stack, but we have not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) # incremented the stack pointer by the appropriate number of bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) # do it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) iea_fmovm_data_postinc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) btst &0x7,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) bne.b iea_fmovm_data_pi_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) mov.w EXC_SR(%a6),(EXC_SR,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) mov.l EXC_EXTWPTR(%a6),(EXC_PC,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) mov.w &0x00f0,(EXC_VOFF,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) lea (EXC_SR,%a6,%d0),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) mov.l %a0,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) mov.l (%sp)+,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) iea_fmovm_data_pi_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) mov.w EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) mov.l EXC_EXTWPTR(%a6),(EXC_PC-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) mov.w &0x2024,(EXC_VOFF-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) mov.l EXC_PC(%a6),(EXC_VOFF+0x2-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) lea (EXC_SR-0x4,%a6,%d0),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) mov.l %a0,EXC_SR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) mov.l (%sp)+,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) # right now, d1 = size and d0 = the strg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) iea_fmovm_data_predec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) mov.b %d1,EXC_VOFF(%a6) # store strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) mov.b %d0,0x1+EXC_VOFF(%a6) # store size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) mov.l (%a6),-(%sp) # make a copy of a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) mov.l %d1,-(%sp) # save d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) mov.l EXC_EXTWPTR(%a6),-(%sp) # make a copy of Next PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) mov.b 0x1+EXC_VOFF(%a6),%d0 # fetch size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) neg.l %d0 # get negative of size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) btst &0x7,EXC_SR(%a6) # is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) beq.b iea_fmovm_data_p2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) mov.w EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) mov.l EXC_PC(%a6),(EXC_VOFF-0x2,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) mov.l (%sp)+,(EXC_PC-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) mov.w &0x2024,(EXC_VOFF-0x4,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) pea (%a6,%d0) # create final sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) bra.b iea_fmovm_data_p3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) iea_fmovm_data_p2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) mov.w EXC_SR(%a6),(EXC_SR,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) mov.l (%sp)+,(EXC_PC,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) mov.w &0x00f0,(EXC_VOFF,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) pea (0x4,%a6,%d0) # create final sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) iea_fmovm_data_p3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) clr.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) mov.b EXC_VOFF(%a6),%d1 # fetch strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) bpl.b fm_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) fmovm.x &0x80,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) addi.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) fm_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) lsl.b &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) bpl.b fm_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) fmovm.x &0x40,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) addi.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) fm_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) lsl.b &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) bpl.b fm_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) fmovm.x &0x20,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) addi.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) fm_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) lsl.b &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) bpl.b fm_4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) fmovm.x &0x10,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) addi.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) fm_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) lsl.b &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) bpl.b fm_5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) fmovm.x &0x08,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) addi.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) fm_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) lsl.b &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) bpl.b fm_6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) fmovm.x &0x04,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) addi.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) fm_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) lsl.b &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) bpl.b fm_7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) fmovm.x &0x02,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) addi.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) fm_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) lsl.b &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) bpl.b fm_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) fmovm.x &0x01,(0x4+0x8,%a6,%d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) fm_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) mov.l 0x4(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) mov.l 0x8(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) mov.l 0xc(%sp),%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) mov.l (%sp)+,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) btst &0x7,(%sp) # is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) beq.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) iea_fmovm_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) bsr.l fmovm_ctrl # load ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) iea_fmovm_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) btst &0x7,EXC_SR(%a6) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) bne.b iea_fmovm_trace # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) mov.l EXC_EXTWPTR(%a6),EXC_PC(%a6) # set Next PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) unlk %a6 # unravel the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) bra.l _fpsp_done # exit to os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) # The control reg instruction that took an "Unimplemented Effective Address"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) # exception was being traced. The "Current PC" for the trace frame is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) # PC stacked for Unimp EA. The "Next PC" is in EXC_EXTWPTR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) # After fixing the stack frame, jump to _real_trace().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) # UNIMP EA FRAME TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) # * 0x0 * 0x0f0 * * Current *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) # ***************** * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) # * Current * *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) # * PC * * 0x2 * 0x024 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) # * SR * * Next *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) # ***************** * PC *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) # * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) # this ain't a pretty solution, but it works:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) # -restore a6 (not with unlk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) # -shift stack frame down over where old a6 used to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) # -add LOCAL_SIZE to stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) iea_fmovm_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) mov.l (%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) mov.w EXC_SR+LOCAL_SIZE(%sp),0x0+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) mov.l EXC_PC+LOCAL_SIZE(%sp),0x8+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) mov.l EXC_EXTWPTR+LOCAL_SIZE(%sp),0x2+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) mov.w &0x2024,0x6+LOCAL_SIZE(%sp) # stk fmt = 0x2; voff = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) add.l &LOCAL_SIZE,%sp # clear stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) # The FPU is disabled and so we should really have taken the "Line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) # F Emulator" exception. So, here we create an 8-word stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) # from our 4-word stack frame. This means we must calculate the length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) # the faulting instruction to get the "next PC". This is trivial for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) # immediate operands but requires some extra work for fmovm dynamic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) # which can use most addressing modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) iea_disabled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) link %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) # PC of instruction that took the exception is the PC in the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) mov.l EXC_PC(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) mov.l %d0,EXC_OPWORD(%a6) # store OPWORD and EXTWORD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) tst.w %d0 # is instr fmovm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) bmi.b iea_dis_fmovm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) # instruction is using an extended precision immediate operand. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) # the total instruction length is 16 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) iea_dis_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) mov.l &0x10,%d0 # 16 bytes of instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) bra.b iea_dis_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) iea_dis_fmovm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) btst &0xe,%d0 # is instr fmovm ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) bne.b iea_dis_fmovm_data # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) # the instruction is a fmovm.l with 2 or 3 registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) bfextu %d0{&19:&3},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) mov.l &0xc,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) cmpi.b %d1,&0x7 # move all regs?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) bne.b iea_dis_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) addq.l &0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) bra.b iea_dis_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) # the instruction is an fmovm.x dynamic which can use many addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) # modes and thus can have several different total instruction lengths.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) # call fmovm_calc_ea which will go through the ea calc process and,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) # as a by-product, will tell us how long the instruction is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) iea_dis_fmovm_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) bsr.l fmovm_calc_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) mov.l EXC_EXTWPTR(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) sub.l EXC_PC(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) iea_dis_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) mov.w %d0,EXC_VOFF(%a6) # store stack shift value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) # here, we actually create the 8-word frame from the 4-word frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) # with the "next PC" as additional info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) # the <ea> field is let as undefined.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) subq.l &0x8,%sp # make room for new stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) mov.w 0xc(%sp),0x4(%sp) # move SR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) mov.l 0xe(%sp),0x6(%sp) # move Current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) mov.w 0x12(%sp),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) mov.l 0x6(%sp),0x10(%sp) # move Current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) add.l %d0,0x6(%sp) # make Next PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) mov.w &0x402c,0xa(%sp) # insert offset,frame format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) bra.l _real_fpu_disabled
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) iea_iacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) movc %pcr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) btst &0x1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) bne.b iea_iacc_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) iea_iacc_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) subq.w &0x8,%sp # make stack frame bigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) mov.l 0x8(%sp),(%sp) # store SR,hi(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) mov.w 0xc(%sp),0x4(%sp) # store lo(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) mov.w &0x4008,0x6(%sp) # store voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) mov.l 0x2(%sp),0x8(%sp) # store ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) mov.l &0x09428001,0xc(%sp) # store fslw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) iea_acc_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) btst &0x5,(%sp) # user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) beq.b iea_acc_done2 # user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) bset &0x2,0xd(%sp) # set supervisor TM bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) iea_acc_done2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) bra.l _real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) iea_dacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) lea -LOCAL_SIZE(%a6),%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) movc %pcr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) btst &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) bne.b iea_dacc_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) fmovm.l LOCAL_SIZE+USER_FPCR(%sp),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) iea_dacc_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) mov.l (%a6),%a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) mov.l 0x4+LOCAL_SIZE(%sp),-0x8+0x4+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) mov.w 0x8+LOCAL_SIZE(%sp),-0x8+0x8+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) mov.w &0x4008,-0x8+0xa+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) mov.l %a0,-0x8+0xc+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) mov.w %d0,-0x8+0x10+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) mov.w &0x0001,-0x8+0x12+LOCAL_SIZE(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) movm.l LOCAL_SIZE+EXC_DREGS(%sp),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) add.w &LOCAL_SIZE-0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) bra.b iea_acc_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) # _fpsp_operr(): 060FPSP entry point for FP Operr exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) # FP Operand Error exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) # _imem_read_long() - read instruction longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) # fix_skewed_ops() - adjust src operand in fsave frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) # _real_operr() - "callout" to operating system operr handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) # _dmem_write_{byte,word,long}() - store data to mem (opclass 3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) # store_dreg_{b,w,l}() - store data to data regfile (opclass 3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) # facc_out_{b,w,l}() - store to memory took access error (opcl 3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) # - The system stack contains the FP Operr exception frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) # - The fsave frame contains the source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) # No access error: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) # - The fsave frame contains the adjusted src op for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) # In a system where the FP Operr exception is enabled, the goal #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) # is to get to the handler specified at _real_operr(). But, on the 060, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) # for opclass zero and two instruction taking this exception, the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) # input operand in the fsave frame may be incorrect for some cases #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) # and needs to be corrected. This handler calls fix_skewed_ops() to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) # do just this and then exits through _real_operr(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) # For opclass 3 instructions, the 060 doesn't store the default #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) # operr result out to memory or data register file as it should. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) # This code must emulate the move out before finally exiting through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) # _real_inex(). The move out, if to memory, is performed using #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) # _mem_write() "callout" routines that may return a failing result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) # In this special case, the handler must exit through facc_out() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) # which creates an access error stack frame from the current operr #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) # stack frame. #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) global _fpsp_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) _fpsp_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) fsave FP_SRC(%a6) # grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) mov.l %d0,EXC_OPWORD(%a6)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) btst &13,%d0 # is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) bne.b foperr_out # fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) # here, we simply see if the operand in the fsave frame needs to be "unskewed".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) # this would be the case for opclass two operations with a source infinity or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) # denorm operand in the sgl or dbl format. NANs also become skewed, but can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) # cause an operr so we don't need to check for them here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) bsr.l fix_skewed_ops # fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) foperr_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) frestore FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) bra.l _real_operr
^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) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) # the hardware does not save the default result to memory on enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) # operand error exceptions. we do this here before passing control to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) # the user operand error handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) # byte, word, and long destination format operations can pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) # through here. we simply need to test the sign of the src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) # operand and save the appropriate minimum or maximum integer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) # to the effective address as pointed to by the stacked effective address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) # although packed opclass three operations can take operand error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) # exceptions, they won't pass through here since they are caught
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) # first by the unsupported data format exception handler. that handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) # sends them directly to _real_operr() if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) foperr_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) mov.w FP_SRC_EX(%a6),%d1 # fetch exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) cmpi.w %d1,&0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) bne.b foperr_out_not_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) # the operand is either an infinity or a QNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) tst.l FP_SRC_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) bne.b foperr_out_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) mov.l FP_SRC_HI(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) andi.l &0x7fffffff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) beq.b foperr_out_not_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) foperr_out_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) mov.l FP_SRC_HI(%a6),L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) bra.b foperr_out_jmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) foperr_out_not_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) mov.l &0x7fffffff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) tst.b FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) bpl.b foperr_out_not_qnan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) addq.l &0x1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) foperr_out_not_qnan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) mov.l %d1,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) foperr_out_jmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) bfextu %d0{&19:&3},%d0 # extract dst format field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) mov.b 1+EXC_OPWORD(%a6),%d1 # extract <ea> mode,reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) mov.w (tbl_operr.b,%pc,%d0.w*2),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) jmp (tbl_operr.b,%pc,%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) tbl_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) short foperr_out_l - tbl_operr # long word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) short tbl_operr - tbl_operr # sgl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) short tbl_operr - tbl_operr # ext prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) short foperr_exit - tbl_operr # packed won't enter here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) short foperr_out_w - tbl_operr # word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) short tbl_operr - tbl_operr # dbl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) short foperr_out_b - tbl_operr # byte integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) short tbl_operr - tbl_operr # packed won't enter here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) foperr_out_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) mov.b L_SCR1(%a6),%d0 # load positive default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) cmpi.b %d1,&0x7 # is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) ble.b foperr_out_b_save_dn # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) bsr.l _dmem_write_byte # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) bne.l facc_out_b # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) bra.w foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) foperr_out_b_save_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) andi.w &0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) bsr.l store_dreg_b # store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) bra.w foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) foperr_out_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) mov.w L_SCR1(%a6),%d0 # load positive default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) cmpi.b %d1,&0x7 # is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) ble.b foperr_out_w_save_dn # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) bsr.l _dmem_write_word # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) bne.l facc_out_w # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) bra.w foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) foperr_out_w_save_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) andi.w &0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) bsr.l store_dreg_w # store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) bra.w foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) foperr_out_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) mov.l L_SCR1(%a6),%d0 # load positive default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) cmpi.b %d1,&0x7 # is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) ble.b foperr_out_l_save_dn # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) bsr.l _dmem_write_long # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) bne.l facc_out_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) bra.w foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) foperr_out_l_save_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) andi.w &0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) bsr.l store_dreg_l # store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) bra.w foperr_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) # _fpsp_snan(): 060FPSP entry point for FP SNAN exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) # FP Signalling NAN exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) # _imem_read_long() - read instruction longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) # fix_skewed_ops() - adjust src operand in fsave frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) # _real_snan() - "callout" to operating system SNAN handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) # _dmem_write_{byte,word,long}() - store data to mem (opclass 3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) # store_dreg_{b,w,l}() - store data to data regfile (opclass 3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) # facc_out_{b,w,l,d,x}() - store to mem took acc error (opcl 3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) # _calc_ea_fout() - fix An if <ea> is -() or ()+; also get <ea> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) # - The system stack contains the FP SNAN exception frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) # - The fsave frame contains the source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) # No access error: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) # - The fsave frame contains the adjusted src op for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) # In a system where the FP SNAN exception is enabled, the goal #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) # is to get to the handler specified at _real_snan(). But, on the 060, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) # for opclass zero and two instructions taking this exception, the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) # input operand in the fsave frame may be incorrect for some cases #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) # and needs to be corrected. This handler calls fix_skewed_ops() to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) # do just this and then exits through _real_snan(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) # For opclass 3 instructions, the 060 doesn't store the default #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) # SNAN result out to memory or data register file as it should. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) # This code must emulate the move out before finally exiting through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) # _real_snan(). The move out, if to memory, is performed using #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) # _mem_write() "callout" routines that may return a failing result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) # In this special case, the handler must exit through facc_out() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) # which creates an access error stack frame from the current SNAN #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) # stack frame. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) # For the case of an extended precision opclass 3 instruction, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) # if the effective addressing mode was -() or ()+, then the address #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) # register must get updated by calling _calc_ea_fout(). If the <ea> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) # was -(a7) from supervisor mode, then the exception frame currently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) # on the system stack must be carefully moved "down" to make room #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) # for the operand being moved. #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) global _fpsp_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) _fpsp_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) fsave FP_SRC(%a6) # grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) mov.l %d0,EXC_OPWORD(%a6)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) btst &13,%d0 # is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) bne.w fsnan_out # fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) # here, we simply see if the operand in the fsave frame needs to be "unskewed".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) # this would be the case for opclass two operations with a source infinity or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) # denorm operand in the sgl or dbl format. NANs also become skewed and must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) # fixed here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) bsr.l fix_skewed_ops # fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) fsnan_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) frestore FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) bra.l _real_snan
^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) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) # the hardware does not save the default result to memory on enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) # snan exceptions. we do this here before passing control to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) # the user snan handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) # byte, word, long, and packed destination format operations can pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) # through here. since packed format operations already were handled by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) # fpsp_unsupp(), then we need to do nothing else for them here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) # for byte, word, and long, we simply need to test the sign of the src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) # operand and save the appropriate minimum or maximum integer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) # to the effective address as pointed to by the stacked effective address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) fsnan_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) bfextu %d0{&19:&3},%d0 # extract dst format field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) mov.b 1+EXC_OPWORD(%a6),%d1 # extract <ea> mode,reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) mov.w (tbl_snan.b,%pc,%d0.w*2),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) jmp (tbl_snan.b,%pc,%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) tbl_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) short fsnan_out_l - tbl_snan # long word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) short fsnan_out_s - tbl_snan # sgl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) short fsnan_out_x - tbl_snan # ext prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) short tbl_snan - tbl_snan # packed needs no help
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) short fsnan_out_w - tbl_snan # word integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) short fsnan_out_d - tbl_snan # dbl prec shouldn't happen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) short fsnan_out_b - tbl_snan # byte integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) short tbl_snan - tbl_snan # packed needs no help
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) fsnan_out_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) mov.b FP_SRC_HI(%a6),%d0 # load upper byte of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) bset &6,%d0 # set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) cmpi.b %d1,&0x7 # is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) ble.b fsnan_out_b_dn # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) bsr.l _dmem_write_byte # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) bne.l facc_out_b # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) fsnan_out_b_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) andi.w &0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) bsr.l store_dreg_b # store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) fsnan_out_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) mov.w FP_SRC_HI(%a6),%d0 # load upper word of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) bset &14,%d0 # set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) cmpi.b %d1,&0x7 # is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) ble.b fsnan_out_w_dn # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) bsr.l _dmem_write_word # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) bne.l facc_out_w # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) fsnan_out_w_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) andi.w &0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) bsr.l store_dreg_w # store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) fsnan_out_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) mov.l FP_SRC_HI(%a6),%d0 # load upper longword of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) bset &30,%d0 # set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) cmpi.b %d1,&0x7 # is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) ble.b fsnan_out_l_dn # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) bsr.l _dmem_write_long # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) bne.l facc_out_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) fsnan_out_l_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) andi.w &0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) bsr.l store_dreg_l # store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) fsnan_out_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) cmpi.b %d1,&0x7 # is <ea> mode a data reg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) ble.b fsnan_out_d_dn # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) mov.l FP_SRC_EX(%a6),%d0 # fetch SNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) andi.l &0x80000000,%d0 # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) ori.l &0x7fc00000,%d0 # insert new exponent,SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) mov.l FP_SRC_HI(%a6),%d1 # load mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) lsr.l &0x8,%d1 # shift mantissa for sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) or.l %d1,%d0 # create sgl SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) bsr.l _dmem_write_long # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) bne.l facc_out_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) fsnan_out_d_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) mov.l FP_SRC_EX(%a6),%d0 # fetch SNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) andi.l &0x80000000,%d0 # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) ori.l &0x7fc00000,%d0 # insert new exponent,SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) mov.l %d1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) mov.l FP_SRC_HI(%a6),%d1 # load mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) lsr.l &0x8,%d1 # shift mantissa for sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) or.l %d1,%d0 # create sgl SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) mov.l (%sp)+,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) andi.w &0x0007,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) bsr.l store_dreg_l # store result to regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) fsnan_out_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) mov.l FP_SRC_EX(%a6),%d0 # fetch SNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) andi.l &0x80000000,%d0 # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) ori.l &0x7ff80000,%d0 # insert new exponent,SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) mov.l FP_SRC_HI(%a6),%d1 # load hi mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) mov.l %d0,FP_SCR0_EX(%a6) # store to temp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) mov.l &11,%d0 # load shift amt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) lsr.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) or.l %d1,FP_SCR0_EX(%a6) # create dbl hi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) mov.l FP_SRC_HI(%a6),%d1 # load hi mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) andi.l &0x000007ff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) ror.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) mov.l %d1,FP_SCR0_HI(%a6) # store to temp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) mov.l FP_SRC_LO(%a6),%d1 # load lo mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) lsr.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) or.l %d1,FP_SCR0_HI(%a6) # create dbl lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) lea FP_SCR0(%a6),%a0 # pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) mov.l EXC_EA(%a6),%a1 # pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) movq.l &0x8,%d0 # pass: size of 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) bsr.l _dmem_write # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) bne.l facc_out_d # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) # for extended precision, if the addressing mode is pre-decrement or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) # post-increment, then the address register did not get updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) # in addition, for pre-decrement, the stacked <ea> is incorrect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) fsnan_out_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) clr.b SPCOND_FLG(%a6) # clear special case flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) mov.w FP_SRC_EX(%a6),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) clr.w 2+FP_SCR0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) mov.l FP_SRC_HI(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) bset &30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) mov.l %d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) mov.l FP_SRC_LO(%a6),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) btst &0x5,EXC_SR(%a6) # supervisor mode exception?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) bne.b fsnan_out_x_s # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) mov.l %usp,%a0 # fetch user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) mov.l %a0,EXC_A7(%a6) # save on stack for calc_ea()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) mov.l (%a6),EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) bsr.l _calc_ea_fout # find the correct ea,update An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) mov.l %a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) mov.l %a0,EXC_EA(%a6) # stack correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) mov.l EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) mov.l %a0,%usp # restore user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) mov.l EXC_A6(%a6),(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) fsnan_out_x_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) lea FP_SCR0(%a6),%a0 # pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) movq.l &0xc,%d0 # pass: size of extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) bsr.l _dmem_write # write the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) bne.l facc_out_x # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) bra.w fsnan_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) fsnan_out_x_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) mov.l (%a6),EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) bsr.l _calc_ea_fout # find the correct ea,update An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) mov.l %a0,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) mov.l %a0,EXC_EA(%a6) # stack correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) mov.l EXC_A6(%a6),(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) cmpi.b SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) bne.b fsnan_out_x_save # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) # the operation was "fmove.x SNAN,-(a7)" from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) frestore FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) mov.l EXC_A6(%a6),%a6 # restore frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) mov.l LOCAL_SIZE+EXC_PC+0x2(%sp),LOCAL_SIZE+EXC_PC+0x2-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) mov.l LOCAL_SIZE+FP_SCR0_EX(%sp),LOCAL_SIZE+EXC_SR(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) mov.l LOCAL_SIZE+FP_SCR0_HI(%sp),LOCAL_SIZE+EXC_PC+0x2(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) mov.l LOCAL_SIZE+FP_SCR0_LO(%sp),LOCAL_SIZE+EXC_EA(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) add.l &LOCAL_SIZE-0x8,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) bra.l _real_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) # _fpsp_inex(): 060FPSP entry point for FP Inexact exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) # FP Inexact exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) # _imem_read_long() - read instruction longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) # fix_skewed_ops() - adjust src operand in fsave frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) # set_tag_x() - determine optype of src/dst operands #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) # store_fpreg() - store opclass 0 or 2 result to FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) # unnorm_fix() - change UNNORM operands to NORM or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) # load_fpn2() - load dst operand from FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) # smovcr() - emulate an "fmovcr" instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) # fout() - emulate an opclass 3 instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) # tbl_unsupp - add of table of emulation routines for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) # _real_inex() - "callout" to operating system inexact handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) # - The system stack contains the FP Inexact exception frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) # - The fsave frame contains the source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) # - The fsave frame contains the adjusted src op for opclass 0,2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) # In a system where the FP Inexact exception is enabled, the goal #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) # is to get to the handler specified at _real_inex(). But, on the 060, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) # for opclass zero and two instruction taking this exception, the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) # hardware doesn't store the correct result to the destination FP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) # register as did the '040 and '881/2. This handler must emulate the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) # instruction in order to get this value and then store it to the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) # correct register before calling _real_inex(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) # For opclass 3 instructions, the 060 doesn't store the default #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) # inexact result out to memory or data register file as it should. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) # This code must emulate the move out by calling fout() before finally #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) # exiting through _real_inex(). #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) global _fpsp_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) _fpsp_inex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) fsave FP_SRC(%a6) # grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) mov.l %d0,EXC_OPWORD(%a6)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) btst &13,%d0 # is instr an fmove out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) bne.w finex_out # fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) # the hardware, for "fabs" and "fneg" w/ a long source format, puts the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) # longword integer directly into the upper longword of the mantissa along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) # w/ an exponent value of 0x401e. we convert this to extended precision here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) bfextu %d0{&19:&3},%d0 # fetch instr size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) bne.b finex_cont # instr size is not long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) cmpi.w FP_SRC_EX(%a6),&0x401e # is exponent 0x401e?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) bne.b finex_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) fmov.l &0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) fmov.l FP_SRC_HI(%a6),%fp0 # load integer src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) fmov.x %fp0,FP_SRC(%a6) # store integer as extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) mov.w &0xe001,0x2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) finex_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) bsr.l fix_skewed_ops # fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) # Here, we zero the ccode and exception byte field since we're going to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) # emulate the whole instruction. Notice, though, that we don't kill the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) # INEX1 bit. This is because a packed op has long since been converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) # to extended before arriving here. Therefore, we need to retain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) # INEX1 bit from when the operand was first converted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) andi.l &0x00ff01ff,USER_FPSR(%a6) # zero all but accured field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) fmov.l &0x0,%fpcr # zero current control regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) bfextu EXC_EXTWORD(%a6){&0:&6},%d1 # extract upper 6 of cmdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) cmpi.b %d1,&0x17 # is op an fmovecr?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) beq.w finex_fmovcr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) mov.b %d0,STAG(%a6) # maybe NORM,DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) # bits four and five of the fp extension word separate the monadic and dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) # operations that can pass through fpsp_inex(). remember that fcmp and ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) # will never take this exception, but fsincos will.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) beq.b finex_extract # monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) btst &0x4,1+EXC_CMDREG(%a6) # is operation an fsincos?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) bne.b finex_extract # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) bsr.l load_fpn2 # load dst into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) lea FP_DST(%a6),%a0 # pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) bsr.l set_tag_x # tag the operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) cmpi.b %d0,&UNNORM # is operand an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) bne.b finex_op2_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) finex_op2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) mov.b %d0,DTAG(%a6) # save dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) finex_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) mov.b 1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) andi.w &0x007f,%d1 # extract extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) lea FP_DST(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) jsr (tbl_unsupp.l,%pc,%d1.l*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) # the operation has been emulated. the result is in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) finex_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) bfextu EXC_CMDREG(%a6){&6:&3},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) bsr.l store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) finex_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) frestore FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) bra.l _real_inex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) finex_fmovcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) mov.b FPCR_MODE(%a6),%d0 # pass rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) mov.b 1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) andi.l &0x0000007f,%d1 # pass rom offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) bsr.l smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) bra.b finex_save
^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) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) # the hardware does not save the default result to memory on enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) # inexact exceptions. we do this here before passing control to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) # the user inexact handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) # byte, word, and long destination format operations can pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) # through here. so can double and single precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) # although packed opclass three operations can take inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) # exceptions, they won't pass through here since they are caught
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) # first by the unsupported data format exception handler. that handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) # sends them directly to _real_inex() if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) finex_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) mov.b &NORM,STAG(%a6) # src is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) mov.b FPCR_MODE(%a6),%d0 # pass rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) andi.l &0xffff00ff,USER_FPSR(%a6) # zero exception field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) lea FP_SRC(%a6),%a0 # pass ptr to src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) bsr.l fout # store the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) bra.b finex_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) # _fpsp_dz(): 060FPSP entry point for FP DZ exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) # This handler should be the first code executed upon taking #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) # the FP DZ exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) # _imem_read_long() - read instruction longword from memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) # fix_skewed_ops() - adjust fsave operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) # _real_dz() - "callout" exit point from FP DZ handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) # - The system stack contains the FP DZ exception stack. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) # - The fsave frame contains the source operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) # - The system stack contains the FP DZ exception stack. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) # - The fsave frame contains the adjusted source operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) # In a system where the DZ exception is enabled, the goal is to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) # get to the handler specified at _real_dz(). But, on the 060, when the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) # exception is taken, the input operand in the fsave state frame may #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) # be incorrect for some cases and need to be adjusted. So, this package #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) # adjusts the operand using fix_skewed_ops() and then branches to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) # _real_dz(). #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) global _fpsp_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) _fpsp_dz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) fsave FP_SRC(%a6) # grab the "busy" frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) # the FPIAR holds the "current PC" of the faulting instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) mov.l %d0,EXC_OPWORD(%a6)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) # here, we simply see if the operand in the fsave frame needs to be "unskewed".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) # this would be the case for opclass two operations with a source zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) # in the sgl or dbl format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) lea FP_SRC(%a6),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) bsr.l fix_skewed_ops # fix src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) fdz_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) frestore FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) bra.l _real_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) # _fpsp_fline(): 060FPSP entry point for "Line F emulator" exc. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) # "Line F Emulator" exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) # _fpsp_unimp() - handle "FP Unimplemented" exceptions #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) # _real_fpu_disabled() - handle "FPU disabled" exceptions #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) # _real_fline() - handle "FLINE" exceptions #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) # _imem_read_long() - read instruction longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) # - The system stack contains a "Line F Emulator" exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) # stack frame. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) # - The system stack is unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) # When a "Line F Emulator" exception occurs, there are 3 possible #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) # exception types, denoted by the exception stack frame format number: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) # (1) FPU unimplemented instruction (6 word stack frame) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) # (2) FPU disabled (8 word stack frame) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) # (3) Line F (4 word stack frame) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) # This module determines which and forks the flow off to the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) # appropriate "callout" (for "disabled" and "Line F") or to the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) # correct emulation code (for "FPU unimplemented"). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) # This code also must check for "fmovecr" instructions w/ a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) # non-zero <ea> field. These may get flagged as "Line F" but should #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) # really be flagged as "FPU Unimplemented". (This is a "feature" on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) # the '060. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) global _fpsp_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) _fpsp_fline:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) # check to see if this exception is a "FP Unimplemented Instruction"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) # exception. if so, branch directly to that handler's entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) cmpi.w 0x6(%sp),&0x202c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) beq.l _fpsp_unimp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) # check to see if the FPU is disabled. if so, jump to the OS entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) # point for that condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) cmpi.w 0x6(%sp),&0x402c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) beq.l _real_fpu_disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) # the exception was an "F-Line Illegal" exception. we check to see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) # if the F-Line instruction is an "fmovecr" w/ a non-zero <ea>. if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) # so, convert the F-Line exception stack frame to an FP Unimplemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) # Instruction exception stack frame else branch to the OS entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) # point for the F-Line exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) mov.l EXC_PC(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) bsr.l _imem_read_long # fetch instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) bfextu %d0{&0:&10},%d1 # is it an fmovecr?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) cmpi.w %d1,&0x03c8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) bne.b fline_fline # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) bfextu %d0{&16:&6},%d1 # is it an fmovecr?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) cmpi.b %d1,&0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) bne.b fline_fline # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) # it's an fmovecr w/ a non-zero <ea> that has entered through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) # the F-Line Illegal exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) # so, we need to convert the F-Line exception stack frame into an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) # FP Unimplemented Instruction stack frame and jump to that entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) # point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) # but, if the FPU is disabled, then we need to jump to the FPU disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) # entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) movc %pcr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) btst &0x1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) beq.b fline_fmovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) sub.l &0x8,%sp # make room for "Next PC", <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) mov.w 0x8(%sp),(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) mov.l 0xa(%sp),0x2(%sp) # move "Current PC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) mov.w &0x402c,0x6(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) mov.l 0x2(%sp),0xc(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) addq.l &0x4,0x2(%sp) # set "Next PC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) bra.l _real_fpu_disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) fline_fmovcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) fmov.l 0x2(%sp),%fpiar # set current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) addq.l &0x4,0x2(%sp) # set Next PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) mov.l (%sp),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) mov.l 0x8(%sp),0x4(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) mov.b &0x20,0x6(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) bra.l _fpsp_unimp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) fline_fline:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) bra.l _real_fline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) # _fpsp_unimp(): 060FPSP entry point for FP "Unimplemented #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) # Instruction" exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) # This handler should be the first code executed upon taking the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) # FP Unimplemented Instruction exception in an operating system. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) # _imem_read_{word,long}() - read instruction word/longword #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) # load_fop() - load src/dst ops from memory and/or FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) # store_fpreg() - store opclass 0 or 2 result to FP regfile #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) # tbl_trans - addr of table of emulation routines for trnscndls #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) # _real_access() - "callout" for access error exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) # _fpsp_done() - "callout" for exit; work all done #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) # _real_trace() - "callout" for Trace enabled exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) # smovcr() - emulate "fmovecr" instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) # funimp_skew() - adjust fsave src ops to "incorrect" value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) # _ftrapcc() - emulate an "ftrapcc" instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) # _fdbcc() - emulate an "fdbcc" instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) # _fscc() - emulate an "fscc" instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) # _real_trap() - "callout" for Trap exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) # _real_bsun() - "callout" for enabled Bsun exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) # - The system stack contains the "Unimplemented Instr" stk frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) # If access error: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) # - The system stack is changed to an access error stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) # If Trace exception enabled: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) # - The system stack is changed to a Trace exception stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) # Else: (normal case) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) # - Correct result has been stored as appropriate #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) # There are two main cases of instructions that may enter here to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) # be emulated: (1) the FPgen instructions, most of which were also #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) # unimplemented on the 040, and (2) "ftrapcc", "fscc", and "fdbcc". #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) # For the first set, this handler calls the routine load_fop() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) # to load the source and destination (for dyadic) operands to be used #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) # for instruction emulation. The correct emulation routine is then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) # chosen by decoding the instruction type and indexing into an #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) # emulation subroutine index table. After emulation returns, this #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) # handler checks to see if an exception should occur as a result of the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) # FP instruction emulation. If so, then an FP exception of the correct #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) # type is inserted into the FPU state frame using the "frestore" #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) # instruction before exiting through _fpsp_done(). In either the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) # exceptional or non-exceptional cases, we must check to see if the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) # Trace exception is enabled. If so, then we must create a Trace #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) # exception frame from the current exception frame and exit through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) # _real_trace(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) # For "fdbcc", "ftrapcc", and "fscc", the emulation subroutines #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) # _fdbcc(), _ftrapcc(), and _fscc() respectively are used. All three #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) # may flag that a BSUN exception should be taken. If so, then the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) # current exception stack frame is converted into a BSUN exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) # stack frame and an exit is made through _real_bsun(). If the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) # instruction was "ftrapcc" and a Trap exception should result, a Trap #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) # exception stack frame is created from the current frame and an exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) # is made through _real_trap(). If a Trace exception is pending, then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) # a Trace exception frame is created from the current frame and a jump #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) # is made to _real_trace(). Finally, if none of these conditions exist, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) # then the handler exits though the callout _fpsp_done(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) # In any of the above scenarios, if a _mem_read() or _mem_write() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) # "callout" returns a failing value, then an access error stack frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) # is created from the current stack frame and an exit is made through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) # _real_access(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) # FP UNIMPLEMENTED INSTRUCTION STACK FRAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) # * * => <ea> of fp unimp instr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) # - EA -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) # * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) # * 0x2 * 0x02c * => frame format and vector offset(vector #11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) # * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) # - Next PC - => PC of instr to execute after exc handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) # * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) # * SR * => SR at the time the exception was taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) # Note: the !NULL bit does not get set in the fsave frame when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) # machine encounters an fp unimp exception. Therefore, it must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) # before leaving this handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) global _fpsp_unimp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) _fpsp_unimp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) link.w %a6,&-LOCAL_SIZE # init stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) btst &0x5,EXC_SR(%a6) # user mode exception?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) bne.b funimp_s # no; supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) # save the value of the user stack pointer onto the stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) funimp_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) mov.l %usp,%a0 # fetch user stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) mov.l %a0,EXC_A7(%a6) # store in stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) bra.b funimp_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) # store the value of the supervisor stack pointer BEFORE the exc occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) # old_sp is address just above stacked effective address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) funimp_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) lea 4+EXC_EA(%a6),%a0 # load old a7'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) mov.l %a0,EXC_A7(%a6) # store a7'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) mov.l %a0,OLD_A7(%a6) # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) funimp_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) # the FPIAR holds the "current PC" of the faulting instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) bsr.l _imem_read_long # fetch the instruction words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) mov.l %d0,EXC_OPWORD(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) ############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) clr.b SPCOND_FLG(%a6) # clear "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) # Divide the fp instructions into 8 types based on the TYPE field in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) # bits 6-8 of the opword(classes 6,7 are undefined).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) # (for the '060, only two types can take this exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) # bftst %d0{&7:&3} # test TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) btst &22,%d0 # type 0 or 1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) bne.w funimp_misc # type 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) # TYPE == 0: General instructions #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) funimp_gen:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) clr.b STORE_FLG(%a6) # clear "store result" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) # clear the ccode byte and exception status byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) bfextu %d0{&16:&6},%d1 # extract upper 6 of cmdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) cmpi.b %d1,&0x17 # is op an fmovecr?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) beq.w funimp_fmovcr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) funimp_gen_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) bsr.l _load_fop # load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) mov.b 1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) andi.w &0x003f,%d1 # extract extension bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) lsl.w &0x3,%d1 # shift right 3 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) or.b STAG(%a6),%d1 # insert src optag bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) lea FP_DST(%a6),%a1 # pass dst ptr in a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) lea FP_SRC(%a6),%a0 # pass src ptr in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) mov.w (tbl_trans.w,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) jsr (tbl_trans.w,%pc,%d1.w*1) # emulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) funimp_fsave:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) bne.w funimp_ena # some are enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) funimp_store:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) bfextu EXC_CMDREG(%a6){&6:&3},%d0 # fetch Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) bsr.l store_fpreg # store result to fp regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) funimp_gen_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) funimp_gen_exit_cmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) cmpi.b SPCOND_FLG(%a6),&mia7_flg # was the ea mode (sp)+ ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) beq.b funimp_gen_exit_a7 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) cmpi.b SPCOND_FLG(%a6),&mda7_flg # was the ea mode -(sp) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) beq.b funimp_gen_exit_a7 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) funimp_gen_exit_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) funimp_gen_exit_cont2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) btst &0x7,(%sp) # is trace on?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) beq.l _fpsp_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) # this catches a problem with the case where an exception will be re-inserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) # into the machine. the frestore has already been executed...so, the fmov.l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) # alone of the control register would trigger an unwanted exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) # until I feel like fixing this, we'll sidestep the exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) fsave -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) fmov.l %fpiar,0x14(%sp) # "Current PC" is in FPIAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) frestore (%sp)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) funimp_gen_exit_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) btst &0x5,EXC_SR(%a6) # supervisor or user mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) bne.b funimp_gen_exit_a7_s # supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) mov.l %a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) mov.l EXC_A7(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) mov.l (%sp)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) bra.b funimp_gen_exit_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) # if the instruction was executed from supervisor mode and the addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) # mode was (a7)+, then the stack frame for the rte must be shifted "up"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) # "n" bytes where "n" is the size of the src operand type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) # f<op>.{b,w,l,s,d,x,p}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) funimp_gen_exit_a7_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) mov.l EXC_A7(%a6),%d0 # load new a7'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) sub.l OLD_A7(%a6),%d0 # subtract old a7'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) mov.l 0x2+EXC_PC(%a6),(0x2+EXC_PC,%a6,%d0) # shift stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) mov.l EXC_SR(%a6),(EXC_SR,%a6,%d0) # shift stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) mov.w %d0,EXC_SR(%a6) # store incr number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) add.w (%sp),%sp # stack frame shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) bra.b funimp_gen_exit_cont2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) ######################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) # fmovecr.x #ccc,fpn #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) ######################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) funimp_fmovcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) mov.b FPCR_MODE(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) mov.b 1+EXC_CMDREG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) andi.l &0x0000007f,%d1 # pass rom offset in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) bsr.l smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) bra.w funimp_fsave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) # the user has enabled some exceptions. we figure not to see this too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) # often so that's why it gets lower priority.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) funimp_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) # was an exception set that was also enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled and set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) bfffo %d0{&24:&8},%d0 # find highest priority exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) bne.b funimp_exc # at least one was set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) # no exception that was enabled was set BUT if we got an exact overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) # and overflow wasn't enabled but inexact was (yech!) then this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) # an inexact exception; otherwise, return to normal non-exception flow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) beq.w funimp_store # no; return to normal flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) # the overflow w/ exact result happened but was inexact set in the FPCR?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) funimp_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) beq.w funimp_store # no; return to normal flow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) bra.b funimp_exc_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) # some exception happened that was actually enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) # we'll insert this new exception into the FPU and then return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) funimp_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) subi.l &24,%d0 # fix offset to be 0-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) cmpi.b %d0,&0x6 # is exception INEX?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) bne.b funimp_exc_force # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) # the enabled exception was inexact. so, if it occurs with an overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) # or underflow that was disabled, then we have to force an overflow or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) # underflow frame. the eventual overflow or underflow handler will see that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) # it's actually an inexact and act appropriately. this is the only easy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) # way to have the EXOP available for the enabled inexact handler when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) # a disabled overflow or underflow has also happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) bne.b funimp_exc_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) btst &unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) bne.b funimp_exc_unfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) # force the fsave exception status bits to signal an exception of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) # appropriate type. don't forget to "skew" the source operand in case we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) # "unskewed" the one the hardware initially gave us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) funimp_exc_force:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) bsr.l funimp_skew # check for special case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) mov.w (tbl_funimp_except.b,%pc,%d0.w*2),2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) bra.b funimp_gen_exit2 # exit with frestore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) tbl_funimp_except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) short 0xe002, 0xe006, 0xe004, 0xe005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) short 0xe003, 0xe002, 0xe001, 0xe001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) # insert an overflow frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) funimp_exc_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) bsr.l funimp_skew # check for special case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) mov.w &0xe005,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) bra.b funimp_gen_exit2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) # insert an underflow frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) funimp_exc_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) bsr.l funimp_skew # check for special case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) mov.w &0xe003,2+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) # this is the general exit point for an enabled exception that will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) # restored into the machine for the instruction just emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) funimp_gen_exit2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) frestore FP_SRC(%a6) # insert exceptional status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) bra.w funimp_gen_exit_cmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) ############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) # TYPE == 1: FDB<cc>, FS<cc>, FTRAP<cc>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) # These instructions were implemented on the '881/2 and '040 in hardware but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) # are emulated in software on the '060.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) funimp_misc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) bfextu %d0{&10:&3},%d1 # extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) cmpi.b %d1,&0x1 # is it an fdb<cc>?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) beq.w funimp_fdbcc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) cmpi.b %d1,&0x7 # is it an fs<cc>?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) bne.w funimp_fscc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) bfextu %d0{&13:&3},%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) cmpi.b %d1,&0x2 # is it an fs<cc>?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) blt.w funimp_fscc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) # ftrap<cc> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) # ftrap<cc>.w #<data> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) # ftrap<cc>.l #<data> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) funimp_ftrapcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) bsr.l _ftrapcc # FTRAP<cc>()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) cmpi.b SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) beq.w funimp_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) cmpi.b SPCOND_FLG(%a6),&ftrapcc_flg # should a trap occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) bne.w funimp_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) # FP UNIMP FRAME TRAP FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) # ** <EA> ** ** Current PC **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) # * 0x2 * 0x02c * * 0x2 * 0x01c *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) # ** Next PC ** ** Next PC **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) # * SR * * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) # (6 words) (6 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) # the ftrapcc instruction should take a trap. so, here we must create a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) # trap stack frame from an unimplemented fp instruction stack frame and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) # jump to the user supplied entry point for the trap exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) funimp_ftrapcc_tp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) mov.l USER_FPIAR(%a6),EXC_EA(%a6) # Address = Current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) mov.w &0x201c,EXC_VOFF(%a6) # Vector Offset = 0x01c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) bra.l _real_trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) # fdb<cc> Dn,<label> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) funimp_fdbcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) bsr.l _imem_read_word # read displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) bne.w funimp_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) ext.l %d0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) bsr.l _fdbcc # FDB<cc>()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) cmpi.b SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) beq.w funimp_bsun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) bra.w funimp_done # branch to finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) #################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) # fs<cc>.b <ea> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) #################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) funimp_fscc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) bsr.l _fscc # FS<cc>()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) # I am assuming here that an "fs<cc>.b -(An)" or "fs<cc>.b (An)+" instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) # does not need to update "An" before taking a bsun exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) cmpi.b SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) beq.w funimp_bsun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) btst &0x5,EXC_SR(%a6) # yes; is it a user mode exception?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) bne.b funimp_fscc_s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) funimp_fscc_u:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) mov.l EXC_A7(%a6),%a0 # yes; set new USP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) mov.l %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) bra.w funimp_done # branch to finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) # remember, I'm assuming that post-increment is bogus...(it IS!!!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) # so, the least significant WORD of the stacked effective address got
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) # overwritten by the "fs<cc> -(An)". We must shift the stack frame "down"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) # so that the rte will work correctly without destroying the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) # even though the operation size is byte, the stack ptr is decr by 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) # remember, also, this instruction may be traced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) funimp_fscc_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) cmpi.b SPCOND_FLG(%a6),&mda7_flg # was a7 modified?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) bne.w funimp_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) btst &0x7,(%sp) # is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) bne.b funimp_fscc_s_trace # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) subq.l &0x2,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) mov.l 0x2(%sp),(%sp) # shift SR,hi(PC) "down"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) mov.l 0x6(%sp),0x4(%sp) # shift lo(PC),voff "down"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) funimp_fscc_s_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) subq.l &0x2,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) mov.l 0x2(%sp),(%sp) # shift SR,hi(PC) "down"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) mov.w 0x6(%sp),0x4(%sp) # shift lo(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) mov.w &0x2024,0x6(%sp) # fmt/voff = $2024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) fmov.l %fpiar,0x8(%sp) # insert "current PC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) # The ftrap<cc>, fs<cc>, or fdb<cc> is to take an enabled bsun. we must convert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) # the fp unimplemented instruction exception stack frame into a bsun stack frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) # restore a bsun exception into the machine, and branch to the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) # supplied bsun hook.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) # FP UNIMP FRAME BSUN FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) # ** <EA> ** * 0x0 * 0x0c0 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) # * 0x2 * 0x02c * ** Current PC **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) # ** Next PC ** * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) # * SR * (4 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) # *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) # (6 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) funimp_bsun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) mov.w &0x00c0,2+EXC_EA(%a6) # Fmt = 0x0; Vector Offset = 0x0c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) mov.l USER_FPIAR(%a6),EXC_VOFF(%a6) # PC = Current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) mov.w EXC_SR(%a6),2+EXC_PC(%a6) # shift SR "up"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) mov.w &0xe000,2+FP_SRC(%a6) # bsun exception enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) frestore FP_SRC(%a6) # restore bsun exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) addq.l &0x4,%sp # erase sludge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) bra.l _real_bsun # branch to user bsun hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) # all ftrapcc/fscc/fdbcc processing has been completed. unwind the stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) # and return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) # as usual, we have to check for trace mode being on here. since instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) # modifying the supervisor stack frame don't pass through here, this is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) # relatively easy task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) funimp_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) btst &0x7,(%sp) # is trace enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) bne.b funimp_trace # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) bra.l _fpsp_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) # FP UNIMP FRAME TRACE FRAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) # ** <EA> ** ** Current PC **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) # * 0x2 * 0x02c * * 0x2 * 0x024 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) # ** Next PC ** ** Next PC **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) # * SR * * SR *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) # ***************** *****************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) # (6 words) (6 words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) # the fscc instruction should take a trace trap. so, here we must create a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) # trace stack frame from an unimplemented fp instruction stack frame and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) # jump to the user supplied entry point for the trace exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) funimp_trace:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) fmov.l %fpiar,0x8(%sp) # current PC is in fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) mov.b &0x24,0x7(%sp) # vector offset = 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) bra.l _real_trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) global tbl_trans
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) swbeg &0x1c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) tbl_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) short tbl_trans - tbl_trans # $00-0 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) short tbl_trans - tbl_trans # $00-1 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) short tbl_trans - tbl_trans # $00-2 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) short tbl_trans - tbl_trans # $00-3 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) short tbl_trans - tbl_trans # $00-4 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) short tbl_trans - tbl_trans # $00-5 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) short tbl_trans - tbl_trans # $00-6 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) short tbl_trans - tbl_trans # $00-7 fmovecr all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) short tbl_trans - tbl_trans # $01-0 fint norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) short tbl_trans - tbl_trans # $01-1 fint zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) short tbl_trans - tbl_trans # $01-2 fint inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) short tbl_trans - tbl_trans # $01-3 fint qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) short tbl_trans - tbl_trans # $01-5 fint denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) short tbl_trans - tbl_trans # $01-4 fint snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) short tbl_trans - tbl_trans # $01-6 fint unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) short tbl_trans - tbl_trans # $01-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) short ssinh - tbl_trans # $02-0 fsinh norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) short src_zero - tbl_trans # $02-1 fsinh zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) short src_inf - tbl_trans # $02-2 fsinh inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) short src_qnan - tbl_trans # $02-3 fsinh qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) short ssinhd - tbl_trans # $02-5 fsinh denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) short src_snan - tbl_trans # $02-4 fsinh snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) short tbl_trans - tbl_trans # $02-6 fsinh unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) short tbl_trans - tbl_trans # $02-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) short tbl_trans - tbl_trans # $03-0 fintrz norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) short tbl_trans - tbl_trans # $03-1 fintrz zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) short tbl_trans - tbl_trans # $03-2 fintrz inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) short tbl_trans - tbl_trans # $03-3 fintrz qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) short tbl_trans - tbl_trans # $03-5 fintrz denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) short tbl_trans - tbl_trans # $03-4 fintrz snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) short tbl_trans - tbl_trans # $03-6 fintrz unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) short tbl_trans - tbl_trans # $03-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) short tbl_trans - tbl_trans # $04-0 fsqrt norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) short tbl_trans - tbl_trans # $04-1 fsqrt zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) short tbl_trans - tbl_trans # $04-2 fsqrt inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) short tbl_trans - tbl_trans # $04-3 fsqrt qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) short tbl_trans - tbl_trans # $04-5 fsqrt denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) short tbl_trans - tbl_trans # $04-4 fsqrt snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) short tbl_trans - tbl_trans # $04-6 fsqrt unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) short tbl_trans - tbl_trans # $04-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) short tbl_trans - tbl_trans # $05-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) short tbl_trans - tbl_trans # $05-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) short tbl_trans - tbl_trans # $05-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) short tbl_trans - tbl_trans # $05-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) short tbl_trans - tbl_trans # $05-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) short tbl_trans - tbl_trans # $05-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) short tbl_trans - tbl_trans # $05-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) short tbl_trans - tbl_trans # $05-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) short slognp1 - tbl_trans # $06-0 flognp1 norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) short src_zero - tbl_trans # $06-1 flognp1 zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) short sopr_inf - tbl_trans # $06-2 flognp1 inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) short src_qnan - tbl_trans # $06-3 flognp1 qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) short slognp1d - tbl_trans # $06-5 flognp1 denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) short src_snan - tbl_trans # $06-4 flognp1 snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) short tbl_trans - tbl_trans # $06-6 flognp1 unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) short tbl_trans - tbl_trans # $06-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) short tbl_trans - tbl_trans # $07-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) short tbl_trans - tbl_trans # $07-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) short tbl_trans - tbl_trans # $07-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) short tbl_trans - tbl_trans # $07-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) short tbl_trans - tbl_trans # $07-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) short tbl_trans - tbl_trans # $07-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) short tbl_trans - tbl_trans # $07-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) short tbl_trans - tbl_trans # $07-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) short setoxm1 - tbl_trans # $08-0 fetoxm1 norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) short src_zero - tbl_trans # $08-1 fetoxm1 zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) short setoxm1i - tbl_trans # $08-2 fetoxm1 inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) short src_qnan - tbl_trans # $08-3 fetoxm1 qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) short setoxm1d - tbl_trans # $08-5 fetoxm1 denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) short src_snan - tbl_trans # $08-4 fetoxm1 snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) short tbl_trans - tbl_trans # $08-6 fetoxm1 unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) short tbl_trans - tbl_trans # $08-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) short stanh - tbl_trans # $09-0 ftanh norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) short src_zero - tbl_trans # $09-1 ftanh zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) short src_one - tbl_trans # $09-2 ftanh inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) short src_qnan - tbl_trans # $09-3 ftanh qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) short stanhd - tbl_trans # $09-5 ftanh denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) short src_snan - tbl_trans # $09-4 ftanh snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) short tbl_trans - tbl_trans # $09-6 ftanh unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) short tbl_trans - tbl_trans # $09-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) short satan - tbl_trans # $0a-0 fatan norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) short src_zero - tbl_trans # $0a-1 fatan zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) short spi_2 - tbl_trans # $0a-2 fatan inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) short src_qnan - tbl_trans # $0a-3 fatan qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) short satand - tbl_trans # $0a-5 fatan denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) short src_snan - tbl_trans # $0a-4 fatan snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) short tbl_trans - tbl_trans # $0a-6 fatan unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) short tbl_trans - tbl_trans # $0a-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) short tbl_trans - tbl_trans # $0b-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) short tbl_trans - tbl_trans # $0b-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) short tbl_trans - tbl_trans # $0b-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) short tbl_trans - tbl_trans # $0b-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) short tbl_trans - tbl_trans # $0b-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) short tbl_trans - tbl_trans # $0b-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) short tbl_trans - tbl_trans # $0b-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) short tbl_trans - tbl_trans # $0b-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) short sasin - tbl_trans # $0c-0 fasin norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) short src_zero - tbl_trans # $0c-1 fasin zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) short t_operr - tbl_trans # $0c-2 fasin inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) short src_qnan - tbl_trans # $0c-3 fasin qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) short sasind - tbl_trans # $0c-5 fasin denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) short src_snan - tbl_trans # $0c-4 fasin snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) short tbl_trans - tbl_trans # $0c-6 fasin unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) short tbl_trans - tbl_trans # $0c-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) short satanh - tbl_trans # $0d-0 fatanh norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) short src_zero - tbl_trans # $0d-1 fatanh zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) short t_operr - tbl_trans # $0d-2 fatanh inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) short src_qnan - tbl_trans # $0d-3 fatanh qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) short satanhd - tbl_trans # $0d-5 fatanh denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) short src_snan - tbl_trans # $0d-4 fatanh snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) short tbl_trans - tbl_trans # $0d-6 fatanh unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) short tbl_trans - tbl_trans # $0d-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) short ssin - tbl_trans # $0e-0 fsin norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) short src_zero - tbl_trans # $0e-1 fsin zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) short t_operr - tbl_trans # $0e-2 fsin inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) short src_qnan - tbl_trans # $0e-3 fsin qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) short ssind - tbl_trans # $0e-5 fsin denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) short src_snan - tbl_trans # $0e-4 fsin snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) short tbl_trans - tbl_trans # $0e-6 fsin unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) short tbl_trans - tbl_trans # $0e-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) short stan - tbl_trans # $0f-0 ftan norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) short src_zero - tbl_trans # $0f-1 ftan zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) short t_operr - tbl_trans # $0f-2 ftan inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) short src_qnan - tbl_trans # $0f-3 ftan qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) short stand - tbl_trans # $0f-5 ftan denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) short src_snan - tbl_trans # $0f-4 ftan snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) short tbl_trans - tbl_trans # $0f-6 ftan unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) short tbl_trans - tbl_trans # $0f-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) short setox - tbl_trans # $10-0 fetox norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) short ld_pone - tbl_trans # $10-1 fetox zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) short szr_inf - tbl_trans # $10-2 fetox inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) short src_qnan - tbl_trans # $10-3 fetox qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) short setoxd - tbl_trans # $10-5 fetox denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) short src_snan - tbl_trans # $10-4 fetox snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) short tbl_trans - tbl_trans # $10-6 fetox unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) short tbl_trans - tbl_trans # $10-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) short stwotox - tbl_trans # $11-0 ftwotox norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) short ld_pone - tbl_trans # $11-1 ftwotox zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) short szr_inf - tbl_trans # $11-2 ftwotox inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) short src_qnan - tbl_trans # $11-3 ftwotox qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) short stwotoxd - tbl_trans # $11-5 ftwotox denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) short src_snan - tbl_trans # $11-4 ftwotox snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) short tbl_trans - tbl_trans # $11-6 ftwotox unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) short tbl_trans - tbl_trans # $11-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) short stentox - tbl_trans # $12-0 ftentox norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) short ld_pone - tbl_trans # $12-1 ftentox zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) short szr_inf - tbl_trans # $12-2 ftentox inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) short src_qnan - tbl_trans # $12-3 ftentox qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) short stentoxd - tbl_trans # $12-5 ftentox denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) short src_snan - tbl_trans # $12-4 ftentox snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) short tbl_trans - tbl_trans # $12-6 ftentox unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) short tbl_trans - tbl_trans # $12-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) short tbl_trans - tbl_trans # $13-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) short tbl_trans - tbl_trans # $13-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) short tbl_trans - tbl_trans # $13-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) short tbl_trans - tbl_trans # $13-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) short tbl_trans - tbl_trans # $13-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) short tbl_trans - tbl_trans # $13-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) short tbl_trans - tbl_trans # $13-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) short tbl_trans - tbl_trans # $13-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) short slogn - tbl_trans # $14-0 flogn norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) short t_dz2 - tbl_trans # $14-1 flogn zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) short sopr_inf - tbl_trans # $14-2 flogn inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) short src_qnan - tbl_trans # $14-3 flogn qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) short slognd - tbl_trans # $14-5 flogn denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) short src_snan - tbl_trans # $14-4 flogn snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) short tbl_trans - tbl_trans # $14-6 flogn unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) short tbl_trans - tbl_trans # $14-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) short slog10 - tbl_trans # $15-0 flog10 norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) short t_dz2 - tbl_trans # $15-1 flog10 zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) short sopr_inf - tbl_trans # $15-2 flog10 inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) short src_qnan - tbl_trans # $15-3 flog10 qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) short slog10d - tbl_trans # $15-5 flog10 denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) short src_snan - tbl_trans # $15-4 flog10 snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) short tbl_trans - tbl_trans # $15-6 flog10 unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) short tbl_trans - tbl_trans # $15-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) short slog2 - tbl_trans # $16-0 flog2 norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) short t_dz2 - tbl_trans # $16-1 flog2 zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) short sopr_inf - tbl_trans # $16-2 flog2 inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) short src_qnan - tbl_trans # $16-3 flog2 qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) short slog2d - tbl_trans # $16-5 flog2 denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) short src_snan - tbl_trans # $16-4 flog2 snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) short tbl_trans - tbl_trans # $16-6 flog2 unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) short tbl_trans - tbl_trans # $16-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) short tbl_trans - tbl_trans # $17-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) short tbl_trans - tbl_trans # $17-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) short tbl_trans - tbl_trans # $17-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) short tbl_trans - tbl_trans # $17-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) short tbl_trans - tbl_trans # $17-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) short tbl_trans - tbl_trans # $17-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) short tbl_trans - tbl_trans # $17-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) short tbl_trans - tbl_trans # $17-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) short tbl_trans - tbl_trans # $18-0 fabs norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) short tbl_trans - tbl_trans # $18-1 fabs zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) short tbl_trans - tbl_trans # $18-2 fabs inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) short tbl_trans - tbl_trans # $18-3 fabs qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) short tbl_trans - tbl_trans # $18-5 fabs denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) short tbl_trans - tbl_trans # $18-4 fabs snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) short tbl_trans - tbl_trans # $18-6 fabs unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) short tbl_trans - tbl_trans # $18-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) short scosh - tbl_trans # $19-0 fcosh norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) short ld_pone - tbl_trans # $19-1 fcosh zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) short ld_pinf - tbl_trans # $19-2 fcosh inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) short src_qnan - tbl_trans # $19-3 fcosh qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) short scoshd - tbl_trans # $19-5 fcosh denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) short src_snan - tbl_trans # $19-4 fcosh snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) short tbl_trans - tbl_trans # $19-6 fcosh unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) short tbl_trans - tbl_trans # $19-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) short tbl_trans - tbl_trans # $1a-0 fneg norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) short tbl_trans - tbl_trans # $1a-1 fneg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) short tbl_trans - tbl_trans # $1a-2 fneg inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) short tbl_trans - tbl_trans # $1a-3 fneg qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) short tbl_trans - tbl_trans # $1a-5 fneg denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) short tbl_trans - tbl_trans # $1a-4 fneg snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) short tbl_trans - tbl_trans # $1a-6 fneg unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) short tbl_trans - tbl_trans # $1a-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) short tbl_trans - tbl_trans # $1b-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) short tbl_trans - tbl_trans # $1b-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) short tbl_trans - tbl_trans # $1b-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) short tbl_trans - tbl_trans # $1b-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) short tbl_trans - tbl_trans # $1b-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) short tbl_trans - tbl_trans # $1b-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) short tbl_trans - tbl_trans # $1b-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) short tbl_trans - tbl_trans # $1b-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) short sacos - tbl_trans # $1c-0 facos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) short ld_ppi2 - tbl_trans # $1c-1 facos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) short t_operr - tbl_trans # $1c-2 facos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) short src_qnan - tbl_trans # $1c-3 facos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) short sacosd - tbl_trans # $1c-5 facos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) short src_snan - tbl_trans # $1c-4 facos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) short tbl_trans - tbl_trans # $1c-6 facos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) short tbl_trans - tbl_trans # $1c-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) short scos - tbl_trans # $1d-0 fcos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) short ld_pone - tbl_trans # $1d-1 fcos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) short t_operr - tbl_trans # $1d-2 fcos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) short src_qnan - tbl_trans # $1d-3 fcos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) short scosd - tbl_trans # $1d-5 fcos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) short src_snan - tbl_trans # $1d-4 fcos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) short tbl_trans - tbl_trans # $1d-6 fcos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) short tbl_trans - tbl_trans # $1d-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) short sgetexp - tbl_trans # $1e-0 fgetexp norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) short src_zero - tbl_trans # $1e-1 fgetexp zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) short t_operr - tbl_trans # $1e-2 fgetexp inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) short src_qnan - tbl_trans # $1e-3 fgetexp qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) short sgetexpd - tbl_trans # $1e-5 fgetexp denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) short src_snan - tbl_trans # $1e-4 fgetexp snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) short tbl_trans - tbl_trans # $1e-6 fgetexp unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) short tbl_trans - tbl_trans # $1e-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) short sgetman - tbl_trans # $1f-0 fgetman norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) short src_zero - tbl_trans # $1f-1 fgetman zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) short t_operr - tbl_trans # $1f-2 fgetman inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) short src_qnan - tbl_trans # $1f-3 fgetman qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) short sgetmand - tbl_trans # $1f-5 fgetman denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) short src_snan - tbl_trans # $1f-4 fgetman snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) short tbl_trans - tbl_trans # $1f-6 fgetman unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) short tbl_trans - tbl_trans # $1f-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) short tbl_trans - tbl_trans # $20-0 fdiv norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) short tbl_trans - tbl_trans # $20-1 fdiv zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) short tbl_trans - tbl_trans # $20-2 fdiv inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) short tbl_trans - tbl_trans # $20-3 fdiv qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) short tbl_trans - tbl_trans # $20-5 fdiv denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) short tbl_trans - tbl_trans # $20-4 fdiv snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) short tbl_trans - tbl_trans # $20-6 fdiv unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) short tbl_trans - tbl_trans # $20-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) short smod_snorm - tbl_trans # $21-0 fmod norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) short smod_szero - tbl_trans # $21-1 fmod zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) short smod_sinf - tbl_trans # $21-2 fmod inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) short sop_sqnan - tbl_trans # $21-3 fmod qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) short smod_sdnrm - tbl_trans # $21-5 fmod denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) short sop_ssnan - tbl_trans # $21-4 fmod snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) short tbl_trans - tbl_trans # $21-6 fmod unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) short tbl_trans - tbl_trans # $21-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) short tbl_trans - tbl_trans # $22-0 fadd norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) short tbl_trans - tbl_trans # $22-1 fadd zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) short tbl_trans - tbl_trans # $22-2 fadd inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) short tbl_trans - tbl_trans # $22-3 fadd qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) short tbl_trans - tbl_trans # $22-5 fadd denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) short tbl_trans - tbl_trans # $22-4 fadd snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) short tbl_trans - tbl_trans # $22-6 fadd unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) short tbl_trans - tbl_trans # $22-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) short tbl_trans - tbl_trans # $23-0 fmul norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) short tbl_trans - tbl_trans # $23-1 fmul zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) short tbl_trans - tbl_trans # $23-2 fmul inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) short tbl_trans - tbl_trans # $23-3 fmul qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) short tbl_trans - tbl_trans # $23-5 fmul denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) short tbl_trans - tbl_trans # $23-4 fmul snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) short tbl_trans - tbl_trans # $23-6 fmul unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) short tbl_trans - tbl_trans # $23-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) short tbl_trans - tbl_trans # $24-0 fsgldiv norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) short tbl_trans - tbl_trans # $24-1 fsgldiv zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) short tbl_trans - tbl_trans # $24-2 fsgldiv inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) short tbl_trans - tbl_trans # $24-3 fsgldiv qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) short tbl_trans - tbl_trans # $24-5 fsgldiv denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) short tbl_trans - tbl_trans # $24-4 fsgldiv snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) short tbl_trans - tbl_trans # $24-6 fsgldiv unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) short tbl_trans - tbl_trans # $24-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) short srem_snorm - tbl_trans # $25-0 frem norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) short srem_szero - tbl_trans # $25-1 frem zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) short srem_sinf - tbl_trans # $25-2 frem inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) short sop_sqnan - tbl_trans # $25-3 frem qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) short srem_sdnrm - tbl_trans # $25-5 frem denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) short sop_ssnan - tbl_trans # $25-4 frem snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) short tbl_trans - tbl_trans # $25-6 frem unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) short tbl_trans - tbl_trans # $25-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) short sscale_snorm - tbl_trans # $26-0 fscale norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) short sscale_szero - tbl_trans # $26-1 fscale zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) short sscale_sinf - tbl_trans # $26-2 fscale inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) short sop_sqnan - tbl_trans # $26-3 fscale qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) short sscale_sdnrm - tbl_trans # $26-5 fscale denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) short sop_ssnan - tbl_trans # $26-4 fscale snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) short tbl_trans - tbl_trans # $26-6 fscale unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) short tbl_trans - tbl_trans # $26-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) short tbl_trans - tbl_trans # $27-0 fsglmul norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) short tbl_trans - tbl_trans # $27-1 fsglmul zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) short tbl_trans - tbl_trans # $27-2 fsglmul inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) short tbl_trans - tbl_trans # $27-3 fsglmul qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) short tbl_trans - tbl_trans # $27-5 fsglmul denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) short tbl_trans - tbl_trans # $27-4 fsglmul snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) short tbl_trans - tbl_trans # $27-6 fsglmul unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) short tbl_trans - tbl_trans # $27-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) short tbl_trans - tbl_trans # $28-0 fsub norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) short tbl_trans - tbl_trans # $28-1 fsub zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) short tbl_trans - tbl_trans # $28-2 fsub inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) short tbl_trans - tbl_trans # $28-3 fsub qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) short tbl_trans - tbl_trans # $28-5 fsub denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) short tbl_trans - tbl_trans # $28-4 fsub snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) short tbl_trans - tbl_trans # $28-6 fsub unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) short tbl_trans - tbl_trans # $28-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) short tbl_trans - tbl_trans # $29-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) short tbl_trans - tbl_trans # $29-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) short tbl_trans - tbl_trans # $29-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) short tbl_trans - tbl_trans # $29-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) short tbl_trans - tbl_trans # $29-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) short tbl_trans - tbl_trans # $29-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) short tbl_trans - tbl_trans # $29-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) short tbl_trans - tbl_trans # $29-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) short tbl_trans - tbl_trans # $2a-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) short tbl_trans - tbl_trans # $2a-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) short tbl_trans - tbl_trans # $2a-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) short tbl_trans - tbl_trans # $2a-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) short tbl_trans - tbl_trans # $2a-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) short tbl_trans - tbl_trans # $2a-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) short tbl_trans - tbl_trans # $2a-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) short tbl_trans - tbl_trans # $2a-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) short tbl_trans - tbl_trans # $2b-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) short tbl_trans - tbl_trans # $2b-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) short tbl_trans - tbl_trans # $2b-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) short tbl_trans - tbl_trans # $2b-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) short tbl_trans - tbl_trans # $2b-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) short tbl_trans - tbl_trans # $2b-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) short tbl_trans - tbl_trans # $2b-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) short tbl_trans - tbl_trans # $2b-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) short tbl_trans - tbl_trans # $2c-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) short tbl_trans - tbl_trans # $2c-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) short tbl_trans - tbl_trans # $2c-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) short tbl_trans - tbl_trans # $2c-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) short tbl_trans - tbl_trans # $2c-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) short tbl_trans - tbl_trans # $2c-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) short tbl_trans - tbl_trans # $2c-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) short tbl_trans - tbl_trans # $2c-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) short tbl_trans - tbl_trans # $2d-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) short tbl_trans - tbl_trans # $2d-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) short tbl_trans - tbl_trans # $2d-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) short tbl_trans - tbl_trans # $2d-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) short tbl_trans - tbl_trans # $2d-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) short tbl_trans - tbl_trans # $2d-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) short tbl_trans - tbl_trans # $2d-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) short tbl_trans - tbl_trans # $2d-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) short tbl_trans - tbl_trans # $2e-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) short tbl_trans - tbl_trans # $2e-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) short tbl_trans - tbl_trans # $2e-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) short tbl_trans - tbl_trans # $2e-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) short tbl_trans - tbl_trans # $2e-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) short tbl_trans - tbl_trans # $2e-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) short tbl_trans - tbl_trans # $2e-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) short tbl_trans - tbl_trans # $2e-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) short tbl_trans - tbl_trans # $2f-0 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) short tbl_trans - tbl_trans # $2f-1 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) short tbl_trans - tbl_trans # $2f-2 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) short tbl_trans - tbl_trans # $2f-3 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) short tbl_trans - tbl_trans # $2f-4 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) short tbl_trans - tbl_trans # $2f-5 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) short tbl_trans - tbl_trans # $2f-6 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) short tbl_trans - tbl_trans # $2f-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) short ssincos - tbl_trans # $30-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) short ssincosz - tbl_trans # $30-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) short ssincosi - tbl_trans # $30-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) short ssincosqnan - tbl_trans # $30-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) short ssincosd - tbl_trans # $30-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) short ssincossnan - tbl_trans # $30-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) short tbl_trans - tbl_trans # $30-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) short tbl_trans - tbl_trans # $30-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) short ssincos - tbl_trans # $31-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) short ssincosz - tbl_trans # $31-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) short ssincosi - tbl_trans # $31-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) short ssincosqnan - tbl_trans # $31-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) short ssincosd - tbl_trans # $31-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) short ssincossnan - tbl_trans # $31-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) short tbl_trans - tbl_trans # $31-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) short tbl_trans - tbl_trans # $31-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) short ssincos - tbl_trans # $32-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) short ssincosz - tbl_trans # $32-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) short ssincosi - tbl_trans # $32-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) short ssincosqnan - tbl_trans # $32-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) short ssincosd - tbl_trans # $32-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) short ssincossnan - tbl_trans # $32-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) short tbl_trans - tbl_trans # $32-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) short tbl_trans - tbl_trans # $32-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) short ssincos - tbl_trans # $33-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) short ssincosz - tbl_trans # $33-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) short ssincosi - tbl_trans # $33-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) short ssincosqnan - tbl_trans # $33-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) short ssincosd - tbl_trans # $33-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) short ssincossnan - tbl_trans # $33-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) short tbl_trans - tbl_trans # $33-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) short tbl_trans - tbl_trans # $33-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) short ssincos - tbl_trans # $34-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) short ssincosz - tbl_trans # $34-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) short ssincosi - tbl_trans # $34-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) short ssincosqnan - tbl_trans # $34-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) short ssincosd - tbl_trans # $34-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) short ssincossnan - tbl_trans # $34-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) short tbl_trans - tbl_trans # $34-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) short tbl_trans - tbl_trans # $34-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) short ssincos - tbl_trans # $35-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) short ssincosz - tbl_trans # $35-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) short ssincosi - tbl_trans # $35-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) short ssincosqnan - tbl_trans # $35-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) short ssincosd - tbl_trans # $35-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) short ssincossnan - tbl_trans # $35-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) short tbl_trans - tbl_trans # $35-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) short tbl_trans - tbl_trans # $35-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) short ssincos - tbl_trans # $36-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) short ssincosz - tbl_trans # $36-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) short ssincosi - tbl_trans # $36-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) short ssincosqnan - tbl_trans # $36-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) short ssincosd - tbl_trans # $36-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) short ssincossnan - tbl_trans # $36-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) short tbl_trans - tbl_trans # $36-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) short tbl_trans - tbl_trans # $36-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) short ssincos - tbl_trans # $37-0 fsincos norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) short ssincosz - tbl_trans # $37-1 fsincos zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) short ssincosi - tbl_trans # $37-2 fsincos inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) short ssincosqnan - tbl_trans # $37-3 fsincos qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) short ssincosd - tbl_trans # $37-5 fsincos denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) short ssincossnan - tbl_trans # $37-4 fsincos snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) short tbl_trans - tbl_trans # $37-6 fsincos unnorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) short tbl_trans - tbl_trans # $37-7 ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) ##########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) # the instruction fetch access for the displacement word for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) # fdbcc emulation failed. here, we create an access error frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) # from the current frame and branch to _real_access().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) funimp_iacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) mov.l USER_FPIAR(%a6),EXC_PC(%a6) # store current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) mov.l (%sp),-(%sp) # store SR,hi(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) mov.w 0x8(%sp),0x4(%sp) # store lo(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) mov.w &0x4008,0x6(%sp) # store voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) mov.l 0x2(%sp),0x8(%sp) # store EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) mov.l &0x09428001,0xc(%sp) # store FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) btst &0x5,(%sp) # user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) beq.b funimp_iacc_end # user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) bset &0x2,0xd(%sp) # set supervisor TM bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) funimp_iacc_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) bra.l _real_access
^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) # ssin(): computes the sine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) # ssind(): computes the sine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) # scos(): computes the cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) # scosd(): computes the cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) # ssincos(): computes the sine and cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) # ssincosd(): computes the sine and cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) # fp0 = sin(X) or cos(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) # For ssincos(X): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) # fp0 = sin(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) # fp1 = cos(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) # The returned result is within 1 ulp in 64 significant bit, i.e. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) # within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) # SIN and COS: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) # 1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) # 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) # 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) # k = N mod 4, so in particular, k = 0,1,2,or 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) # Overwrite k by k := k + AdjN. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) # 4. If k is even, go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) # 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) # Return sgn*cos(r) where cos(r) is approximated by an #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) # even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) # s = r*r. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) # 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) # where sin(r) is approximated by an odd polynomial in r #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) # r + r*s*(A1+s*(A2+ ... + s*A7)), s = r*r. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) # 7. If |X| > 1, go to 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) # 8. (|X|<2**(-40)) If SIN is invoked, return X; #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) # otherwise return 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) # 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) # go back to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) # SINCOS: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) # k = N mod 4, so in particular, k = 0,1,2,or 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) # 3. If k is even, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) # 4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) # j1 exclusive or with the l.s.b. of k. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) # sgn1 := (-1)**j1, sgn2 := (-1)**j2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) # SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) # sin(r) and cos(r) are computed as odd and even #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) # polynomials in r, respectively. Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) # 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) # SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) # sin(r) and cos(r) are computed as odd and even #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) # polynomials in r, respectively. Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) # 6. If |X| > 1, go to 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) # 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) # go back to 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) SINA7: long 0xBD6AAA77,0xCCC994F5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) SINA6: long 0x3DE61209,0x7AAE8DA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) SINA5: long 0xBE5AE645,0x2A118AE4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) SINA4: long 0x3EC71DE3,0xA5341531
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) SINA3: long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) SINA2: long 0x3FF80000,0x88888888,0x888859AF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) SINA1: long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) COSB8: long 0x3D2AC4D0,0xD6011EE3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) COSB7: long 0xBDA9396F,0x9F45AC19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) COSB6: long 0x3E21EED9,0x0612C972
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) COSB5: long 0xBE927E4F,0xB79D9FCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) COSB4: long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) COSB3: long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) COSB2: long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) COSB1: long 0xBF000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) set INARG,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) # set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) set RPRIME,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) set SPRIME,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) set POSNEG1,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) set TWOTO63,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) set ENDFLAG,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) set INT,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) set ADJN,L_SCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) global ssin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) ssin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) mov.l &0,ADJN(%a6) # yes; SET ADJN TO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) bra.b SINBGN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) global scos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) scos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) mov.l &1,ADJN(%a6) # yes; SET ADJN TO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) SINBGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) fmov.x %fp0,X(%a6) # save input at X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) # "COMPACTIFY" X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) mov.l (%a0),%d1 # put exp in hi word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) mov.w 4(%a0),%d1 # fetch hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) and.l &0x7FFFFFFF,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) cmpi.l %d1,&0x3FD78000 # is |X| >= 2**(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) bge.b SOK1 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) bra.w SINSM # yes; input is very small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) SOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) cmp.l %d1,&0x4004BC7E # is |X| < 15 PI?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) blt.b SINMAIN # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) bra.w SREDUCEX # yes; input is very large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) #--THIS IS THE USUAL CASE, |X| <= 15 PI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) SINMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) mov.l INT(%a6),%d1 # make a copy of N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) asl.l &4,%d1 # N *= 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) add.l %d1,%a1 # tbl_addr = a1 + (N*16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) # A1 IS THE ADDRESS OF N*PIBY2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) # ...WHICH IS IN TWO PIECES Y1 & Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) fsub.x (%a1)+,%fp0 # X-Y1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) fsub.s (%a1),%fp0 # fp0 = R = (X-Y1)-Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) SINCONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) #--continuation from REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) add.l ADJN(%a6),%d1 # SEE IF D0 IS ODD OR EVEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) ror.l &1,%d1 # D0 WAS ODD IFF D0 IS NEGATIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) blt.w COSPOLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) #--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) #--WHERE T=S*S.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) SINPOLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) fmov.x %fp0,X(%a6) # X IS R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) fmul.x %fp0,%fp0 # FP0 IS S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) fmov.d SINA7(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) fmov.d SINA6(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) fmul.x %fp1,%fp1 # FP1 IS T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) eor.l %d1,X(%a6) # X IS NOW R'= SGN*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) fmul.x %fp1,%fp3 # TA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) fmul.x %fp1,%fp2 # TA6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) fadd.d SINA5(%pc),%fp3 # A5+TA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) fadd.d SINA4(%pc),%fp2 # A4+TA6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) fmul.x %fp1,%fp3 # T(A5+TA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) fmul.x %fp1,%fp2 # T(A4+TA6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) fadd.d SINA3(%pc),%fp3 # A3+T(A5+TA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) fadd.x SINA2(%pc),%fp2 # A2+T(A4+TA6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) fmul.x %fp3,%fp1 # T(A3+T(A5+TA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) fmul.x %fp0,%fp2 # S(A2+T(A4+TA6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) fadd.x SINA1(%pc),%fp1 # A1+T(A3+T(A5+TA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) fmul.x X(%a6),%fp0 # R'*S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) fadd.x %fp2,%fp1 # [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) fmul.x %fp1,%fp0 # SIN(R')-R'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) fadd.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) #--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) #--WHERE T=S*S.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) #--AND IS THEREFORE STORED AS SINGLE PRECISION.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) COSPOLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) fmul.x %fp0,%fp0 # FP0 IS S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) fmov.d COSB8(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) fmov.d COSB7(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) fmul.x %fp1,%fp1 # FP1 IS T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) fmov.x %fp0,X(%a6) # X IS S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) fmul.x %fp1,%fp2 # TB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) eor.l %d1,X(%a6) # X IS NOW S'= SGN*S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) fmul.x %fp1,%fp3 # TB7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) or.l &0x3F800000,%d1 # D0 IS SGN IN SINGLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) mov.l %d1,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) fadd.d COSB6(%pc),%fp2 # B6+TB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) fadd.d COSB5(%pc),%fp3 # B5+TB7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) fmul.x %fp1,%fp2 # T(B6+TB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) fmul.x %fp1,%fp3 # T(B5+TB7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) fadd.d COSB4(%pc),%fp2 # B4+T(B6+TB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) fadd.x COSB3(%pc),%fp3 # B3+T(B5+TB7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) fmul.x %fp1,%fp2 # T(B4+T(B6+TB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) fmul.x %fp3,%fp1 # T(B3+T(B5+TB7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) fadd.x COSB2(%pc),%fp2 # B2+T(B4+T(B6+TB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) fadd.s COSB1(%pc),%fp1 # B1+T(B3+T(B5+TB7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) fmul.x %fp2,%fp0 # S(B2+T(B4+T(B6+TB8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) fadd.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) fmul.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) fadd.s POSNEG1(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) ##############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) # SINe: Big OR Small?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) #--IF |X| < 2**(-40), RETURN X OR 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) SINBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) bgt.l SREDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) SINSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) mov.l ADJN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) bgt.b COSTINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) # here, the operation may underflow iff the precision is sgl or dbl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) # extended denorms are handled through another entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) SINTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) # mov.w &0x0000,XDCARE(%a6) # JUST IN CASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) fmov.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) COSTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) fmov.s &0x3F800000,%fp0 # fp0 = 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) fadd.s &0x80800000,%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) ################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) global ssind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) #--SIN(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) ssind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) global scosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) #--COS(X) = 1 FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) scosd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) fmov.s &0x3F800000,%fp0 # fp0 = 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) ##################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) global ssincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) ssincos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) #--SET ADJN TO 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) mov.l &4,ADJN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) and.l &0x7FFFFFFF,%d1 # COMPACTIFY X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) bge.b SCOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) bra.w SCSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) SCOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) cmp.l %d1,&0x4004BC7E # |X| < 15 PI?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) blt.b SCMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) bra.w SREDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) #--THIS IS THE USUAL CASE, |X| <= 15 PI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) SCMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) asl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) add.l %d1,%a1 # ADDRESS OF N*PIBY2, IN Y1, Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) fsub.x (%a1)+,%fp0 # X-Y1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) SCCONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) #--continuation point from REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) cmp.l %d1,&0 # D0 < 0 IFF N IS ODD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) bge.w NEVEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) SNODD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) #--REGISTERS SAVED SO FAR: D0, A0, FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) fmovm.x &0x04,-(%sp) # save fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) fmov.x %fp0,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) fmul.x %fp0,%fp0 # FP0 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) fmov.d SINA7(%pc),%fp1 # A7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) fmov.d COSB8(%pc),%fp2 # B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) fmul.x %fp0,%fp1 # SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) fmul.x %fp0,%fp2 # SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) mov.l %d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) mov.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) ror.l &1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) eor.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) fadd.d SINA6(%pc),%fp1 # A6+SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) fadd.d COSB7(%pc),%fp2 # B7+SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) fmul.x %fp0,%fp1 # S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) eor.l %d2,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) mov.l (%sp)+,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) fmul.x %fp0,%fp2 # S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) mov.l &0x3F800000,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) eor.l %d1,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) fadd.d SINA5(%pc),%fp1 # A5+S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) fadd.d COSB6(%pc),%fp2 # B6+S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) fmul.x %fp0,%fp1 # S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) fmul.x %fp0,%fp2 # S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) fmov.x %fp0,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) fadd.d SINA4(%pc),%fp1 # A4+S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) eor.l %d1,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) fadd.d COSB5(%pc),%fp2 # B5+S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) fmul.x %fp0,%fp1 # S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) fmul.x %fp0,%fp2 # S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) fadd.d SINA3(%pc),%fp1 # A3+S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) fadd.d COSB4(%pc),%fp2 # B4+S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) fmul.x %fp0,%fp1 # S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) fmul.x %fp0,%fp2 # S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) fadd.x SINA2(%pc),%fp1 # A2+S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) fadd.x COSB3(%pc),%fp2 # B3+S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) fmul.x %fp0,%fp1 # S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) fmul.x %fp0,%fp2 # S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) fadd.x SINA1(%pc),%fp1 # A1+S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) fadd.x COSB2(%pc),%fp2 # B2+S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) fmul.x %fp0,%fp1 # S(A1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) fmul.x %fp2,%fp0 # S(B2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) fmul.x RPRIME(%a6),%fp1 # R'S(A1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) fadd.s COSB1(%pc),%fp0 # B1+S(B2...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) fmul.x SPRIME(%a6),%fp0 # S'(B1+S(B2+...))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) fmovm.x (%sp)+,&0x20 # restore fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) fadd.x RPRIME(%a6),%fp1 # COS(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) fadd.s POSNEG1(%a6),%fp0 # SIN(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) NEVEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) #--REGISTERS SAVED SO FAR: FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) fmovm.x &0x04,-(%sp) # save fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) fmov.x %fp0,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) fmul.x %fp0,%fp0 # FP0 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) fmov.d COSB8(%pc),%fp1 # B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) fmov.d SINA7(%pc),%fp2 # A7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) fmul.x %fp0,%fp1 # SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) fmov.x %fp0,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) fmul.x %fp0,%fp2 # SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) fadd.d COSB7(%pc),%fp1 # B7+SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) fadd.d SINA6(%pc),%fp2 # A6+SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) eor.l %d1,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) eor.l %d1,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) fmul.x %fp0,%fp1 # S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) or.l &0x3F800000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) mov.l %d1,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) fmul.x %fp0,%fp2 # S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) fadd.d COSB6(%pc),%fp1 # B6+S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) fadd.d SINA5(%pc),%fp2 # A5+S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) fmul.x %fp0,%fp1 # S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) fmul.x %fp0,%fp2 # S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) fadd.d COSB5(%pc),%fp1 # B5+S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) fadd.d SINA4(%pc),%fp2 # A4+S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) fmul.x %fp0,%fp1 # S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) fmul.x %fp0,%fp2 # S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) fadd.d COSB4(%pc),%fp1 # B4+S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) fadd.d SINA3(%pc),%fp2 # A3+S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) fmul.x %fp0,%fp1 # S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) fmul.x %fp0,%fp2 # S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) fadd.x COSB3(%pc),%fp1 # B3+S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) fadd.x SINA2(%pc),%fp2 # A2+S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) fmul.x %fp0,%fp1 # S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) fmul.x %fp0,%fp2 # S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) fadd.x COSB2(%pc),%fp1 # B2+S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) fadd.x SINA1(%pc),%fp2 # A1+S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) fmul.x %fp0,%fp1 # S(B2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) fmul.x %fp2,%fp0 # s(a1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) fadd.s COSB1(%pc),%fp1 # B1+S(B2...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) fmul.x RPRIME(%a6),%fp0 # R'S(A1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) fmul.x SPRIME(%a6),%fp1 # S'(B1+S(B2+...))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) fmovm.x (%sp)+,&0x20 # restore fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) fadd.s POSNEG1(%a6),%fp1 # COS(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) fadd.x RPRIME(%a6),%fp0 # SIN(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) ################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) SCBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) bgt.w SREDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) ################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) SCSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) # mov.w &0x0000,XDCARE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) fsub.s &0x00800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) fmov.l %fpcr,%d0 # d0 must have fpcr,too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) ##############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) global ssincosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) #--SIN AND COS OF X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) ssincosd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) SREDUCEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) fmovm.x &0x3c,-(%sp) # save {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) fmov.s &0x00000000,%fp1 # fp1 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) #--there is a danger of unwanted overflow in first LOOP iteration. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) #--case, reduce argument by one remainder step to make subsequent reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) #--safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) cmp.l %d1,&0x7ffeffff # is arg dangerously large?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) bne.b SLOOP # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) # yes; create 2**16383*PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) mov.w &0x7ffe,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) mov.l &0xc90fdaa2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) clr.l FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) # create low half of 2**16383*PI/2 at FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) mov.w &0x7fdc,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) mov.l &0x85a308d3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) clr.l FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) ftest.x %fp0 # test sign of argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) fblt.w sred_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) or.b &0x80,FP_SCR0_EX(%a6) # positive arg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) or.b &0x80,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) sred_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) fmov.x %fp0,%fp1 # save high result in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) fadd.x FP_SCR1(%a6),%fp0 # low part of reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) fsub.x %fp0,%fp1 # determine low component of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) #--integer quotient will be stored in N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) SLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) mov.w INARG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) mov.l %d1,%a1 # save a copy of D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) and.l &0x00007FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) sub.l &0x00003FFF,%d1 # d0 = K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) cmp.l %d1,&28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) ble.b SLASTLOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) SCONTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) sub.l &27,%d1 # d0 = L := K-27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) mov.b &0,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) bra.b SWORK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) SLASTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) clr.l %d1 # d0 = L := 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) mov.b &1,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) SWORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) #--2**L * (PIby2_1), 2**L * (PIby2_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) mov.l &0xA2F9836E,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) mov.l &0x4E44152A,FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) #--US THE DESIRED VALUE IN FLOATING POINT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) mov.l %a1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) swap %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) mov.l %d2,TWOTO63(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) fsub.s TWOTO63(%a6),%fp2 # fp2 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) # fint.x %fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) mov.l %d1,%d2 # d2 = L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) mov.w %d2,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) mov.l &0xC90FDAA2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) add.l &0x00003FDD,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) mov.w %d1,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) mov.l &0x85A308D3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) mov.b ENDFLAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) #--P2 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) fmov.x %fp2,%fp4 # fp4 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) fmov.x %fp2,%fp5 # fp5 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) fmov.x %fp4,%fp3 # fp3 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) #--we want P+p = W+w but |p| <= half ulp of P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) #--Then, we need to compute A := R-P and a := r-p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) fadd.x %fp5,%fp3 # fp3 = P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) fsub.x %fp3,%fp4 # fp4 = W-P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) fsub.x %fp3,%fp0 # fp0 = A := R - P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) fmov.x %fp0,%fp3 # fp3 = A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) fsub.x %fp4,%fp1 # fp1 = a := r - p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) #--|r| <= half ulp of R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) fadd.x %fp1,%fp0 # fp0 = R := A+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) #--No need to calculate r if this is the last loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) cmp.b %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) bgt.w SRESTORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) #--Need to calculate r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) fsub.x %fp0,%fp3 # fp3 = A-R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) bra.w SLOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) SRESTORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) fmov.l %fp2,INT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) fmovm.x (%sp)+,&0x3c # restore {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) mov.l ADJN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) cmp.l %d1,&4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) blt.w SINCONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) bra.w SCCONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) # stan(): computes the tangent of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) # stand(): computes the tangent of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) # fp0 = tan(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) # The returned result is within 3 ulp in 64 significant bit, i.e. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) # within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) # k = N mod 2, so in particular, k = 0 or 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) # 3. If k is odd, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) # 4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) # rational function U/V where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) # U = r + r*s*(P1 + s*(P2 + s*P3)), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) # 4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) # a rational function U/V where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) # U = r + r*s*(P1 + s*(P2 + s*P3)), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) # -Cot(r) = -V/U. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) # 6. If |X| > 1, go to 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) # 7. (|X|<2**(-40)) Tan(X) = X. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) # to 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) TANQ4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) long 0x3EA0B759,0xF50F8688
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) TANP3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) long 0xBEF2BAA5,0xA8924F04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) TANQ3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) long 0xBF346F59,0xB39BA65F,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) TANP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) long 0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) TANQ2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) long 0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) TANP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) long 0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) TANQ1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) long 0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) INVTWOPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) long 0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) TWOPI1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) long 0x40010000,0xC90FDAA2,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) TWOPI2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) #--MOST 69 BITS LONG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) # global PITBL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) PITBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) long 0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) long 0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) long 0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) long 0xC0040000,0xB6365E22,0xEE46F000,0x21480000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) long 0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) long 0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) long 0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) long 0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) long 0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) long 0xC0040000,0x90836524,0x88034B96,0x20B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) long 0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) long 0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) long 0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) long 0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) long 0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) long 0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) long 0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) long 0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) long 0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) long 0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) long 0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) long 0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) long 0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) long 0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) long 0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) long 0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) long 0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) long 0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) long 0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) long 0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) long 0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) long 0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) long 0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) long 0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) long 0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) long 0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) long 0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) long 0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) long 0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) long 0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) long 0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) long 0x40030000,0x8A3AE64F,0x76F80584,0x21080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) long 0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) long 0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) long 0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) long 0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) long 0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) long 0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) long 0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) long 0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) long 0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) long 0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) long 0x40040000,0x8A3AE64F,0x76F80584,0x21880000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) long 0x40040000,0x90836524,0x88034B96,0xA0B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) long 0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) long 0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) long 0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) long 0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) long 0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) long 0x40040000,0xB6365E22,0xEE46F000,0xA1480000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) long 0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) long 0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) long 0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) set INARG,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) set TWOTO63,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) set INT,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) set ENDFLAG,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) global stan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) stan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) bge.b TANOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) bra.w TANSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) TANOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) cmp.l %d1,&0x4004BC7E # |X| < 15 PI?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) blt.b TANMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) bra.w REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) TANMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) #--THIS IS THE USUAL CASE, |X| <= 15 PI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) lea.l PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) fmov.l %fp1,%d1 # CONVERT TO INTEGER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) asl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) add.l %d1,%a1 # ADDRESS N*PIBY2 IN Y1, Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) fsub.x (%a1)+,%fp0 # X-Y1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) ror.l &5,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) and.l &0x80000000,%d1 # D0 WAS ODD IFF D0 < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) TANCONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) fmovm.x &0x0c,-(%sp) # save fp2,fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) blt.w NODD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) fmul.x %fp1,%fp1 # S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) fmov.d TANQ4(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) fmov.d TANP3(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) fmul.x %fp1,%fp3 # SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) fmul.x %fp1,%fp2 # SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) fadd.d TANQ3(%pc),%fp3 # Q3+SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) fadd.x TANP2(%pc),%fp2 # P2+SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) fmul.x %fp1,%fp3 # S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) fmul.x %fp1,%fp2 # S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) fmul.x %fp1,%fp3 # S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) fmul.x %fp1,%fp2 # S(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) fmul.x %fp0,%fp2 # RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) fmul.x %fp3,%fp1 # S(Q1+S(Q2+S(Q3+SQ4)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) fadd.x %fp2,%fp0 # R+RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) fadd.s &0x3F800000,%fp1 # 1+S(Q1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) fmovm.x (%sp)+,&0x30 # restore fp2,fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) fdiv.x %fp1,%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) NODD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) fmul.x %fp0,%fp0 # S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) fmov.d TANQ4(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) fmov.d TANP3(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) fmul.x %fp0,%fp3 # SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) fmul.x %fp0,%fp2 # SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) fadd.d TANQ3(%pc),%fp3 # Q3+SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) fadd.x TANP2(%pc),%fp2 # P2+SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) fmul.x %fp0,%fp3 # S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) fmul.x %fp0,%fp2 # S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) fmul.x %fp0,%fp3 # S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) fmul.x %fp0,%fp2 # S(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) fmul.x %fp1,%fp2 # RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) fmul.x %fp3,%fp0 # S(Q1+S(Q2+S(Q3+SQ4)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) fadd.x %fp2,%fp1 # R+RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) fadd.s &0x3F800000,%fp0 # 1+S(Q1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) fmovm.x (%sp)+,&0x30 # restore fp2,fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) fmov.x %fp1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) eor.l &0x80000000,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) fdiv.x (%sp)+,%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) TANBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) #--IF |X| < 2**(-40), RETURN X OR 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) bgt.b REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) TANSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) fmov.x %fp0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) fmov.x (%sp)+,%fp0 # last inst - posibble exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) global stand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) #--TAN(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) stand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) REDUCEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) fmovm.x &0x3c,-(%sp) # save {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) fmov.s &0x00000000,%fp1 # fp1 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) #--there is a danger of unwanted overflow in first LOOP iteration. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) #--case, reduce argument by one remainder step to make subsequent reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) #--safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) cmp.l %d1,&0x7ffeffff # is arg dangerously large?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) bne.b LOOP # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) # yes; create 2**16383*PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) mov.w &0x7ffe,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) mov.l &0xc90fdaa2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) clr.l FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) # create low half of 2**16383*PI/2 at FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) mov.w &0x7fdc,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) mov.l &0x85a308d3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) clr.l FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) ftest.x %fp0 # test sign of argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) fblt.w red_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) or.b &0x80,FP_SCR0_EX(%a6) # positive arg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) or.b &0x80,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) red_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) fmov.x %fp0,%fp1 # save high result in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) fadd.x FP_SCR1(%a6),%fp0 # low part of reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) fsub.x %fp0,%fp1 # determine low component of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) #--integer quotient will be stored in N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) LOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) mov.w INARG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) mov.l %d1,%a1 # save a copy of D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) and.l &0x00007FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) sub.l &0x00003FFF,%d1 # d0 = K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) cmp.l %d1,&28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) ble.b LASTLOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) CONTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) sub.l &27,%d1 # d0 = L := K-27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) mov.b &0,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) bra.b WORK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) LASTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) clr.l %d1 # d0 = L := 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) mov.b &1,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) WORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) #--2**L * (PIby2_1), 2**L * (PIby2_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) mov.l &0xA2F9836E,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) mov.l &0x4E44152A,FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) #--US THE DESIRED VALUE IN FLOATING POINT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) mov.l %a1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) swap %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) mov.l %d2,TWOTO63(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) fsub.s TWOTO63(%a6),%fp2 # fp2 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) # fintrz.x %fp2,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) mov.l %d1,%d2 # d2 = L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) mov.w %d2,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) mov.l &0xC90FDAA2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) add.l &0x00003FDD,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) mov.w %d1,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) mov.l &0x85A308D3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) mov.b ENDFLAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) #--P2 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) fmov.x %fp2,%fp4 # fp4 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) fmov.x %fp2,%fp5 # fp5 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) fmov.x %fp4,%fp3 # fp3 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) #--we want P+p = W+w but |p| <= half ulp of P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) #--Then, we need to compute A := R-P and a := r-p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) fadd.x %fp5,%fp3 # fp3 = P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) fsub.x %fp3,%fp4 # fp4 = W-P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) fsub.x %fp3,%fp0 # fp0 = A := R - P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) fmov.x %fp0,%fp3 # fp3 = A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) fsub.x %fp4,%fp1 # fp1 = a := r - p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) #--|r| <= half ulp of R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) fadd.x %fp1,%fp0 # fp0 = R := A+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) #--No need to calculate r if this is the last loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) cmp.b %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) bgt.w RESTORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) #--Need to calculate r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) fsub.x %fp0,%fp3 # fp3 = A-R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) bra.w LOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) RESTORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) fmov.l %fp2,INT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) fmovm.x (%sp)+,&0x3c # restore {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) bra.w TANCONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) # satan(): computes the arctangent of a normalized number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) # satand(): computes the arctangent of a denormalized number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) # fp0 = arctan(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) # The returned result is within 2 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) # Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) # Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) # Note that k = -4, -3,..., or 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) # Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) # significant bits of X with a bit-1 attached at the 6-th #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) # bit position. Define u to be u = (X-F) / (1 + X*F). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) # Step 3. Approximate arctan(u) by a polynomial poly. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) # Step 4. Return arctan(F) + poly, arctan(F) is fetched from a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) # table of values calculated beforehand. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) # Step 5. If |X| >= 16, go to Step 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) # Step 6. Approximate arctan(X) by an odd polynomial in X. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) # Step 7. Define X' = -1/X. Approximate arctan(X') by an odd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) # polynomial in X'. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) # Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) ATANA3: long 0xBFF6687E,0x314987D8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) ATANA2: long 0x4002AC69,0x34A26DB3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) ATANA1: long 0xBFC2476F,0x4E1DA28E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) ATANB6: long 0x3FB34444,0x7F876989
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) ATANB5: long 0xBFB744EE,0x7FAF45DB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) ATANB4: long 0x3FBC71C6,0x46940220
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) ATANB3: long 0xBFC24924,0x921872F9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) ATANB2: long 0x3FC99999,0x99998FA9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) ATANB1: long 0xBFD55555,0x55555555
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) ATANC5: long 0xBFB70BF3,0x98539E6A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) ATANC4: long 0x3FBC7187,0x962D1D7D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) ATANC3: long 0xBFC24924,0x827107B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) ATANC2: long 0x3FC99999,0x9996263E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198) ATANC1: long 0xBFD55555,0x55555536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) PPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) NPIBY2: long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) PTINY: long 0x00010000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) NTINY: long 0x80010000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) ATANTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) long 0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) long 0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) long 0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) long 0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) long 0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) long 0x3FFB0000,0xAB98E943,0x62765619,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) long 0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) long 0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) long 0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) long 0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) long 0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) long 0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) long 0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) long 0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) long 0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) long 0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) long 0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) long 0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) long 0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) long 0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) long 0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) long 0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) long 0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) long 0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) long 0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) long 0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) long 0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) long 0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) long 0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) long 0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) long 0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) long 0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) long 0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) long 0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) long 0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) long 0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) long 0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) long 0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) long 0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) long 0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) long 0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) long 0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) long 0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) long 0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) long 0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) long 0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) long 0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) long 0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) long 0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) long 0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) long 0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) long 0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) long 0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) long 0x3FFE0000,0x97731420,0x365E538C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) long 0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) long 0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) long 0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) long 0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) long 0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) long 0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) long 0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) long 0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) long 0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) long 0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) long 0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) long 0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) long 0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) long 0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) long 0x3FFE0000,0xE8771129,0xC4353259,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) long 0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) long 0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) long 0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) long 0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) long 0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) long 0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) long 0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) long 0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) long 0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) long 0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) long 0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) long 0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) long 0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) long 0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) long 0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) long 0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) long 0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) long 0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294) long 0x3FFF0000,0x9F100575,0x006CC571,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) long 0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) long 0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) long 0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) long 0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) long 0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) long 0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) long 0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) long 0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) long 0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) long 0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) long 0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) long 0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) long 0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) long 0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) long 0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) long 0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) long 0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) long 0x3FFF0000,0xB525529D,0x562246BD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) long 0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) long 0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315) long 0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) long 0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) long 0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) long 0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) long 0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) long 0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) long 0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) long 0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) long 0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) long 0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) long 0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) long 0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) long 0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) long 0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) long 0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) long 0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) long 0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) long 0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) long 0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334) long 0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) set XFRACLO,X+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) set ATANF,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342) set ATANFHI,ATANF+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) set ATANFLO,ATANF+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) global satan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346) #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) satan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) cmp.l %d1,&0x3FFB8000 # |X| >= 1/16?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) bge.b ATANOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) bra.w ATANSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) ATANOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) cmp.l %d1,&0x4002FFFF # |X| < 16 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) ble.b ATANMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) bra.w ATANBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) #--WILL INVOLVE A VERY LONG POLYNOMIAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) #--WE CHOSE F TO BE +-2^K * 1.BBBB1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) ATANMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) and.l &0xF8000000,XFRAC(%a6) # FIRST 5 BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) or.l &0x04000000,XFRAC(%a6) # SET 6-TH BIT TO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) mov.l &0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) fmov.x %fp0,%fp1 # FP1 IS X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) fmul.x X(%a6),%fp1 # FP1 IS X*F, NOTE THAT X*F > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) fsub.x X(%a6),%fp0 # FP0 IS X-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) fadd.s &0x3F800000,%fp1 # FP1 IS 1 + X*F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) fdiv.x %fp1,%fp0 # FP0 IS U = (X-F)/(1+X*F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) #--CREATE ATAN(F) AND STORE IT IN ATANF, AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) #--SAVE REGISTERS FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) mov.l %d2,-(%sp) # SAVE d2 TEMPORARILY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) mov.l %d1,%d2 # THE EXP AND 16 BITS OF X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) and.l &0x00007800,%d1 # 4 VARYING BITS OF F'S FRACTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) and.l &0x7FFF0000,%d2 # EXPONENT OF F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) sub.l &0x3FFB0000,%d2 # K+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) asr.l &1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) add.l %d2,%d1 # THE 7 BITS IDENTIFYING F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) asr.l &7,%d1 # INDEX INTO TBL OF ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) lea ATANTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) add.l %d1,%a1 # ADDRESS OF ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) mov.l (%a1)+,ATANF(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) mov.l (%a1)+,ATANFHI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) mov.l (%a1)+,ATANFLO(%a6) # ATANF IS NOW ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) mov.l X(%a6),%d1 # LOAD SIGN AND EXPO. AGAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) and.l &0x80000000,%d1 # SIGN(F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) or.l %d1,ATANF(%a6) # ATANF IS NOW SIGN(F)*ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) mov.l (%sp)+,%d2 # RESTORE d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) #--THAT'S ALL I HAVE TO DO FOR NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) #--BUT ALAS, THE DIVIDE IS STILL CRANKING!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) #--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = A1/A3, A3 = A2/A3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) fmovm.x &0x04,-(%sp) # save fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) fmul.x %fp1,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) fmov.d ATANA3(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) fadd.x %fp1,%fp2 # A3+V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) fmul.x %fp1,%fp2 # V*(A3+V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) fmul.x %fp0,%fp1 # U*V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) fadd.d ATANA2(%pc),%fp2 # A2+V*(A3+V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) fmul.d ATANA1(%pc),%fp1 # A1*U*V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) fmul.x %fp2,%fp1 # A1*U*V*(A2+V*(A3+V))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) fadd.x %fp1,%fp0 # ATAN(U), FP1 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) fmovm.x (%sp)+,&0x20 # restore fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) fadd.x ATANF(%a6),%fp0 # ATAN(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) ATANBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) bgt.w ATANBIG # I.E. |X| >= 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) ATANSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) #--|X| <= 1/16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6)))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) #--WHERE Y = X*X, AND Z = Y*Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) cmp.l %d1,&0x3FD78000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) blt.w ATANTINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) #--COMPUTE POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) fmul.x %fp0,%fp0 # FPO IS Y = X*X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) fmov.d ATANB6(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) fmov.d ATANB5(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) fmul.x %fp1,%fp2 # Z*B6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) fmul.x %fp1,%fp3 # Z*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) fadd.d ATANB4(%pc),%fp2 # B4+Z*B6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) fadd.d ATANB3(%pc),%fp3 # B3+Z*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) fmul.x %fp1,%fp2 # Z*(B4+Z*B6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) fmul.x %fp3,%fp1 # Z*(B3+Z*B5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) fadd.d ATANB2(%pc),%fp2 # B2+Z*(B4+Z*B6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) fadd.d ATANB1(%pc),%fp1 # B1+Z*(B3+Z*B5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) fmul.x %fp0,%fp2 # Y*(B2+Z*(B4+Z*B6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) fmul.x X(%a6),%fp0 # X*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) fadd.x %fp2,%fp1 # [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) fmul.x %fp1,%fp0 # X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) fadd.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) ATANTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) #--|X| < 2^(-40), ATAN(X) = X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) fmov.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) ATANBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) #--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 - TINY). OTHERWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) #--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) cmp.l %d1,&0x40638000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) bgt.w ATANHUGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) #--APPROXIMATE ATAN(-1/X) BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) #--THIS CAN BE RE-WRITTEN AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) fmov.s &0xBF800000,%fp1 # LOAD -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) fdiv.x %fp0,%fp1 # FP1 IS -1/X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) #--DIVIDE IS STILL CRANKING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) fmov.x %fp1,%fp0 # FP0 IS X'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) fmul.x %fp0,%fp0 # FP0 IS Y = X'*X'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) fmov.x %fp1,X(%a6) # X IS REALLY X'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) fmov.d ATANC5(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) fmov.d ATANC4(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) fmul.x %fp1,%fp3 # Z*C5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) fmul.x %fp1,%fp2 # Z*B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) fadd.d ATANC3(%pc),%fp3 # C3+Z*C5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) fadd.d ATANC2(%pc),%fp2 # C2+Z*C4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) fmul.x %fp3,%fp1 # Z*(C3+Z*C5), FP3 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) fmul.x %fp0,%fp2 # Y*(C2+Z*C4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) fadd.d ATANC1(%pc),%fp1 # C1+Z*(C3+Z*C5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) fmul.x X(%a6),%fp0 # X'*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) fadd.x %fp2,%fp1 # [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) fmul.x %fp1,%fp0 # X'*Y*([B1+Z*(B3+Z*B5)]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) # ... +[Y*(B2+Z*(B4+Z*B6))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) fadd.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) tst.b (%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) bpl.b pos_big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) neg_big:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) fadd.x NPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) pos_big:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) fadd.x PPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) ATANHUGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) tst.b (%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) bpl.b pos_huge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) neg_huge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) fmov.x NPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) fadd.x PTINY(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) pos_huge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) fmov.x PPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) fadd.x NTINY(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) global satand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) satand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) # sasin(): computes the inverse sine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) # sasind(): computes the inverse sine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) # fp0 = arcsin(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) # ASIN #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) # 1. If |X| >= 1, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) # 2. (|X| < 1) Calculate asin(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) # z := sqrt( [1-X][1+X] ) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) # asin(X) = atan( x / z ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) # 3. If |X| > 1, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) # 4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) global sasin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) sasin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) bge.b ASINBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) # This catch is added here for the '060 QSP. Originally, the call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) # satan() would handle this case by causing the exception which would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) # not be caught until gen_except(). Now, with the exceptions being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) # detected inside of satan(), the exception would have been handled there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) # instead of inside sasin() as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) cmp.l %d1,&0x3FD78000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) blt.w ASINTINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) #--THIS IS THE USUAL CASE, |X| < 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) ASINMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) fsub.x %fp0,%fp1 # 1-X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) fmovm.x &0x4,-(%sp) # {fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) fmov.s &0x3F800000,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) fadd.x %fp0,%fp2 # 1+X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) fmul.x %fp2,%fp1 # (1+X)(1-X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) fmovm.x (%sp)+,&0x20 # {fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) fsqrt.x %fp1 # SQRT([1-X][1+X])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) fdiv.x %fp1,%fp0 # X/SQRT([1-X][1+X])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) fmovm.x &0x01,-(%sp) # save X/SQRT(...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) lea (%sp),%a0 # pass ptr to X/SQRT(...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) bsr satan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) add.l &0xc,%sp # clear X/SQRT(...) from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) ASINBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) fabs.x %fp0 # |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) fcmp.s %fp0,&0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) fbgt t_operr # cause an operr exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) #--|X| = 1, ASIN(X) = +- PI/2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) ASINONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) fmov.x PIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) and.l &0x80000000,%d1 # SIGN BIT OF X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) or.l &0x3F800000,%d1 # +-1 IN SGL FORMAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) mov.l %d1,-(%sp) # push SIGN(X) IN SGL-FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) fmul.s (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) #--|X| < 2^(-40), ATAN(X) = X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) ASINTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) fmov.x (%a0),%fp0 # last inst - possible exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) global sasind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) #--ASIN(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) sasind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) # sacos(): computes the inverse cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) # sacosd(): computes the inverse cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) # fp0 = arccos(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) # ACOS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) # 1. If |X| >= 1, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) # 2. (|X| < 1) Calculate acos(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) # z := (1-X) / (1+X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) # acos(X) = 2 * atan( sqrt(z) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720) # 3. If |X| > 1, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) # 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) # #
^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) global sacos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) sacos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) mov.l (%a0),%d1 # pack exp w/ upper 16 fraction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) bge.b ACOSBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) #--THIS IS THE USUAL CASE, |X| < 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) #--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) ACOSMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) fadd.x %fp0,%fp1 # 1+X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) fneg.x %fp0 # -X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) fadd.s &0x3F800000,%fp0 # 1-X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) fdiv.x %fp1,%fp0 # (1-X)/(1+X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) fsqrt.x %fp0 # SQRT((1-X)/(1+X))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) mov.l %d0,-(%sp) # save original users fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) fmovm.x &0x01,-(%sp) # save SQRT(...) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) lea (%sp),%a0 # pass ptr to sqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) bsr satan # ATAN(SQRT([1-X]/[1+X]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) add.l &0xc,%sp # clear SQRT(...) from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) fmov.l (%sp)+,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) fadd.x %fp0,%fp0 # 2 * ATAN( STUFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) ACOSBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) fabs.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) fcmp.s %fp0,&0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) fbgt t_operr # cause an operr exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) #--|X| = 1, ACOS(X) = 0 OR PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) tst.b (%a0) # is X positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) bpl.b ACOSP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) #--X = -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) #Returns PI and inexact exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) ACOSM1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) fmov.x PI(%pc),%fp0 # load PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) fmov.l %d0,%fpcr # load round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) fadd.s &0x00800000,%fp0 # add a small value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) ACOSP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) bra ld_pzero # answer is positive zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) global sacosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) #--ACOS(X) = PI/2 FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) sacosd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) fmov.l %d0,%fpcr # load user's rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) fmov.x PIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) bra t_pinx2
^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) # setox(): computes the exponential for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789) # setoxd(): computes the exponential for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) # setoxm1(): computes the exponential minus 1 for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) # setoxm1d(): computes the exponential minus 1 for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) # fp0 = exp(X) or exp(X)-1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) # The returned result is within 0.85 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) # ALGORITHM and IMPLEMENTATION **************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) # setoxd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) # ------ #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) # Step 1. Set ans := 1.0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) # Step 2. Return ans := ans + sign(X)*2^(-126). Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) # Notes: This will always generate one exception -- inexact. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) # setox #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) # ----- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) # Step 1. Filter out extreme cases of input argument. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) # 1.1 If |X| >= 2^(-65), go to Step 1.3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) # 1.2 Go to Step 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) # 1.3 If |X| < 16380 log(2), go to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) # 1.4 Go to Step 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) # To avoid the use of floating-point comparisons, a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) # compact representation of |X| is used. This format is a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) # 32-bit integer, the upper (more significant) 16 bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) # are the sign and biased exponent field of |X|; the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) # lower 16 bits are the 16 most significant fraction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) # (including the explicit bit) bits of |X|. Consequently, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) # the comparisons in Steps 1.1 and 1.3 can be performed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) # by integer comparison. Note also that the constant #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) # 16380 log(2) used in Step 1.3 is also in the compact #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) # form. Thus taking the branch to Step 2 guarantees #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) # |X| < 16380 log(2). There is no harm to have a small #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) # number of cases where |X| is less than, but close to, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) # 16380 log(2) and the branch to Step 9 is taken. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) # 2.1 Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) # was taken) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) # 2.2 N := round-to-nearest-integer( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) # 2.3 Calculate J = N mod 64; so J = 0,1,2,..., #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) # or 63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) # 2.4 Calculate M = (N - J)/64; so N = 64M + J. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) # 2.5 Calculate the address of the stored value of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) # 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) # 2.6 Create the value Scale = 2^M. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) # Notes: The calculation in 2.2 is really performed by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) # Z := X * constant #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) # N := round-to-nearest-integer(Z) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) # where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) # constant := single-precision( 64/log 2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) # Using a single-precision constant avoids memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) # access. Another effect of using a single-precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) # "constant" is that the calculated value Z is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) # Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) # This error has to be considered later in Steps 3 and 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) # Step 3. Calculate X - N*log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) # 3.1 R := X + N*L1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) # where L1 := single-precision(-log2/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) # 3.2 R := R + N*L2, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) # L2 := extended-precision(-log2/64 - L1).#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) # Notes: a) The way L1 and L2 are chosen ensures L1+L2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) # approximate the value -log2/64 to 88 bits of accuracy. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) # b) N*L1 is exact because N is no longer than 22 bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) # and L1 is no longer than 24 bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) # c) The calculation X+N*L1 is also exact due to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) # cancellation. Thus, R is practically X+N(L1+L2) to full #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) # 64 bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) # d) It is important to estimate how large can |R| be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) # after Step 3.2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) # N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) # X*64/log2 (1+eps) = N + f, |f| <= 0.5 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) # X*64/log2 - N = f - eps*X 64/log2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) # X - N*log2/64 = f*log2/64 - eps*X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) # Now |X| <= 16446 log2, thus #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) # |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) # <= 0.57 log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) # This bound will be used in Step 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) # Step 4. Approximate exp(R)-1 by a polynomial #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) # p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) # Notes: a) In order to reduce memory access, the coefficients #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) # are made as "short" as possible: A1 (which is 1/2), A4 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) # and A5 are single precision; A2 and A3 are double #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) # precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) # b) Even with the restrictions above, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) # |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) # Note that 0.0062 is slightly bigger than 0.57 log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) # c) To fully utilize the pipeline, p is separated into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) # two independent pieces of roughly equal complexities #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) # p = [ R + R*S*(A2 + S*A4) ] + #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) # [ S*(A1 + S*(A3 + S*A5)) ] #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) # where S = R*R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) # Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) # ans := T + ( T*p + t) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) # where T and t are the stored values for 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) # Notes: 2^(J/64) is stored as T and t where T+t approximates #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) # 2^(J/64) to roughly 85 bits; T is in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) # and t is in single precision. Note also that T is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) # rounded to 62 bits so that the last two bits of T are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) # zero. The reason for such a special form is that T-1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) # T-2, and T-8 will all be exact --- a property that will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) # give much more accurate computation of the function #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) # EXPM1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) # Step 6. Reconstruction of exp(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) # exp(X) = 2^M * 2^(J/64) * exp(R). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) # 6.1 If AdjFlag = 0, go to 6.3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) # 6.2 ans := ans * AdjScale #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) # 6.3 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) # 6.4 Return ans := ans * Scale. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) # Notes: If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) # |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) # neither overflow nor underflow. If AdjFlag = 1, that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) # means that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) # X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) # Hence, exp(X) may overflow or underflow or neither. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) # When that is the case, AdjScale = 2^(M1) where M1 is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) # approximately M. Thus 6.2 will never cause #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) # over/underflow. Possible exception in 6.4 is overflow #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) # or underflow. The inexact exception is not generated in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) # 6.4. Although one can argue that the inexact flag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) # should always be raised, to simulate that exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) # cost to much than the flag is worth in practical uses. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) # Step 7. Return 1 + X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) # 7.1 ans := X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) # 7.2 Restore user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) # 7.3 Return ans := 1 + ans. Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) # Notes: For non-zero X, the inexact exception will always be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) # raised by 7.3. That is the only exception raised by 7.3.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) # Note also that we use the FMOVEM instruction to move X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) # in Step 7.1 to avoid unnecessary trapping. (Although #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) # the FMOVEM may not seem relevant since X is normalized, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) # the precaution will be useful in the library version of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) # this code where the separate entry for denormalized #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) # inputs will be done away with.) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) # Step 8. Handle exp(X) where |X| >= 16380log2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) # 8.1 If |X| > 16480 log2, go to Step 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) # (mimic 2.2 - 2.6) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) # 8.2 N := round-to-integer( X * 64/log2 ) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) # 8.3 Calculate J = N mod 64, J = 0,1,...,63 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) # 8.4 K := (N-J)/64, M1 := truncate(K/2), M = K-M1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) # AdjFlag := 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) # 8.5 Calculate the address of the stored value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) # 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) # 8.6 Create the values Scale = 2^M, AdjScale = 2^M1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) # 8.7 Go to Step 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) # Notes: Refer to notes for 2.2 - 2.6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) # Step 9. Handle exp(X), |X| > 16480 log2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) # 9.1 If X < 0, go to 9.3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) # 9.2 ans := Huge, go to 9.4 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) # 9.3 ans := Tiny. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) # 9.4 Restore user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) # 9.5 Return ans := ans * ans. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) # Notes: Exp(X) will surely overflow or underflow, depending on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) # X's sign. "Huge" and "Tiny" are respectively large/tiny #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971) # extended-precision numbers whose square over/underflow #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) # with an inexact result. Thus, 9.5 always raises the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) # inexact together with either overflow or underflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) # setoxm1d #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) # -------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) # Step 1. Set ans := 0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) # Step 2. Return ans := X + ans. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) # Notes: This will return X with the appropriate rounding #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) # precision prescribed by the user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) # setoxm1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) # ------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) # Step 1. Check |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) # 1.1 If |X| >= 1/4, go to Step 1.3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) # 1.2 Go to Step 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) # 1.3 If |X| < 70 log(2), go to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) # 1.4 Go to Step 10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992) # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) # However, it is conceivable |X| can be small very often #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) # because EXPM1 is intended to evaluate exp(X)-1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) # accurately when |X| is small. For further details on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) # the comparisons, see the notes on Step 1 of setox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) # 2.1 N := round-to-nearest-integer( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) # 2.2 Calculate J = N mod 64; so J = 0,1,2,..., #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001) # or 63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) # 2.3 Calculate M = (N - J)/64; so N = 64M + J. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) # 2.4 Calculate the address of the stored value of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) # 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) # 2.5 Create the values Sc = 2^M and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006) # OnebySc := -2^(-M). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) # Notes: See the notes on Step 2 of setox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) # Step 3. Calculate X - N*log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) # 3.1 R := X + N*L1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) # where L1 := single-precision(-log2/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) # 3.2 R := R + N*L2, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) # L2 := extended-precision(-log2/64 - L1).#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) # Notes: Applying the analysis of Step 3 of setox in this case #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) # shows that |R| <= 0.0055 (note that |X| <= 70 log2 in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) # this case). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) # Step 4. Approximate exp(R)-1 by a polynomial #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) # p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6))))) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020) # Notes: a) In order to reduce memory access, the coefficients #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) # are made as "short" as possible: A1 (which is 1/2), A5 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) # and A6 are single precision; A2, A3 and A4 are double #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) # precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) # b) Even with the restriction above, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) # |p - (exp(R)-1)| < |R| * 2^(-72.7) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) # for all |R| <= 0.0055. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) # c) To fully utilize the pipeline, p is separated into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) # two independent pieces of roughly equal complexity #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) # p = [ R*S*(A2 + S*(A4 + S*A6)) ] + #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) # [ R + S*(A1 + S*(A3 + S*A5)) ] #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) # where S = R*R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) # Step 5. Compute 2^(J/64)*p by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) # p := T*p #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) # where T and t are the stored values for 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) # Notes: 2^(J/64) is stored as T and t where T+t approximates #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) # 2^(J/64) to roughly 85 bits; T is in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038) # and t is in single precision. Note also that T is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) # rounded to 62 bits so that the last two bits of T are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) # zero. The reason for such a special form is that T-1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) # T-2, and T-8 will all be exact --- a property that will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) # be exploited in Step 6 below. The total relative error #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) # in p is no bigger than 2^(-67.7) compared to the final #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) # result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) # Step 6. Reconstruction of exp(X)-1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) # exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) # 6.1 If M <= 63, go to Step 6.3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) # 6.2 ans := T + (p + (t + OnebySc)). Go to 6.6 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) # 6.3 If M >= -3, go to 6.5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) # 6.4 ans := (T + (p + t)) + OnebySc. Go to 6.6 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) # 6.5 ans := (T + OnebySc) + (p + t). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) # 6.6 Restore user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) # 6.7 Return ans := Sc * ans. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) # Notes: The various arrangements of the expressions give #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) # accurate evaluations. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) # Step 7. exp(X)-1 for |X| < 1/4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) # 7.1 If |X| >= 2^(-65), go to Step 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) # 7.2 Go to Step 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062) # Step 8. Calculate exp(X)-1, |X| < 2^(-65). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) # 8.1 If |X| < 2^(-16312), goto 8.3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) # 8.2 Restore FPCR; return ans := X - 2^(-16382). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) # 8.3 X := X * 2^(140). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) # 8.4 Restore FPCR; ans := ans - 2^(-16382). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) # Return ans := ans*2^(140). Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) # Notes: The idea is to return "X - tiny" under the user #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) # precision and rounding modes. To avoid unnecessary #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) # inefficiency, we stay away from denormalized numbers #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) # the best we can. For |X| >= 2^(-16312), the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) # straightforward 8.2 generates the inexact exception as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) # the case warrants. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) # Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) # p = X + X*X*(B1 + X*(B2 + ... + X*B12)) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) # Notes: a) In order to reduce memory access, the coefficients #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) # are made as "short" as possible: B1 (which is 1/2), B9 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) # to B12 are single precision; B3 to B8 are double #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) # precision; and B2 is double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) # b) Even with the restriction above, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) # |p - (exp(X)-1)| < |X| 2^(-70.6) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) # for all |X| <= 0.251. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) # Note that 0.251 is slightly bigger than 1/4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) # c) To fully preserve accuracy, the polynomial is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) # computed as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) # X + ( S*B1 + Q ) where S = X*X and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) # Q = X*S*(B2 + X*(B3 + ... + X*B12)) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) # d) To fully utilize the pipeline, Q is separated into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) # two independent pieces of roughly equal complexity #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) # Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] + #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093) # [ S*S*(B3 + S*(B5 + ... + S*B11)) ] #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) # Step 10. Calculate exp(X)-1 for |X| >= 70 log 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) # 10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) # practical purposes. Therefore, go to Step 1 of setox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) # 10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) # purposes. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) # ans := -1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) # Restore user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) # Return ans := ans + 2^(-126). Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103) # Notes: 10.2 will always create an inexact and return -1 + tiny #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) # in the user rounding precision and mode. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) L2: long 0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) EEXPA3: long 0x3FA55555,0x55554CC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) EEXPA2: long 0x3FC55555,0x55554A54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) EM1A4: long 0x3F811111,0x11174385
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) EM1A3: long 0x3FA55555,0x55554F5A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) EM1A2: long 0x3FC55555,0x55555555,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) EM1B8: long 0x3EC71DE3,0xA5774682
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) EM1B7: long 0x3EFA01A0,0x19D7CB68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) EM1B6: long 0x3F2A01A0,0x1A019DF3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122) EM1B5: long 0x3F56C16C,0x16C170E2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124) EM1B4: long 0x3F811111,0x11111111
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125) EM1B3: long 0x3FA55555,0x55555555
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) EM1B2: long 0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128) long 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) TWO140: long 0x48B00000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131) TWON140:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) long 0x37300000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134) EEXPTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) long 0x3FFF0000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) long 0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) long 0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138) long 0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) long 0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140) long 0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) long 0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) long 0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) long 0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) long 0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150) long 0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151) long 0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) long 0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153) long 0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) long 0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) long 0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) long 0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) long 0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158) long 0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) long 0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160) long 0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162) long 0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) long 0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) long 0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) long 0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) long 0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) long 0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) long 0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) long 0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) long 0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) long 0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172) long 0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) long 0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174) long 0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175) long 0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) long 0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) long 0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) long 0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) long 0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) long 0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) long 0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) long 0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) long 0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185) long 0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) long 0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187) long 0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) long 0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189) long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) long 0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192) long 0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) long 0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195) long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) long 0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) long 0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) long 0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) set ADJFLAG,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) set SCALE,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) set ADJSCALE,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) set SC,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) set ONEBYSC,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) global setox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) setox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) #--entry point for EXP(X), here X is finite, non-zero, and not NaN's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) #--Step 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) mov.l (%a0),%d1 # load part of input X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212) and.l &0x7FFF0000,%d1 # biased expo. of X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213) cmp.l %d1,&0x3FBE0000 # 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214) bge.b EXPC1 # normal case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) bra EXPSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) EXPC1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218) #--The case |X| >= 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219) mov.w 4(%a0),%d1 # expo. and partial sig. of |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) cmp.l %d1,&0x400CB167 # 16380 log2 trunc. 16 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) blt.b EXPMAIN # normal case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) bra EEXPBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) EXPMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) #--Step 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226) #--This is the normal branch: 2^(-65) <= |X| < 16380 log2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) fmov.x (%a0),%fp0 # load input from (a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) mov.l &0,ADJFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) fmov.l %fp0,%d1 # N = int( X * 64/log2 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) lea EEXPTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) fmov.l %d1,%fp0 # convert to floating-format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) mov.l %d1,L_SCR1(%a6) # save N temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) and.l &0x3F,%d1 # D0 is J = N mod 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) lsl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) add.l %d1,%a1 # address of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) mov.l L_SCR1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) asr.l &6,%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243) add.w &0x3FFF,%d1 # biased expo. of 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244) mov.w L2(%pc),L_SCR1(%a6) # prefetch L2, no need in CB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246) EXPCONT1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247) #--Step 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249) #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251) fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253) fadd.x %fp1,%fp0 # X + N*L1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) fadd.x %fp2,%fp0 # fp0 is R, reduced arg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256) #--Step 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258) #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) fmul.x %fp1,%fp1 # fp1 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265) fmov.s &0x3AB60B70,%fp2 # fp2 IS A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) fmul.x %fp1,%fp2 # fp2 IS S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268) fmov.x %fp1,%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) fmul.s &0x3C088895,%fp3 # fp3 IS S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271) fadd.d EEXPA3(%pc),%fp2 # fp2 IS A3+S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) fadd.d EEXPA2(%pc),%fp3 # fp3 IS A2+S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274) fmul.x %fp1,%fp2 # fp2 IS S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) mov.w %d1,SCALE(%a6) # SCALE is 2^(M) in extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276) mov.l &0x80000000,SCALE+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277) clr.l SCALE+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) fmul.x %fp1,%fp3 # fp3 IS S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) fadd.s &0x3F000000,%fp2 # fp2 IS A1+S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282) fmul.x %fp0,%fp3 # fp3 IS R*S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) fmul.x %fp1,%fp2 # fp2 IS S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285) fadd.x %fp3,%fp0 # fp0 IS R+R*S*(A2+S*A4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287) fmov.x (%a1)+,%fp1 # fp1 is lead. pt. of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) fadd.x %fp2,%fp0 # fp0 is EXP(R) - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290) #--Step 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291) #--final reconstruction process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294) fmul.x %fp1,%fp0 # 2^(J/64)*(Exp(R)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296) fadd.s (%a1),%fp0 # accurate 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) fadd.x %fp1,%fp0 # 2^(J/64) + 2^(J/64)*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299) mov.l ADJFLAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301) #--Step 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302) tst.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303) beq.b NORMAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) ADJUST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) fmul.x ADJSCALE(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306) NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) fmov.l %d0,%fpcr # restore user FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) fmul.x SCALE(%a6),%fp0 # multiply 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312) EXPSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) #--Step 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) fmovm.x (%a0),&0x80 # load X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) fadd.s &0x3F800000,%fp0 # 1+X in user mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) EEXPBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320) #--Step 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321) cmp.l %d1,&0x400CB27C # 16480 log2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322) bgt.b EXP2BIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323) #--Steps 8.2 -- 8.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324) fmov.x (%a0),%fp0 # load input from (a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327) fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329) mov.l &1,ADJFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330) fmov.l %fp0,%d1 # N = int( X * 64/log2 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) lea EEXPTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) fmov.l %d1,%fp0 # convert to floating-format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333) mov.l %d1,L_SCR1(%a6) # save N temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) and.l &0x3F,%d1 # D0 is J = N mod 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335) lsl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336) add.l %d1,%a1 # address of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) mov.l L_SCR1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) asr.l &6,%d1 # D0 is K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) mov.l %d1,L_SCR1(%a6) # save K temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340) asr.l &1,%d1 # D0 is M1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341) sub.l %d1,L_SCR1(%a6) # a1 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) add.w &0x3FFF,%d1 # biased expo. of 2^(M1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343) mov.w %d1,ADJSCALE(%a6) # ADJSCALE := 2^(M1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344) mov.l &0x80000000,ADJSCALE+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) clr.l ADJSCALE+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) mov.l L_SCR1(%a6),%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347) add.w &0x3FFF,%d1 # biased expo. of 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348) bra.w EXPCONT1 # go back to Step 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) EXP2BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351) #--Step 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352) tst.b (%a0) # is X positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353) bmi t_unfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354) bra t_ovfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356) global setoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357) setoxd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358) #--entry point for EXP(X), X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359) mov.l (%a0),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360) andi.l &0x80000000,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) ori.l &0x00800000,(%sp) # sign(X)*2^(-126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363) fmov.s &0x3F800000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366) fadd.s (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369) global setoxm1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) setoxm1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371) #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) #--Step 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) #--Step 1.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) mov.l (%a0),%d1 # load part of input X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376) and.l &0x7FFF0000,%d1 # biased expo. of X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377) cmp.l %d1,&0x3FFD0000 # 1/4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378) bge.b EM1CON1 # |X| >= 1/4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) bra EM1SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381) EM1CON1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) #--Step 1.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383) #--The case |X| >= 1/4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384) mov.w 4(%a0),%d1 # expo. and partial sig. of |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) cmp.l %d1,&0x4004C215 # 70log2 rounded up to 16 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386) ble.b EM1MAIN # 1/4 <= |X| <= 70log2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387) bra EM1BIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389) EM1MAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390) #--Step 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) #--This is the case: 1/4 <= |X| <= 70 log2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) fmov.x (%a0),%fp0 # load input from (a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395) fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) fmov.l %fp0,%d1 # N = int( X * 64/log2 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398) lea EEXPTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399) fmov.l %d1,%fp0 # convert to floating-format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) mov.l %d1,L_SCR1(%a6) # save N temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402) and.l &0x3F,%d1 # D0 is J = N mod 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403) lsl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) add.l %d1,%a1 # address of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) mov.l L_SCR1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406) asr.l &6,%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) mov.l %d1,L_SCR1(%a6) # save a copy of M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409) #--Step 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411) #--a0 points to 2^(J/64), D0 and a1 both contain M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413) fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414) fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) fadd.x %fp1,%fp0 # X + N*L1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416) fadd.x %fp2,%fp0 # fp0 is R, reduced arg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417) add.w &0x3FFF,%d1 # D0 is biased expo. of 2^M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) #--Step 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420) #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421) #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422) #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423) #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426) fmul.x %fp1,%fp1 # fp1 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428) fmov.s &0x3950097B,%fp2 # fp2 IS a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) fmul.x %fp1,%fp2 # fp2 IS S*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) fmov.x %fp1,%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) fmul.s &0x3AB60B6A,%fp3 # fp3 IS S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434) fadd.d EM1A4(%pc),%fp2 # fp2 IS A4+S*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435) fadd.d EM1A3(%pc),%fp3 # fp3 IS A3+S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436) mov.w %d1,SC(%a6) # SC is 2^(M) in extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437) mov.l &0x80000000,SC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438) clr.l SC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440) fmul.x %fp1,%fp2 # fp2 IS S*(A4+S*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441) mov.l L_SCR1(%a6),%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442) neg.w %d1 # D0 is -M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) fmul.x %fp1,%fp3 # fp3 IS S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444) add.w &0x3FFF,%d1 # biased expo. of 2^(-M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445) fadd.d EM1A2(%pc),%fp2 # fp2 IS A2+S*(A4+S*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) fadd.s &0x3F000000,%fp3 # fp3 IS A1+S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448) fmul.x %fp1,%fp2 # fp2 IS S*(A2+S*(A4+S*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449) or.w &0x8000,%d1 # signed/expo. of -2^(-M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) mov.w %d1,ONEBYSC(%a6) # OnebySc is -2^(-M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451) mov.l &0x80000000,ONEBYSC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) clr.l ONEBYSC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453) fmul.x %fp3,%fp1 # fp1 IS S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7455) fmul.x %fp0,%fp2 # fp2 IS R*S*(A2+S*(A4+S*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456) fadd.x %fp1,%fp0 # fp0 IS R+S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458) fadd.x %fp2,%fp0 # fp0 IS EXP(R)-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460) fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) #--Step 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463) #--Compute 2^(J/64)*p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465) fmul.x (%a1),%fp0 # 2^(J/64)*(Exp(R)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) #--Step 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468) #--Step 6.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469) mov.l L_SCR1(%a6),%d1 # retrieve M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470) cmp.l %d1,&63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471) ble.b MLE63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472) #--Step 6.2 M >= 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473) fmov.s 12(%a1),%fp1 # fp1 is t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) fadd.x ONEBYSC(%a6),%fp1 # fp1 is t+OnebySc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475) fadd.x %fp1,%fp0 # p+(t+OnebySc), fp1 released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) fadd.x (%a1),%fp0 # T+(p+(t+OnebySc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477) bra EM1SCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) MLE63:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479) #--Step 6.3 M <= 63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480) cmp.l %d1,&-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481) bge.b MGEN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482) MLTN3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483) #--Step 6.4 M <= -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484) fadd.s 12(%a1),%fp0 # p+t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) fadd.x (%a1),%fp0 # T+(p+t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486) fadd.x ONEBYSC(%a6),%fp0 # OnebySc + (T+(p+t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487) bra EM1SCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488) MGEN3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489) #--Step 6.5 -3 <= M <= 63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) fmov.x (%a1)+,%fp1 # fp1 is T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491) fadd.s (%a1),%fp0 # fp0 is p+t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) fadd.x ONEBYSC(%a6),%fp1 # fp1 is T+OnebySc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493) fadd.x %fp1,%fp0 # (T+OnebySc)+(p+t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) EM1SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) #--Step 6.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) fmul.x SC(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) EM1SM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502) #--Step 7 |X| < 1/4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503) cmp.l %d1,&0x3FBE0000 # 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504) bge.b EM1POLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506) EM1TINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507) #--Step 8 |X| < 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) cmp.l %d1,&0x00330000 # 2^(-16312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) blt.b EM12TINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510) #--Step 8.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) mov.l &0x80010000,SC(%a6) # SC is -2^(-16382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) mov.l &0x80000000,SC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) clr.l SC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514) fmov.x (%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) mov.b &FADD_OP,%d1 # last inst is ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) fadd.x SC(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520) EM12TINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) #--Step 8.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522) fmov.x (%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523) fmul.d TWO140(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524) mov.l &0x80010000,SC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525) mov.l &0x80000000,SC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526) clr.l SC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527) fadd.x SC(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530) fmul.d TWON140(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7533) EM1POLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7534) #--Step 9 exp(X)-1 by a simple polynomial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7535) fmov.x (%a0),%fp0 # fp0 is X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7536) fmul.x %fp0,%fp0 # fp0 is S := X*X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7537) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7538) fmov.s &0x2F30CAA8,%fp1 # fp1 is B12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7539) fmul.x %fp0,%fp1 # fp1 is S*B12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7540) fmov.s &0x310F8290,%fp2 # fp2 is B11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7541) fadd.s &0x32D73220,%fp1 # fp1 is B10+S*B12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7543) fmul.x %fp0,%fp2 # fp2 is S*B11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7544) fmul.x %fp0,%fp1 # fp1 is S*(B10 + ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7546) fadd.s &0x3493F281,%fp2 # fp2 is B9+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7547) fadd.d EM1B8(%pc),%fp1 # fp1 is B8+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7549) fmul.x %fp0,%fp2 # fp2 is S*(B9+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7550) fmul.x %fp0,%fp1 # fp1 is S*(B8+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7552) fadd.d EM1B7(%pc),%fp2 # fp2 is B7+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7553) fadd.d EM1B6(%pc),%fp1 # fp1 is B6+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7555) fmul.x %fp0,%fp2 # fp2 is S*(B7+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7556) fmul.x %fp0,%fp1 # fp1 is S*(B6+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7558) fadd.d EM1B5(%pc),%fp2 # fp2 is B5+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7559) fadd.d EM1B4(%pc),%fp1 # fp1 is B4+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7561) fmul.x %fp0,%fp2 # fp2 is S*(B5+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7562) fmul.x %fp0,%fp1 # fp1 is S*(B4+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7564) fadd.d EM1B3(%pc),%fp2 # fp2 is B3+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7565) fadd.x EM1B2(%pc),%fp1 # fp1 is B2+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7567) fmul.x %fp0,%fp2 # fp2 is S*(B3+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7568) fmul.x %fp0,%fp1 # fp1 is S*(B2+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7570) fmul.x %fp0,%fp2 # fp2 is S*S*(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7571) fmul.x (%a0),%fp1 # fp1 is X*S*(B2...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7573) fmul.s &0x3F000000,%fp0 # fp0 is S*B1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7574) fadd.x %fp2,%fp1 # fp1 is Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7576) fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7578) fadd.x %fp1,%fp0 # fp0 is S*B1+Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7580) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7581) fadd.x (%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7582) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7584) EM1BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7585) #--Step 10 |X| > 70 log2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7586) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7587) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7588) bgt.w EXPC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7589) #--Step 10.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7590) fmov.s &0xBF800000,%fp0 # fp0 is -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7591) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7592) fadd.s &0x00800000,%fp0 # -1 + 2^(-126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7593) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7595) global setoxm1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7596) setoxm1d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7597) #--entry point for EXPM1(X), here X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7598) #--Step 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7599) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7601) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7602) # sgetexp(): returns the exponent portion of the input argument. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7603) # The exponent bias is removed and the exponent value is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7604) # returned as an extended precision number in fp0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7605) # sgetexpd(): handles denormalized numbers. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7606) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7607) # sgetman(): extracts the mantissa of the input argument. The #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7608) # mantissa is converted to an extended precision number w/ #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7609) # an exponent of $3fff and is returned in fp0. The range of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7610) # the result is [1.0 - 2.0). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7611) # sgetmand(): handles denormalized numbers. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7612) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7613) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7614) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7615) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7616) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7617) # fp0 = exponent(X) or mantissa(X) #
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7621) global sgetexp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7622) sgetexp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7623) mov.w SRC_EX(%a0),%d0 # get the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7624) bclr &0xf,%d0 # clear the sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7625) subi.w &0x3fff,%d0 # subtract off the bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7626) fmov.w %d0,%fp0 # return exp in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7627) blt.b sgetexpn # it's negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7628) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7630) sgetexpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7631) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7632) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7634) global sgetexpd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7635) sgetexpd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7636) bsr.l norm # normalize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7637) neg.w %d0 # new exp = -(shft amt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7638) subi.w &0x3fff,%d0 # subtract off the bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7639) fmov.w %d0,%fp0 # return exp in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7640) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7641) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7643) global sgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7644) sgetman:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7645) mov.w SRC_EX(%a0),%d0 # get the exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7646) ori.w &0x7fff,%d0 # clear old exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7647) bclr &0xe,%d0 # make it the new exp +-3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7649) # here, we build the result in a tmp location so as not to disturb the input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7650) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7651) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7652) mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7653) fmov.x FP_SCR0(%a6),%fp0 # put new value back in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7654) bmi.b sgetmann # it's negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7655) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7657) sgetmann:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7658) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7659) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7661) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7662) # For denormalized numbers, shift the mantissa until the j-bit = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7663) # then load the exponent with +/1 $3fff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7664) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7665) global sgetmand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7666) sgetmand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7667) bsr.l norm # normalize exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7668) bra.b sgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7670) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7671) # scosh(): computes the hyperbolic cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7672) # scoshd(): computes the hyperbolic cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7673) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7674) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7675) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7676) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7677) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7678) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7679) # fp0 = cosh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7680) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7681) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7682) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7683) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7684) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7685) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7686) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7687) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7688) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7689) # COSH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7690) # 1. If |X| > 16380 log2, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7691) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7692) # 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7693) # y = |X|, z = exp(Y), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7694) # cosh(X) = (1/2)*( z + 1/z ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7695) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7696) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7697) # 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7698) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7699) # 4. (16380 log2 < |X| <= 16480 log2) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7700) # cosh(X) = sign(X) * exp(|X|)/2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7701) # However, invoking exp(|X|) may cause premature #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7702) # overflow. Thus, we calculate sinh(X) as follows: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7703) # Y := |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7704) # Fact := 2**(16380) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7705) # Y' := Y - 16381 log2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7706) # cosh(X) := Fact * exp(Y'). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7707) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7708) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7709) # 5. (|X| > 16480 log2) sinh(X) must overflow. Return #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7710) # Huge*Huge to generate overflow and an infinity with #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7711) # the appropriate sign. Huge is the largest finite number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7712) # in extended format. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7713) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7714) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7716) TWO16380:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7717) long 0x7FFB0000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7719) global scosh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7720) scosh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7721) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7723) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7724) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7725) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7726) cmp.l %d1,&0x400CB167
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7727) bgt.b COSHBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7729) #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7730) #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7732) fabs.x %fp0 # |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7734) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7735) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7736) fmovm.x &0x01,-(%sp) # save |X| to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7737) lea (%sp),%a0 # pass ptr to |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7738) bsr setox # FP0 IS EXP(|X|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7739) add.l &0xc,%sp # erase |X| from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7740) fmul.s &0x3F000000,%fp0 # (1/2)EXP(|X|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7741) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7743) fmov.s &0x3E800000,%fp1 # (1/4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7744) fdiv.x %fp0,%fp1 # 1/(2 EXP(|X|))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7746) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7747) mov.b &FADD_OP,%d1 # last inst is ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7748) fadd.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7749) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7751) COSHBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7752) cmp.l %d1,&0x400CB2B3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7753) bgt.b COSHHUGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7755) fabs.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7756) fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7757) fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7759) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7760) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7761) fmovm.x &0x01,-(%sp) # save fp0 to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7762) lea (%sp),%a0 # pass ptr to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7763) bsr setox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7764) add.l &0xc,%sp # clear fp0 from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7765) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7767) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7768) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7769) fmul.x TWO16380(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7770) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7772) COSHHUGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7773) bra t_ovfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7775) global scoshd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7776) #--COSH(X) = 1 FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7777) scoshd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7778) fmov.s &0x3F800000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7780) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7781) fadd.s &0x00800000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7782) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7784) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7785) # ssinh(): computes the hyperbolic sine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7786) # ssinhd(): computes the hyperbolic sine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7787) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7788) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7789) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7790) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7791) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7792) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7793) # fp0 = sinh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7794) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7795) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7796) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7797) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7798) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7799) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7800) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7801) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7802) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7803) # SINH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7804) # 1. If |X| > 16380 log2, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7805) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7806) # 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7807) # y = |X|, sgn = sign(X), and z = expm1(Y), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7808) # sinh(X) = sgn*(1/2)*( z + z/(1+z) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7809) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7810) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7811) # 3. If |X| > 16480 log2, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7812) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7813) # 4. (16380 log2 < |X| <= 16480 log2) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7814) # sinh(X) = sign(X) * exp(|X|)/2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7815) # However, invoking exp(|X|) may cause premature overflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7816) # Thus, we calculate sinh(X) as follows: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7817) # Y := |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7818) # sgn := sign(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7819) # sgnFact := sgn * 2**(16380) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7820) # Y' := Y - 16381 log2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7821) # sinh(X) := sgnFact * exp(Y'). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7822) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7823) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7824) # 5. (|X| > 16480 log2) sinh(X) must overflow. Return #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7825) # sign(X)*Huge*Huge to generate overflow and an infinity with #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7826) # the appropriate sign. Huge is the largest finite number in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7827) # extended format. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7828) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7829) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7831) global ssinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7832) ssinh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7833) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7835) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7836) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7837) mov.l %d1,%a1 # save (compacted) operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7838) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7839) cmp.l %d1,&0x400CB167
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7840) bgt.b SINHBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7842) #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7843) #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7845) fabs.x %fp0 # Y = |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7847) movm.l &0x8040,-(%sp) # {a1/d0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7848) fmovm.x &0x01,-(%sp) # save Y on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7849) lea (%sp),%a0 # pass ptr to Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7850) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7851) bsr setoxm1 # FP0 IS Z = EXPM1(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7852) add.l &0xc,%sp # clear Y from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7853) fmov.l &0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7854) movm.l (%sp)+,&0x0201 # {a1/d0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7856) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7857) fadd.s &0x3F800000,%fp1 # 1+Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7858) fmov.x %fp0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7859) fdiv.x %fp1,%fp0 # Z/(1+Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7860) mov.l %a1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7861) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7862) or.l &0x3F000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7863) fadd.x (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7864) mov.l %d1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7866) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7867) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7868) fmul.s (%sp)+,%fp0 # last fp inst - possible exceptions set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7869) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7871) SINHBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7872) cmp.l %d1,&0x400CB2B3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7873) bgt t_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7874) fabs.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7875) fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7876) mov.l &0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7877) mov.l &0x80000000,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7878) mov.l %a1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7879) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7880) or.l &0x7FFB0000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7881) mov.l %d1,-(%sp) # EXTENDED FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7882) fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7884) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7885) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7886) fmovm.x &0x01,-(%sp) # save fp0 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7887) lea (%sp),%a0 # pass ptr to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7888) bsr setox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7889) add.l &0xc,%sp # clear fp0 from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7891) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7892) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7893) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7894) fmul.x (%sp)+,%fp0 # possible exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7895) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7897) global ssinhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7898) #--SINH(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7899) ssinhd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7900) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7902) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7903) # stanh(): computes the hyperbolic tangent of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7904) # stanhd(): computes the hyperbolic tangent of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7905) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7906) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7907) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7908) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7909) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7910) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7911) # fp0 = tanh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7912) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7913) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7914) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7915) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7916) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7917) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7918) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7919) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7920) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7921) # TANH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7922) # 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7923) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7924) # 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7925) # sgn := sign(X), y := 2|X|, z := expm1(Y), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7926) # tanh(X) = sgn*( z/(2+z) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7927) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7928) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7929) # 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7930) # go to 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7931) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7932) # 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7933) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7934) # 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7935) # sgn := sign(X), y := 2|X|, z := exp(Y), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7936) # tanh(X) = sgn - [ sgn*2/(1+z) ]. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7937) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7938) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7939) # 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7940) # calculate Tanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7941) # sgn := sign(X), Tiny := 2**(-126), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7942) # tanh(X) := sgn - sgn*Tiny. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7943) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7944) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7945) # 7. (|X| < 2**(-40)). Tanh(X) = X. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7946) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7947) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7949) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7950) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7952) set SGN,L_SCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7954) set V,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7956) global stanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7957) stanh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7958) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7960) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7961) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7962) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7963) mov.l %d1,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7964) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7965) cmp.l %d1, &0x3fd78000 # is |X| < 2^(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7966) blt.w TANHBORS # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7967) cmp.l %d1, &0x3fffddce # is |X| > (5/2)LOG2?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7968) bgt.w TANHBORS # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7970) #--THIS IS THE USUAL CASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7971) #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7973) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7974) mov.l %d1,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7975) and.l &0x7FFF0000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7976) add.l &0x00010000,%d1 # EXPONENT OF 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7977) mov.l %d1,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7978) and.l &0x80000000,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7979) fmov.x X(%a6),%fp0 # FP0 IS Y = 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7981) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7982) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7983) fmovm.x &0x1,-(%sp) # save Y on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7984) lea (%sp),%a0 # pass ptr to Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7985) bsr setoxm1 # FP0 IS Z = EXPM1(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7986) add.l &0xc,%sp # clear Y from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7987) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7989) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7990) fadd.s &0x40000000,%fp1 # Z+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7991) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7992) fmov.x %fp1,V(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7993) eor.l %d1,V(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7995) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7996) fdiv.x V(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7997) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7999) TANHBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8000) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8001) blt.w TANHSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8003) cmp.l %d1,&0x40048AA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8004) bgt.w TANHHUGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8006) #-- (5/2) LOG2 < |X| < 50 LOG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8007) #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8008) #--TANH(X) = SGN - SGN*2/[EXP(Y)+1].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8010) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8011) mov.l %d1,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8012) and.l &0x7FFF0000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8013) add.l &0x00010000,%d1 # EXPO OF 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8014) mov.l %d1,X(%a6) # Y = 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8015) and.l &0x80000000,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8016) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8017) fmov.x X(%a6),%fp0 # Y = 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8019) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8020) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8021) fmovm.x &0x01,-(%sp) # save Y on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8022) lea (%sp),%a0 # pass ptr to Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8023) bsr setox # FP0 IS EXP(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8024) add.l &0xc,%sp # clear Y from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8025) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8026) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8027) fadd.s &0x3F800000,%fp0 # EXP(Y)+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8029) eor.l &0xC0000000,%d1 # -SIGN(X)*2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8030) fmov.s %d1,%fp1 # -SIGN(X)*2 IN SGL FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8031) fdiv.x %fp0,%fp1 # -SIGN(X)2 / [EXP(Y)+1 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8033) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8034) or.l &0x3F800000,%d1 # SGN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8035) fmov.s %d1,%fp0 # SGN IN SGL FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8037) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8038) mov.b &FADD_OP,%d1 # last inst is ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8039) fadd.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8040) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8042) TANHSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8043) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8044) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8045) fmov.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8046) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8048) #---RETURN SGN(X) - SGN(X)EPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8049) TANHHUGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8050) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8051) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8052) or.l &0x3F800000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8053) fmov.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8054) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8055) eor.l &0x80800000,%d1 # -SIGN(X)*EPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8057) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8058) fadd.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8059) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8061) global stanhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8062) #--TANH(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8063) stanhd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8064) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8066) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8067) # slogn(): computes the natural logarithm of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8068) # slognd(): computes the natural logarithm of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8069) # slognp1(): computes the log(1+X) of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8070) # slognp1d(): computes the log(1+X) of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8071) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8072) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8073) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8074) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8075) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8076) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8077) # fp0 = log(X) or log(1+X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8078) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8079) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8080) # The returned result is within 2 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8081) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8082) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8083) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8084) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8085) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8086) # LOGN: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8087) # Step 1. If |X-1| < 1/16, approximate log(X) by an odd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8088) # polynomial in u, where u = 2(X-1)/(X+1). Otherwise, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8089) # move on to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8090) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8091) # Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8092) # seven significant bits of Y plus 2**(-7), i.e. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8093) # F = 1.xxxxxx1 in base 2 where the six "x" match those #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8094) # of Y. Note that |Y-F| <= 2**(-7). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8095) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8096) # Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8097) # polynomial in u, log(1+u) = poly. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8098) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8099) # Step 4. Reconstruct #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8100) # log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8101) # by k*log(2) + (log(F) + poly). The values of log(F) are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8102) # calculated beforehand and stored in the program. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8103) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8104) # lognp1: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8105) # Step 1: If |X| < 1/16, approximate log(1+X) by an odd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8106) # polynomial in u where u = 2X/(2+X). Otherwise, move on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8107) # to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8108) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8109) # Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8110) # in Step 2 of the algorithm for LOGN and compute #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8111) # log(1+X) as k*log(2) + log(F) + poly where poly #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8112) # approximates log(1+u), u = (Y-F)/F. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8113) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8114) # Implementation Notes: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8115) # Note 1. There are 64 different possible values for F, thus 64 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8116) # log(F)'s need to be tabulated. Moreover, the values of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8117) # 1/F are also tabulated so that the division in (Y-F)/F #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8118) # can be performed by a multiplication. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8119) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8120) # Note 2. In Step 2 of lognp1, in order to preserved accuracy, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8121) # the value Y-F has to be calculated carefully when #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8122) # 1/2 <= X < 3/2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8123) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8124) # Note 3. To fully exploit the pipeline, polynomials are usually #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8125) # separated into two parts evaluated independently before #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8126) # being added up. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8127) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8128) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8129) LOGOF2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8130) long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8132) one:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8133) long 0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8134) zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8135) long 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8136) infty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8137) long 0x7F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8138) negone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8139) long 0xBF800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8141) LOGA6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8142) long 0x3FC2499A,0xB5E4040B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8143) LOGA5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8144) long 0xBFC555B5,0x848CB7DB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8146) LOGA4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8147) long 0x3FC99999,0x987D8730
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8148) LOGA3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8149) long 0xBFCFFFFF,0xFF6F7E97
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8151) LOGA2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8152) long 0x3FD55555,0x555555A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8153) LOGA1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8154) long 0xBFE00000,0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8156) LOGB5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8157) long 0x3F175496,0xADD7DAD6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8158) LOGB4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8159) long 0x3F3C71C2,0xFE80C7E0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8161) LOGB3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8162) long 0x3F624924,0x928BCCFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8163) LOGB2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8164) long 0x3F899999,0x999995EC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8166) LOGB1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8167) long 0x3FB55555,0x55555555
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8168) TWO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8169) long 0x40000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8171) LTHOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8172) long 0x3f990000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8174) LOGTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8175) long 0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8176) long 0x3FF70000,0xFF015358,0x833C47E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8177) long 0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8178) long 0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8179) long 0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8180) long 0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8181) long 0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8182) long 0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8183) long 0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8184) long 0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8185) long 0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8186) long 0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8187) long 0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8188) long 0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8189) long 0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8190) long 0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8191) long 0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8192) long 0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8193) long 0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8194) long 0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8195) long 0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8196) long 0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8197) long 0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8198) long 0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8199) long 0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8200) long 0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8201) long 0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8202) long 0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8203) long 0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8204) long 0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8205) long 0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8206) long 0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8207) long 0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8208) long 0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8209) long 0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8210) long 0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8211) long 0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8212) long 0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8213) long 0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8214) long 0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8215) long 0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8216) long 0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8217) long 0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8218) long 0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8219) long 0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8220) long 0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8221) long 0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8222) long 0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8223) long 0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8224) long 0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8225) long 0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8226) long 0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8227) long 0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8228) long 0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8229) long 0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8230) long 0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8231) long 0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8232) long 0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8233) long 0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8234) long 0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8235) long 0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8236) long 0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8237) long 0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8238) long 0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8239) long 0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8240) long 0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8241) long 0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8242) long 0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8243) long 0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8244) long 0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8245) long 0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8246) long 0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8247) long 0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8248) long 0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8249) long 0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8250) long 0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8251) long 0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8252) long 0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8253) long 0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8254) long 0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8255) long 0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8256) long 0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8257) long 0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8258) long 0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8259) long 0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8260) long 0x3FFE0000,0x825EFCED,0x49369330,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8261) long 0x3FFE0000,0x9868C809,0x868C8098,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8262) long 0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8263) long 0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8264) long 0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8265) long 0x3FFE0000,0x95A02568,0x095A0257,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8266) long 0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8267) long 0x3FFE0000,0x94458094,0x45809446,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8268) long 0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8269) long 0x3FFE0000,0x92F11384,0x0497889C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8270) long 0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8271) long 0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8272) long 0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8273) long 0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8274) long 0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8275) long 0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8276) long 0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8277) long 0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8278) long 0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8279) long 0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8280) long 0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8281) long 0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8282) long 0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8283) long 0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8284) long 0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8285) long 0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8286) long 0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8287) long 0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8288) long 0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8289) long 0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8290) long 0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8291) long 0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8292) long 0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8293) long 0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8294) long 0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8295) long 0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8296) long 0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8297) long 0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8298) long 0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8299) long 0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8300) long 0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8301) long 0x3FFE0000,0x80808080,0x80808081,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8302) long 0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8304) set ADJK,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8306) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8307) set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8308) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8310) set F,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8311) set FFRAC,F+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8313) set KLOG2,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8315) set SAVEU,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8317) global slogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8318) #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8319) slogn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8320) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8321) mov.l &0x00000000,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8323) LOGBGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8324) #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8325) #--A FINITE, NON-ZERO, NORMALIZED NUMBER.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8327) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8328) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8330) mov.l (%a0),X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8331) mov.l 4(%a0),X+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8332) mov.l 8(%a0),X+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8334) cmp.l %d1,&0 # CHECK IF X IS NEGATIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8335) blt.w LOGNEG # LOG OF NEGATIVE ARGUMENT IS INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8336) # X IS POSITIVE, CHECK IF X IS NEAR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8337) cmp.l %d1,&0x3ffef07d # IS X < 15/16?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8338) blt.b LOGMAIN # YES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8339) cmp.l %d1,&0x3fff8841 # IS X > 17/16?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8340) ble.w LOGNEAR1 # NO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8342) LOGMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8343) #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8345) #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8346) #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8347) #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8348) #-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8349) #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8350) #--LOG(1+U) CAN BE VERY EFFICIENT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8351) #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8352) #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8354) #--GET K, Y, F, AND ADDRESS OF 1/F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8355) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8356) asr.l &8,%d1 # SHIFTED 16 BITS, BIASED EXPO. OF X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8357) sub.l &0x3FFF,%d1 # THIS IS K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8358) add.l ADJK(%a6),%d1 # ADJUST K, ORIGINAL INPUT MAY BE DENORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8359) lea LOGTBL(%pc),%a0 # BASE ADDRESS OF 1/F AND LOG(F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8360) fmov.l %d1,%fp1 # CONVERT K TO FLOATING-POINT FORMAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8362) #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8363) mov.l &0x3FFF0000,X(%a6) # X IS NOW Y, I.E. 2^(-K)*X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8364) mov.l XFRAC(%a6),FFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8365) and.l &0xFE000000,FFRAC(%a6) # FIRST 7 BITS OF Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8366) or.l &0x01000000,FFRAC(%a6) # GET F: ATTACH A 1 AT THE EIGHTH BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8367) mov.l FFRAC(%a6),%d1 # READY TO GET ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8368) and.l &0x7E000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8369) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8370) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8371) asr.l &4,%d1 # SHIFTED 20, D0 IS THE DISPLACEMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8372) add.l %d1,%a0 # A0 IS THE ADDRESS FOR 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8374) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8375) mov.l &0x3fff0000,F(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8376) clr.l F+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8377) fsub.x F(%a6),%fp0 # Y-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8378) fmovm.x &0xc,-(%sp) # SAVE FP2-3 WHILE FP0 IS NOT READY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8379) #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8380) #--REGISTERS SAVED: FPCR, FP1, FP2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8382) LP1CONT1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8383) #--AN RE-ENTRY POINT FOR LOGNP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8384) fmul.x (%a0),%fp0 # FP0 IS U = (Y-F)/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8385) fmul.x LOGOF2(%pc),%fp1 # GET K*LOG2 WHILE FP0 IS NOT READY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8386) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8387) fmul.x %fp2,%fp2 # FP2 IS V=U*U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8388) fmov.x %fp1,KLOG2(%a6) # PUT K*LOG2 IN MEMEORY, FREE FP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8390) #--LOG(1+U) IS APPROXIMATED BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8391) #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8392) #--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8394) fmov.x %fp2,%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8395) fmov.x %fp2,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8397) fmul.d LOGA6(%pc),%fp1 # V*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8398) fmul.d LOGA5(%pc),%fp2 # V*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8400) fadd.d LOGA4(%pc),%fp1 # A4+V*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8401) fadd.d LOGA3(%pc),%fp2 # A3+V*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8403) fmul.x %fp3,%fp1 # V*(A4+V*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8404) fmul.x %fp3,%fp2 # V*(A3+V*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8406) fadd.d LOGA2(%pc),%fp1 # A2+V*(A4+V*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8407) fadd.d LOGA1(%pc),%fp2 # A1+V*(A3+V*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8409) fmul.x %fp3,%fp1 # V*(A2+V*(A4+V*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8410) add.l &16,%a0 # ADDRESS OF LOG(F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8411) fmul.x %fp3,%fp2 # V*(A1+V*(A3+V*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8413) fmul.x %fp0,%fp1 # U*V*(A2+V*(A4+V*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8414) fadd.x %fp2,%fp0 # U+V*(A1+V*(A3+V*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8416) fadd.x (%a0),%fp1 # LOG(F)+U*V*(A2+V*(A4+V*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8417) fmovm.x (%sp)+,&0x30 # RESTORE FP2-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8418) fadd.x %fp1,%fp0 # FP0 IS LOG(F) + LOG(1+U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8420) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8421) fadd.x KLOG2(%a6),%fp0 # FINAL ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8422) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8425) LOGNEAR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8427) # if the input is exactly equal to one, then exit through ld_pzero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8428) # if these 2 lines weren't here, the correct answer would be returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8429) # but the INEX2 bit would be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8430) fcmp.b %fp0,&0x1 # is it equal to one?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8431) fbeq.l ld_pzero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8433) #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8434) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8435) fsub.s one(%pc),%fp1 # FP1 IS X-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8436) fadd.s one(%pc),%fp0 # FP0 IS X+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8437) fadd.x %fp1,%fp1 # FP1 IS 2(X-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8438) #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8439) #--IN U, U = 2(X-1)/(X+1) = FP1/FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8441) LP1CONT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8442) #--THIS IS AN RE-ENTRY POINT FOR LOGNP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8443) fdiv.x %fp0,%fp1 # FP1 IS U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8444) fmovm.x &0xc,-(%sp) # SAVE FP2-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8445) #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8446) #--LET V=U*U, W=V*V, CALCULATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8447) #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8448) #--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8449) fmov.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8450) fmul.x %fp0,%fp0 # FP0 IS V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8451) fmov.x %fp1,SAVEU(%a6) # STORE U IN MEMORY, FREE FP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8452) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8453) fmul.x %fp1,%fp1 # FP1 IS W
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8455) fmov.d LOGB5(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8456) fmov.d LOGB4(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8458) fmul.x %fp1,%fp3 # W*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8459) fmul.x %fp1,%fp2 # W*B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8461) fadd.d LOGB3(%pc),%fp3 # B3+W*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8462) fadd.d LOGB2(%pc),%fp2 # B2+W*B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8464) fmul.x %fp3,%fp1 # W*(B3+W*B5), FP3 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8466) fmul.x %fp0,%fp2 # V*(B2+W*B4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8468) fadd.d LOGB1(%pc),%fp1 # B1+W*(B3+W*B5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8469) fmul.x SAVEU(%a6),%fp0 # FP0 IS U*V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8471) fadd.x %fp2,%fp1 # B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8472) fmovm.x (%sp)+,&0x30 # FP2-3 RESTORED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8474) fmul.x %fp1,%fp0 # U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8476) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8477) fadd.x SAVEU(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8478) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8480) #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8481) LOGNEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8482) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8484) global slognd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8485) slognd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8486) #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8488) mov.l &-100,ADJK(%a6) # INPUT = 2^(ADJK) * FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8490) #----normalize the input value by left shifting k bits (k to be determined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8491) #----below), adjusting exponent and storing -k to ADJK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8492) #----the value TWOTO100 is no longer needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8493) #----Note that this code assumes the denormalized input is NON-ZERO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8495) movm.l &0x3f00,-(%sp) # save some registers {d2-d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8496) mov.l (%a0),%d3 # D3 is exponent of smallest norm. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8497) mov.l 4(%a0),%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8498) mov.l 8(%a0),%d5 # (D4,D5) is (Hi_X,Lo_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8499) clr.l %d2 # D2 used for holding K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8501) tst.l %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8502) bne.b Hi_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8504) Hi_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8505) mov.l %d5,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8506) clr.l %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8507) mov.l &32,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8508) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8509) bfffo %d4{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8510) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8511) add.l %d6,%d2 # (D3,D4,D5) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8513) mov.l %d3,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8514) mov.l %d4,XFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8515) mov.l %d5,XFRAC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8516) neg.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8517) mov.l %d2,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8518) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8519) movm.l (%sp)+,&0xfc # restore registers {d2-d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8520) lea X(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8521) bra.w LOGBGN # begin regular log(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8523) Hi_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8524) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8525) bfffo %d4{&0:&32},%d6 # find first 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8526) mov.l %d6,%d2 # get k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8527) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8528) mov.l %d5,%d7 # a copy of D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8529) lsl.l %d6,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8530) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8531) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8532) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8533) or.l %d7,%d4 # (D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8535) mov.l %d3,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8536) mov.l %d4,XFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8537) mov.l %d5,XFRAC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8538) neg.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8539) mov.l %d2,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8540) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8541) movm.l (%sp)+,&0xfc # restore registers {d2-d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8542) lea X(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8543) bra.w LOGBGN # begin regular log(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8545) global slognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8546) #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8547) slognp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8548) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8549) fabs.x %fp0 # test magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8550) fcmp.x %fp0,LTHOLD(%pc) # compare with min threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8551) fbgt.w LP1REAL # if greater, continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8552) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8553) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8554) fmov.x (%a0),%fp0 # return signed argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8555) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8557) LP1REAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8558) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8559) mov.l &0x00000000,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8560) fmov.x %fp0,%fp1 # FP1 IS INPUT Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8561) fadd.s one(%pc),%fp0 # X := ROUND(1+Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8562) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8563) mov.w XFRAC(%a6),XDCARE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8564) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8565) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8566) ble.w LP1NEG0 # LOG OF ZERO OR -VE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8567) cmp.l %d1,&0x3ffe8000 # IS BOUNDS [1/2,3/2]?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8568) blt.w LOGMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8569) cmp.l %d1,&0x3fffc000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8570) bgt.w LOGMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8571) #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8572) #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8573) #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8575) LP1NEAR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8576) #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8577) cmp.l %d1,&0x3ffef07d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8578) blt.w LP1CARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8579) cmp.l %d1,&0x3fff8841
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8580) bgt.w LP1CARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8582) LP1ONE16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8583) #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8584) #--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8585) fadd.x %fp1,%fp1 # FP1 IS 2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8586) fadd.s one(%pc),%fp0 # FP0 IS 1+X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8587) #--U = FP1/FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8588) bra.w LP1CONT2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8590) LP1CARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8591) #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8592) #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8593) #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8594) #--THERE ARE ONLY TWO CASES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8595) #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8596) #--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1-F) + Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8597) #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8598) #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8600) mov.l XFRAC(%a6),FFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8601) and.l &0xFE000000,FFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8602) or.l &0x01000000,FFRAC(%a6) # F OBTAINED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8603) cmp.l %d1,&0x3FFF8000 # SEE IF 1+Z > 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8604) bge.b KISZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8606) KISNEG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8607) fmov.s TWO(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8608) mov.l &0x3fff0000,F(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8609) clr.l F+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8610) fsub.x F(%a6),%fp0 # 2-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8611) mov.l FFRAC(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8612) and.l &0x7E000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8613) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8614) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8615) asr.l &4,%d1 # D0 CONTAINS DISPLACEMENT FOR 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8616) fadd.x %fp1,%fp1 # GET 2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8617) fmovm.x &0xc,-(%sp) # SAVE FP2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8618) fadd.x %fp1,%fp0 # FP0 IS Y-F = (2-F)+2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8619) lea LOGTBL(%pc),%a0 # A0 IS ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8620) add.l %d1,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8621) fmov.s negone(%pc),%fp1 # FP1 IS K = -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8622) bra.w LP1CONT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8624) KISZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8625) fmov.s one(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8626) mov.l &0x3fff0000,F(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8627) clr.l F+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8628) fsub.x F(%a6),%fp0 # 1-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8629) mov.l FFRAC(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8630) and.l &0x7E000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8631) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8632) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8633) asr.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8634) fadd.x %fp1,%fp0 # FP0 IS Y-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8635) fmovm.x &0xc,-(%sp) # FP2 SAVED {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8636) lea LOGTBL(%pc),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8637) add.l %d1,%a0 # A0 IS ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8638) fmov.s zero(%pc),%fp1 # FP1 IS K = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8639) bra.w LP1CONT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8641) LP1NEG0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8642) #--FPCR SAVED. D0 IS X IN COMPACT FORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8643) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8644) blt.b LP1NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8645) LP1ZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8646) fmov.s negone(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8648) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8649) bra t_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8651) LP1NEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8652) fmov.s zero(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8654) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8655) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8657) global slognp1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8658) #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8659) # Simply return the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8660) slognp1d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8661) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8663) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8664) # satanh(): computes the inverse hyperbolic tangent of a norm input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8665) # satanhd(): computes the inverse hyperbolic tangent of a denorm input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8666) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8667) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8668) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8669) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8670) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8671) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8672) # fp0 = arctanh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8673) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8674) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8675) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8676) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8677) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8678) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8679) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8680) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8681) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8682) # ATANH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8683) # 1. If |X| >= 1, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8684) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8685) # 2. (|X| < 1) Calculate atanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8686) # sgn := sign(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8687) # y := |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8688) # z := 2y/(1-y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8689) # atanh(X) := sgn * (1/2) * logp1(z) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8690) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8691) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8692) # 3. If |X| > 1, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8693) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8694) # 4. (|X| = 1) Generate infinity with an appropriate sign and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8695) # divide-by-zero by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8696) # sgn := sign(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8697) # atan(X) := sgn / (+0). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8698) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8699) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8700) # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8701) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8702) # #
^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) global satanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8706) satanh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8707) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8708) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8709) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8710) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8711) bge.b ATANHBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8713) #--THIS IS THE USUAL CASE, |X| < 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8714) #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8716) fabs.x (%a0),%fp0 # Y = |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8717) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8718) fneg.x %fp1 # -Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8719) fadd.x %fp0,%fp0 # 2Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8720) fadd.s &0x3F800000,%fp1 # 1-Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8721) fdiv.x %fp1,%fp0 # 2Y/(1-Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8722) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8723) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8724) or.l &0x3F000000,%d1 # SIGN(X)*HALF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8725) mov.l %d1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8727) mov.l %d0,-(%sp) # save rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8728) clr.l %d0 # pass ext prec,RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8729) fmovm.x &0x01,-(%sp) # save Z on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8730) lea (%sp),%a0 # pass ptr to Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8731) bsr slognp1 # LOG1P(Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8732) add.l &0xc,%sp # clear Z from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8734) mov.l (%sp)+,%d0 # fetch old prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8735) fmov.l %d0,%fpcr # load it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8736) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8737) fmul.s (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8738) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8740) ATANHBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8741) fabs.x (%a0),%fp0 # |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8742) fcmp.s %fp0,&0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8743) fbgt t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8744) bra t_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8746) global satanhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8747) #--ATANH(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8748) satanhd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8749) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8751) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8752) # slog10(): computes the base-10 logarithm of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8753) # slog10d(): computes the base-10 logarithm of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8754) # slog2(): computes the base-2 logarithm of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8755) # slog2d(): computes the base-2 logarithm of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8756) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8757) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8758) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8759) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8760) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8761) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8762) # fp0 = log_10(X) or log_2(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8763) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8764) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8765) # The returned result is within 1.7 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8766) # i.e. within 0.5003 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8767) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8768) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8769) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8770) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8771) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8772) # slog10d: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8773) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8774) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8775) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8776) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8777) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8778) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8779) # Step 1. Call slognd to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8780) # Notes: Even if X is denormalized, log(X) is always normalized. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8781) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8782) # Step 2. Compute log_10(X) = log(X) * (1/log(10)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8783) # 2.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8784) # 2.2 Return ans := Y * INV_L10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8785) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8786) # slog10: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8787) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8788) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8789) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8790) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8791) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8792) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8793) # Step 1. Call sLogN to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8794) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8795) # Step 2. Compute log_10(X) = log(X) * (1/log(10)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8796) # 2.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8797) # 2.2 Return ans := Y * INV_L10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8798) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8799) # sLog2d: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8800) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8801) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8802) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8803) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8804) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8805) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8806) # Step 1. Call slognd to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8807) # Notes: Even if X is denormalized, log(X) is always normalized. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8808) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8809) # Step 2. Compute log_10(X) = log(X) * (1/log(2)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8810) # 2.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8811) # 2.2 Return ans := Y * INV_L2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8812) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8813) # sLog2: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8814) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8815) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8816) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8817) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8818) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8819) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8820) # Step 1. If X is not an integer power of two, i.e., X != 2^k, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8821) # go to Step 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8822) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8823) # Step 2. Return k. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8824) # 2.1 Get integer k, X = 2^k. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8825) # 2.2 Restore the user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8826) # 2.3 Return ans := convert-to-double-extended(k). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8827) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8828) # Step 3. Call sLogN to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8829) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8830) # Step 4. Compute log_2(X) = log(X) * (1/log(2)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8831) # 4.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8832) # 4.2 Return ans := Y * INV_L2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8833) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8834) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8836) INV_L10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8837) long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8839) INV_L2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8840) long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8842) global slog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8843) #--entry point for Log10(X), X is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8844) slog10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8845) fmov.b &0x1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8846) fcmp.x %fp0,(%a0) # if operand == 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8847) fbeq.l ld_pzero # return an EXACT zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8849) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8850) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8851) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8852) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8853) bsr slogn # log(X), X normal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8854) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8855) fmul.x INV_L10(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8856) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8858) global slog10d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8859) #--entry point for Log10(X), X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8860) slog10d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8861) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8862) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8863) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8864) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8865) bsr slognd # log(X), X denorm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8866) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8867) fmul.x INV_L10(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8868) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8870) global slog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8871) #--entry point for Log2(X), X is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8872) slog2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8873) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8874) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8876) mov.l 8(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8877) bne.b continue # X is not 2^k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8879) mov.l 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8880) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8881) bne.b continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8883) #--X = 2^k.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8884) mov.w (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8885) and.l &0x00007FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8886) sub.l &0x3FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8887) beq.l ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8888) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8889) fmov.l %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8890) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8892) continue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8893) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8894) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8895) bsr slogn # log(X), X normal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8896) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8897) fmul.x INV_L2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8898) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8900) invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8901) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8903) global slog2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8904) #--entry point for Log2(X), X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8905) slog2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8906) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8907) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8908) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8909) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8910) bsr slognd # log(X), X denorm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8911) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8912) fmul.x INV_L2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8913) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8915) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8916) # stwotox(): computes 2**X for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8917) # stwotoxd(): computes 2**X for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8918) # stentox(): computes 10**X for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8919) # stentoxd(): computes 10**X for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8920) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8921) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8922) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8923) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8924) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8925) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8926) # fp0 = 2**X or 10**X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8927) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8928) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8929) # The returned result is within 2 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8930) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8931) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8932) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8933) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8934) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8935) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8936) # twotox #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8937) # 1. If |X| > 16480, go to ExpBig. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8938) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8939) # 2. If |X| < 2**(-70), go to ExpSm. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8940) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8941) # 3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8942) # decompose N as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8943) # N = 64(M + M') + j, j = 0,1,2,...,63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8944) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8945) # 4. Overwrite r := r * log2. Then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8946) # 2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8947) # Go to expr to compute that expression. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8948) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8949) # tentox #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8950) # 1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8951) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8952) # 2. If |X| < 2**(-70), go to ExpSm. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8953) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8954) # 3. Set y := X*log_2(10)*64 (base 2 log of 10). Set #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8955) # N := round-to-int(y). Decompose N as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8956) # N = 64(M + M') + j, j = 0,1,2,...,63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8957) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8958) # 4. Define r as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8959) # r := ((X - N*L1)-N*L2) * L10 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8960) # where L1, L2 are the leading and trailing parts of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8961) # log_10(2)/64 and L10 is the natural log of 10. Then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8962) # 10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8963) # Go to expr to compute that expression. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8964) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8965) # expr #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8966) # 1. Fetch 2**(j/64) from table as Fact1 and Fact2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8967) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8968) # 2. Overwrite Fact1 and Fact2 by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8969) # Fact1 := 2**(M) * Fact1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8970) # Fact2 := 2**(M) * Fact2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8971) # Thus Fact1 + Fact2 = 2**(M) * 2**(j/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8972) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8973) # 3. Calculate P where 1 + P approximates exp(r): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8974) # P = r + r*r*(A1+r*(A2+...+r*A5)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8975) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8976) # 4. Let AdjFact := 2**(M'). Return #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8977) # AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8978) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8979) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8980) # ExpBig #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8981) # 1. Generate overflow by Huge * Huge if X > 0; otherwise, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8982) # generate underflow by Tiny * Tiny. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8983) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8984) # ExpSm #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8985) # 1. Return 1 + X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8986) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8987) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8989) L2TEN64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8990) long 0x406A934F,0x0979A371 # 64LOG10/LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8991) L10TWO1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8992) long 0x3F734413,0x509F8000 # LOG2/64LOG10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8994) L10TWO2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8995) long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8997) LOG10: long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8999) LOG2: long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9001) EXPA5: long 0x3F56C16D,0x6F7BD0B2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9002) EXPA4: long 0x3F811112,0x302C712C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9003) EXPA3: long 0x3FA55555,0x55554CC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9004) EXPA2: long 0x3FC55555,0x55554A54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9005) EXPA1: long 0x3FE00000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9007) TEXPTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9008) long 0x3FFF0000,0x80000000,0x00000000,0x3F738000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9009) long 0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9010) long 0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9011) long 0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9012) long 0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9013) long 0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9014) long 0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9015) long 0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9016) long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9017) long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9018) long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9019) long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9020) long 0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9021) long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9022) long 0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9023) long 0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9024) long 0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9025) long 0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9026) long 0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9027) long 0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9028) long 0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9029) long 0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9030) long 0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9031) long 0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9032) long 0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9033) long 0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9034) long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9035) long 0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9036) long 0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9037) long 0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9038) long 0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9039) long 0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9040) long 0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9041) long 0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9042) long 0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9043) long 0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9044) long 0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9045) long 0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9046) long 0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9047) long 0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9048) long 0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9049) long 0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9050) long 0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9051) long 0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9052) long 0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9053) long 0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9054) long 0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9055) long 0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9056) long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9057) long 0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9058) long 0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9059) long 0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9060) long 0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9061) long 0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9062) long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9063) long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9064) long 0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9065) long 0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9066) long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9067) long 0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9068) long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9069) long 0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9070) long 0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9071) long 0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9073) set INT,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9075) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9076) set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9077) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9079) set ADJFACT,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9081) set FACT1,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9082) set FACT1HI,FACT1+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9083) set FACT1LOW,FACT1+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9085) set FACT2,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9086) set FACT2HI,FACT2+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9087) set FACT2LOW,FACT2+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9089) global stwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9090) #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9091) stwotox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9092) fmovm.x (%a0),&0x80 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9094) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9095) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9096) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9097) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9099) cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9100) bge.b TWOOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9101) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9103) TWOOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9104) cmp.l %d1,&0x400D80C0 # |X| > 16480?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9105) ble.b TWOMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9106) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9108) TWOMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9109) #--USUAL CASE, 2^(-70) <= |X| <= 16480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9111) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9112) fmul.s &0x42800000,%fp1 # 64 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9113) fmov.l %fp1,INT(%a6) # N = ROUND-TO-INT(64 X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9114) mov.l %d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9115) lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9116) fmov.l INT(%a6),%fp1 # N --> FLOATING FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9117) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9118) mov.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9119) and.l &0x3F,%d1 # D0 IS J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9120) asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9121) add.l %d1,%a1 # ADDRESS FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9122) asr.l &6,%d2 # d2 IS L, N = 64L + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9123) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9124) asr.l &1,%d1 # D0 IS M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9125) sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9126) add.l &0x3FFF,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9128) #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9129) #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9130) #--ADJFACT = 2^(M').
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9131) #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9133) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9135) fmul.s &0x3C800000,%fp1 # (1/64)*N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9136) mov.l (%a1)+,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9137) mov.l (%a1)+,FACT1HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9138) mov.l (%a1)+,FACT1LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9139) mov.w (%a1)+,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9141) fsub.x %fp1,%fp0 # X - (1/64)*INT(64 X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9143) mov.w (%a1)+,FACT2HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9144) clr.w FACT2HI+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9145) clr.l FACT2LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9146) add.w %d1,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9147) fmul.x LOG2(%pc),%fp0 # FP0 IS R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9148) add.w %d1,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9150) bra.w expr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9152) EXPBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9153) #--FPCR, D0 SAVED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9154) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9155) bgt.b TEXPBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9157) #--|X| IS SMALL, RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9159) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9160) fadd.s &0x3F800000,%fp0 # RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9161) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9163) TEXPBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9164) #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9165) #--REGISTERS SAVE SO FAR ARE FPCR AND D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9166) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9167) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9168) blt.b EXPNEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9170) bra t_ovfl2 # t_ovfl expects positive value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9172) EXPNEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9173) bra t_unfl2 # t_unfl expects positive value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9175) global stwotoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9176) stwotoxd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9177) #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9179) fmov.l %d0,%fpcr # set user's rounding mode/precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9180) fmov.s &0x3F800000,%fp0 # RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9181) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9182) or.l &0x00800001,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9183) fadd.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9184) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9186) global stentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9187) #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9188) stentox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9189) fmovm.x (%a0),&0x80 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9191) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9192) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9193) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9194) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9196) cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9197) bge.b TENOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9198) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9200) TENOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9201) cmp.l %d1,&0x400B9B07 # |X| <= 16480*log2/log10 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9202) ble.b TENMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9203) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9205) TENMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9206) #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9208) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9209) fmul.d L2TEN64(%pc),%fp1 # X*64*LOG10/LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9210) fmov.l %fp1,INT(%a6) # N=INT(X*64*LOG10/LOG2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9211) mov.l %d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9212) lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9213) fmov.l INT(%a6),%fp1 # N --> FLOATING FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9214) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9215) mov.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9216) and.l &0x3F,%d1 # D0 IS J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9217) asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9218) add.l %d1,%a1 # ADDRESS FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9219) asr.l &6,%d2 # d2 IS L, N = 64L + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9220) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9221) asr.l &1,%d1 # D0 IS M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9222) sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9223) add.l &0x3FFF,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9225) #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9226) #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9227) #--ADJFACT = 2^(M').
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9228) #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9229) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9231) fmov.x %fp1,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9233) fmul.d L10TWO1(%pc),%fp1 # N*(LOG2/64LOG10)_LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9234) mov.l (%a1)+,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9236) fmul.x L10TWO2(%pc),%fp2 # N*(LOG2/64LOG10)_TRAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9238) mov.l (%a1)+,FACT1HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9239) mov.l (%a1)+,FACT1LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9240) fsub.x %fp1,%fp0 # X - N L_LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9241) mov.w (%a1)+,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9243) fsub.x %fp2,%fp0 # X - N L_TRAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9245) mov.w (%a1)+,FACT2HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9246) clr.w FACT2HI+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9247) clr.l FACT2LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9249) fmul.x LOG10(%pc),%fp0 # FP0 IS R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9250) add.w %d1,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9251) add.w %d1,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9253) expr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9254) #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9255) #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9256) #--FP0 IS R. THE FOLLOWING CODE COMPUTES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9257) #-- 2**(M'+M) * 2**(J/64) * EXP(R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9259) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9260) fmul.x %fp1,%fp1 # FP1 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9262) fmov.d EXPA5(%pc),%fp2 # FP2 IS A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9263) fmov.d EXPA4(%pc),%fp3 # FP3 IS A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9265) fmul.x %fp1,%fp2 # FP2 IS S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9266) fmul.x %fp1,%fp3 # FP3 IS S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9268) fadd.d EXPA3(%pc),%fp2 # FP2 IS A3+S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9269) fadd.d EXPA2(%pc),%fp3 # FP3 IS A2+S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9271) fmul.x %fp1,%fp2 # FP2 IS S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9272) fmul.x %fp1,%fp3 # FP3 IS S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9274) fadd.d EXPA1(%pc),%fp2 # FP2 IS A1+S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9275) fmul.x %fp0,%fp3 # FP3 IS R*S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9277) fmul.x %fp1,%fp2 # FP2 IS S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9278) fadd.x %fp3,%fp0 # FP0 IS R+R*S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9279) fadd.x %fp2,%fp0 # FP0 IS EXP(R) - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9281) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9283) #--FINAL RECONSTRUCTION PROCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9284) #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1) - (1 OR 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9286) fmul.x FACT1(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9287) fadd.x FACT2(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9288) fadd.x FACT1(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9290) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9291) mov.w %d2,ADJFACT(%a6) # INSERT EXPONENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9292) mov.l (%sp)+,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9293) mov.l &0x80000000,ADJFACT+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9294) clr.l ADJFACT+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9295) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9296) fmul.x ADJFACT(%a6),%fp0 # FINAL ADJUSTMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9297) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9299) global stentoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9300) stentoxd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9301) #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9303) fmov.l %d0,%fpcr # set user's rounding mode/precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9304) fmov.s &0x3F800000,%fp0 # RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9305) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9306) or.l &0x00800001,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9307) fadd.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9308) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9310) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9311) # smovcr(): returns the ROM constant at the offset specified in d1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9312) # rounded to the mode and precision specified in d0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9313) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9314) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9315) # d0 = rnd prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9316) # d1 = ROM offset #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9317) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9318) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9319) # fp0 = the ROM constant rounded to the user's rounding mode,prec #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9320) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9321) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9323) global smovcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9324) smovcr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9325) mov.l %d1,-(%sp) # save rom offset for a sec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9327) lsr.b &0x4,%d0 # shift ctrl bits to lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9328) mov.l %d0,%d1 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9329) andi.w &0x3,%d1 # extract rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9330) andi.w &0xc,%d0 # extract rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9331) swap %d0 # put rnd prec in hi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9332) mov.w %d1,%d0 # put rnd mode in lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9334) mov.l (%sp)+,%d1 # get rom offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9336) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9337) # check range of offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9338) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9339) tst.b %d1 # if zero, offset is to pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9340) beq.b pi_tbl # it is pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9341) cmpi.b %d1,&0x0a # check range $01 - $0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9342) ble.b z_val # if in this range, return zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9343) cmpi.b %d1,&0x0e # check range $0b - $0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9344) ble.b sm_tbl # valid constants in this range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9345) cmpi.b %d1,&0x2f # check range $10 - $2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9346) ble.b z_val # if in this range, return zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9347) cmpi.b %d1,&0x3f # check range $30 - $3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9348) ble.b bg_tbl # valid constants in this range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9350) z_val:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9351) bra.l ld_pzero # return a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9353) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9354) # the answer is PI rounded to the proper precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9355) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9356) # fetch a pointer to the answer table relating to the proper rounding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9357) # precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9358) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9359) pi_tbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9360) tst.b %d0 # is rmode RN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9361) bne.b pi_not_rn # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9362) pi_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9363) lea.l PIRN(%pc),%a0 # yes; load PI RN table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9364) bra.w set_finx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9365) pi_not_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9366) cmpi.b %d0,&rp_mode # is rmode RP?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9367) beq.b pi_rp # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9368) pi_rzrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9369) lea.l PIRZRM(%pc),%a0 # no; load PI RZ,RM table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9370) bra.b set_finx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9371) pi_rp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9372) lea.l PIRP(%pc),%a0 # load PI RP table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9373) bra.b set_finx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9375) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9376) # the answer is one of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9377) # $0B log10(2) (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9378) # $0C e (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9379) # $0D log2(e) (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9380) # $0E log10(e) (exact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9381) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9382) # fetch a pointer to the answer table relating to the proper rounding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9383) # precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9384) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9385) sm_tbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9386) subi.b &0xb,%d1 # make offset in 0-4 range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9387) tst.b %d0 # is rmode RN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9388) bne.b sm_not_rn # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9389) sm_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9390) lea.l SMALRN(%pc),%a0 # yes; load RN table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9391) sm_tbl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9392) cmpi.b %d1,&0x2 # is result log10(e)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9393) ble.b set_finx # no; answer is inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9394) bra.b no_finx # yes; answer is exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9395) sm_not_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9396) cmpi.b %d0,&rp_mode # is rmode RP?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9397) beq.b sm_rp # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9398) sm_rzrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9399) lea.l SMALRZRM(%pc),%a0 # no; load RZ,RM table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9400) bra.b sm_tbl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9401) sm_rp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9402) lea.l SMALRP(%pc),%a0 # load RP table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9403) bra.b sm_tbl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9405) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9406) # the answer is one of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9407) # $30 ln(2) (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9408) # $31 ln(10) (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9409) # $32 10^0 (exact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9410) # $33 10^1 (exact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9411) # $34 10^2 (exact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9412) # $35 10^4 (exact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9413) # $36 10^8 (exact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9414) # $37 10^16 (exact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9415) # $38 10^32 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9416) # $39 10^64 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9417) # $3A 10^128 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9418) # $3B 10^256 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9419) # $3C 10^512 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9420) # $3D 10^1024 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9421) # $3E 10^2048 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9422) # $3F 10^4096 (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9423) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9424) # fetch a pointer to the answer table relating to the proper rounding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9425) # precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9426) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9427) bg_tbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9428) subi.b &0x30,%d1 # make offset in 0-f range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9429) tst.b %d0 # is rmode RN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9430) bne.b bg_not_rn # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9431) bg_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9432) lea.l BIGRN(%pc),%a0 # yes; load RN table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9433) bg_tbl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9434) cmpi.b %d1,&0x1 # is offset <= $31?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9435) ble.b set_finx # yes; answer is inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9436) cmpi.b %d1,&0x7 # is $32 <= offset <= $37?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9437) ble.b no_finx # yes; answer is exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9438) bra.b set_finx # no; answer is inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9439) bg_not_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9440) cmpi.b %d0,&rp_mode # is rmode RP?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9441) beq.b bg_rp # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9442) bg_rzrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9443) lea.l BIGRZRM(%pc),%a0 # no; load RZ,RM table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9444) bra.b bg_tbl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9445) bg_rp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9446) lea.l BIGRP(%pc),%a0 # load RP table addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9447) bra.b bg_tbl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9449) # answer is inexact, so set INEX2 and AINEX in the user's FPSR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9450) set_finx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9451) ori.l &inx2a_mask,USER_FPSR(%a6) # set INEX2/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9452) no_finx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9453) mulu.w &0xc,%d1 # offset points into tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9454) swap %d0 # put rnd prec in lo word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9455) tst.b %d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9457) bne.b not_ext # if xprec, do not call round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9459) # Precision is extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9460) fmovm.x (%a0,%d1.w),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9461) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9463) # Precision is single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9464) not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9465) swap %d0 # rnd prec in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9467) # call round() to round the answer to the proper precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9468) # exponents out of range for single or double DO NOT cause underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9469) # or overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9470) mov.w 0x0(%a0,%d1.w),FP_SCR1_EX(%a6) # load first word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9471) mov.l 0x4(%a0,%d1.w),FP_SCR1_HI(%a6) # load second word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9472) mov.l 0x8(%a0,%d1.w),FP_SCR1_LO(%a6) # load third word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9473) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9474) clr.l %d0 # clear g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9475) lea FP_SCR1(%a6),%a0 # pass ptr to answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9476) clr.w LOCAL_SGN(%a0) # sign always positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9477) bsr.l _round # round the mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9479) fmovm.x (%a0),&0x80 # return rounded result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9480) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9482) align 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9484) PIRN: long 0x40000000,0xc90fdaa2,0x2168c235 # pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9485) PIRZRM: long 0x40000000,0xc90fdaa2,0x2168c234 # pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9486) PIRP: long 0x40000000,0xc90fdaa2,0x2168c235 # pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9488) SMALRN: long 0x3ffd0000,0x9a209a84,0xfbcff798 # log10(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9489) long 0x40000000,0xadf85458,0xa2bb4a9a # e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9490) long 0x3fff0000,0xb8aa3b29,0x5c17f0bc # log2(e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9491) long 0x3ffd0000,0xde5bd8a9,0x37287195 # log10(e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9492) long 0x00000000,0x00000000,0x00000000 # 0.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9494) SMALRZRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9495) long 0x3ffd0000,0x9a209a84,0xfbcff798 # log10(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9496) long 0x40000000,0xadf85458,0xa2bb4a9a # e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9497) long 0x3fff0000,0xb8aa3b29,0x5c17f0bb # log2(e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9498) long 0x3ffd0000,0xde5bd8a9,0x37287195 # log10(e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9499) long 0x00000000,0x00000000,0x00000000 # 0.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9501) SMALRP: long 0x3ffd0000,0x9a209a84,0xfbcff799 # log10(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9502) long 0x40000000,0xadf85458,0xa2bb4a9b # e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9503) long 0x3fff0000,0xb8aa3b29,0x5c17f0bc # log2(e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9504) long 0x3ffd0000,0xde5bd8a9,0x37287195 # log10(e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9505) long 0x00000000,0x00000000,0x00000000 # 0.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9507) BIGRN: long 0x3ffe0000,0xb17217f7,0xd1cf79ac # ln(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9508) long 0x40000000,0x935d8ddd,0xaaa8ac17 # ln(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9510) long 0x3fff0000,0x80000000,0x00000000 # 10 ^ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9511) long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9512) long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9513) long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9514) long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9515) long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9516) long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9517) long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9518) long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9519) long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9520) long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9521) long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9522) long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9523) long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9525) BIGRZRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9526) long 0x3ffe0000,0xb17217f7,0xd1cf79ab # ln(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9527) long 0x40000000,0x935d8ddd,0xaaa8ac16 # ln(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9529) long 0x3fff0000,0x80000000,0x00000000 # 10 ^ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9530) long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9531) long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9532) long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9533) long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9534) long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9535) long 0x40690000,0x9DC5ADA8,0x2B70B59D # 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9536) long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9537) long 0x41A80000,0x93BA47C9,0x80E98CDF # 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9538) long 0x43510000,0xAA7EEBFB,0x9DF9DE8D # 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9539) long 0x46A30000,0xE319A0AE,0xA60E91C6 # 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9540) long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9541) long 0x5A920000,0x9E8B3B5D,0xC53D5DE4 # 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9542) long 0x75250000,0xC4605202,0x8A20979A # 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9544) BIGRP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9545) long 0x3ffe0000,0xb17217f7,0xd1cf79ac # ln(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9546) long 0x40000000,0x935d8ddd,0xaaa8ac17 # ln(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9548) long 0x3fff0000,0x80000000,0x00000000 # 10 ^ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9549) long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9550) long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9551) long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9552) long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9553) long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9554) long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9555) long 0x40D30000,0xC2781F49,0xFFCFA6D6 # 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9556) long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9557) long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9558) long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9559) long 0x4D480000,0xC9767586,0x81750C18 # 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9560) long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9561) long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9563) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9564) # sscale(): computes the destination operand scaled by the source #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9565) # operand. If the absoulute value of the source operand is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9566) # >= 2^14, an overflow or underflow is returned. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9567) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9568) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9569) # a0 = pointer to double-extended source operand X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9570) # a1 = pointer to double-extended destination operand Y #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9571) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9572) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9573) # fp0 = scale(X,Y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9574) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9575) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9577) set SIGN, L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9579) global sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9580) sscale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9581) mov.l %d0,-(%sp) # store off ctrl bits for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9583) mov.w DST_EX(%a1),%d1 # get dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9584) smi.b SIGN(%a6) # use SIGN to hold dst sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9585) andi.l &0x00007fff,%d1 # strip sign from dst exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9587) mov.w SRC_EX(%a0),%d0 # check src bounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9588) andi.w &0x7fff,%d0 # clr src sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9589) cmpi.w %d0,&0x3fff # is src ~ ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9590) blt.w src_small # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9591) cmpi.w %d0,&0x400c # no; is src too big?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9592) bgt.w src_out # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9594) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9595) # Source is within 2^14 range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9596) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9597) src_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9598) fintrz.x SRC(%a0),%fp0 # calc int of src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9599) fmov.l %fp0,%d0 # int src to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9600) # don't want any accrued bits from the fintrz showing up later since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9601) # we may need to read the fpsr for the last fp op in t_catch2().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9602) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9604) tst.b DST_HI(%a1) # is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9605) bmi.b sok_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9607) # the dst is a DENORM. normalize the DENORM and add the adjustment to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9608) # the src value. then, jump to the norm part of the routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9609) sok_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9610) mov.l %d0,-(%sp) # save src for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9612) mov.w DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9613) mov.l DST_HI(%a1),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9614) mov.l DST_LO(%a1),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9616) lea FP_SCR0(%a6),%a0 # pass ptr to DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9617) bsr.l norm # normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9618) neg.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9619) add.l (%sp)+,%d0 # add adjustment to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9621) fmovm.x FP_SCR0(%a6),&0x80 # load normalized DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9623) cmpi.w %d0,&-0x3fff # is the shft amt really low?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9624) bge.b sok_norm2 # thank goodness no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9626) # the multiply factor that we're trying to create should be a denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9627) # for the multiply to work. Therefore, we're going to actually do a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9628) # multiply with a denorm which will cause an unimplemented data type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9629) # exception to be put into the machine which will be caught and corrected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9630) # later. we don't do this with the DENORMs above because this method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9631) # is slower. but, don't fret, I don't see it being used much either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9632) fmov.l (%sp)+,%fpcr # restore user fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9633) mov.l &0x80000000,%d1 # load normalized mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9634) subi.l &-0x3fff,%d0 # how many should we shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9635) neg.l %d0 # make it positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9636) cmpi.b %d0,&0x20 # is it > 32?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9637) bge.b sok_dnrm_32 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9638) lsr.l %d0,%d1 # no; bit stays in upper lw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9639) clr.l -(%sp) # insert zero low mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9640) mov.l %d1,-(%sp) # insert new high mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9641) clr.l -(%sp) # make zero exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9642) bra.b sok_norm_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9643) sok_dnrm_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9644) subi.b &0x20,%d0 # get shift count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9645) lsr.l %d0,%d1 # make low mantissa longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9646) mov.l %d1,-(%sp) # insert new low mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9647) clr.l -(%sp) # insert zero high mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9648) clr.l -(%sp) # make zero exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9649) bra.b sok_norm_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9651) # the src will force the dst to a DENORM value or worse. so, let's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9652) # create an fp multiply that will create the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9653) sok_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9654) fmovm.x DST(%a1),&0x80 # load fp0 with normalized src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9655) sok_norm2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9656) fmov.l (%sp)+,%fpcr # restore user fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9658) addi.w &0x3fff,%d0 # turn src amt into exp value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9659) swap %d0 # put exponent in high word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9660) clr.l -(%sp) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9661) mov.l &0x80000000,-(%sp) # insert new high mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9662) mov.l %d0,-(%sp) # insert new lo mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9664) sok_norm_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9665) fmov.l %fpcr,%d0 # d0 needs fpcr for t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9666) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9667) fmul.x (%sp)+,%fp0 # do the multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9668) bra t_catch2 # catch any exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9670) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9671) # Source is outside of 2^14 range. Test the sign and branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9672) # to the appropriate exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9673) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9674) src_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9675) mov.l (%sp)+,%d0 # restore ctrl bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9676) exg %a0,%a1 # swap src,dst ptrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9677) tst.b SRC_EX(%a1) # is src negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9678) bmi t_unfl # yes; underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9679) bra t_ovfl_sc # no; overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9681) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9682) # The source input is below 1, so we check for denormalized numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9683) # and set unfl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9684) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9685) src_small:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9686) tst.b DST_HI(%a1) # is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9687) bpl.b ssmall_done # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9689) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9690) fmov.l %d0,%fpcr # no; load control bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9691) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9692) fmov.x DST(%a1),%fp0 # simply return dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9693) bra t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9694) ssmall_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9695) mov.l (%sp)+,%d0 # load control bits into d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9696) mov.l %a1,%a0 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9697) bra t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9699) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9700) # smod(): computes the fp MOD of the input values X,Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9701) # srem(): computes the fp (IEEE) REM of the input values X,Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9702) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9703) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9704) # a0 = pointer to extended precision input X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9705) # a1 = pointer to extended precision input Y #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9706) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9707) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9708) # The input operands X and Y can be either normalized or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9709) # denormalized. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9710) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9711) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9712) # fp0 = FREM(X,Y) or FMOD(X,Y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9713) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9714) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9715) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9716) # Step 1. Save and strip signs of X and Y: signX := sign(X), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9717) # signY := sign(Y), X := |X|, Y := |Y|, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9718) # signQ := signX EOR signY. Record whether MOD or REM #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9719) # is requested. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9720) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9721) # Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9722) # If (L < 0) then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9723) # R := X, go to Step 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9724) # else #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9725) # R := 2^(-L)X, j := L. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9726) # endif #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9727) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9728) # Step 3. Perform MOD(X,Y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9729) # 3.1 If R = Y, go to Step 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9730) # 3.2 If R > Y, then { R := R - Y, Q := Q + 1} #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9731) # 3.3 If j = 0, go to Step 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9732) # 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9733) # Step 3.1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9734) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9735) # Step 4. At this point, R = X - QY = MOD(X,Y). Set #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9736) # Last_Subtract := false (used in Step 7 below). If #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9737) # MOD is requested, go to Step 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9738) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9739) # Step 5. R = MOD(X,Y), but REM(X,Y) is requested. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9740) # 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9741) # Step 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9742) # 5.2 If R > Y/2, then { set Last_Subtract := true, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9743) # Q := Q + 1, Y := signY*Y }. Go to Step 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9744) # 5.3 This is the tricky case of R = Y/2. If Q is odd, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9745) # then { Q := Q + 1, signX := -signX }. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9746) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9747) # Step 6. R := signX*R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9748) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9749) # Step 7. If Last_Subtract = true, R := R - Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9750) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9751) # Step 8. Return signQ, last 7 bits of Q, and R as required. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9752) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9753) # Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9754) # X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9755) # R := 0. Return signQ, last 7 bits of Q, and R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9756) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9757) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9759) set Mod_Flag,L_SCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9760) set Sc_Flag,L_SCR3+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9762) set SignY,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9763) set SignX,L_SCR2+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9764) set SignQ,L_SCR3+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9766) set Y,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9767) set Y_Hi,Y+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9768) set Y_Lo,Y+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9770) set R,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9771) set R_Hi,R+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9772) set R_Lo,R+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9774) Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9775) long 0x00010000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9777) global smod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9778) smod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9779) clr.b FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9780) mov.l %d0,-(%sp) # save ctrl bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9781) clr.b Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9782) bra.b Mod_Rem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9784) global srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9785) srem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9786) clr.b FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9787) mov.l %d0,-(%sp) # save ctrl bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9788) mov.b &0x1,Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9790) Mod_Rem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9791) #..Save sign of X and Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9792) movm.l &0x3f00,-(%sp) # save data registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9793) mov.w SRC_EX(%a0),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9794) mov.w %d3,SignY(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9795) and.l &0x00007FFF,%d3 # Y := |Y|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9797) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9798) mov.l SRC_HI(%a0),%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9799) mov.l SRC_LO(%a0),%d5 # (D3,D4,D5) is |Y|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9801) tst.l %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9802) bne.b Y_Normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9804) mov.l &0x00003FFE,%d3 # $3FFD + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9805) tst.l %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9806) bne.b HiY_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9808) HiY_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9809) mov.l %d5,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9810) clr.l %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9811) sub.l &32,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9812) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9813) bfffo %d4{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9814) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9815) sub.l %d6,%d3 # (D3,D4,D5) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9816) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9817) bra.b Chk_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9819) HiY_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9820) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9821) bfffo %d4{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9822) sub.l %d6,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9823) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9824) mov.l %d5,%d7 # a copy of D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9825) lsl.l %d6,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9826) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9827) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9828) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9829) or.l %d7,%d4 # (D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9830) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9831) bra.b Chk_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9833) Y_Normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9834) add.l &0x00003FFE,%d3 # (D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9835) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9837) Chk_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9838) mov.w DST_EX(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9839) mov.w %d0,SignX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9840) mov.w SignY(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9841) eor.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9842) and.l &0x00008000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9843) mov.w %d1,SignQ(%a6) # sign(Q) obtained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9844) and.l &0x00007FFF,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9845) mov.l DST_HI(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9846) mov.l DST_LO(%a1),%d2 # (D0,D1,D2) is |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9847) tst.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9848) bne.b X_Normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9849) mov.l &0x00003FFE,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9850) tst.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9851) bne.b HiX_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9853) HiX_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9854) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9855) clr.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9856) sub.l &32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9857) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9858) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9859) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9860) sub.l %d6,%d0 # (D0,D1,D2) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9861) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9862) bra.b Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9864) HiX_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9865) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9866) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9867) sub.l %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9868) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9869) mov.l %d2,%d7 # a copy of D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9870) lsl.l %d6,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9871) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9872) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9873) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9874) or.l %d7,%d1 # (D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9875) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9876) bra.b Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9878) X_Normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9879) add.l &0x00003FFE,%d0 # (D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9880) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9882) Init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9883) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9884) mov.l %d3,L_SCR1(%a6) # save biased exp(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9885) mov.l %d0,-(%sp) # save biased exp(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9886) sub.l %d3,%d0 # L := expo(X)-expo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9888) clr.l %d6 # D6 := carry <- 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9889) clr.l %d3 # D3 is Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9890) mov.l &0,%a1 # A1 is k; j+k=L, Q=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9892) #..(Carry,D1,D2) is R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9893) tst.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9894) bge.b Mod_Loop_pre
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9896) #..expo(X) < expo(Y). Thus X = mod(X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9897) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9898) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9899) bra.w Get_Mod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9901) Mod_Loop_pre:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9902) addq.l &0x4,%sp # erase exp(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9903) #..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9904) Mod_Loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9905) tst.l %d6 # test carry bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9906) bgt.b R_GT_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9908) #..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9909) cmp.l %d1,%d4 # compare hi(R) and hi(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9910) bne.b R_NE_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9911) cmp.l %d2,%d5 # compare lo(R) and lo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9912) bne.b R_NE_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9914) #..At this point, R = Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9915) bra.w Rem_is_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9917) R_NE_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9918) #..use the borrow of the previous compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9919) bcs.b R_LT_Y # borrow is set iff R < Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9921) R_GT_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9922) #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9923) #..and Y < (D1,D2) < 2Y. Either way, perform R - Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9924) sub.l %d5,%d2 # lo(R) - lo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9925) subx.l %d4,%d1 # hi(R) - hi(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9926) clr.l %d6 # clear carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9927) addq.l &1,%d3 # Q := Q + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9929) R_LT_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9930) #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9931) tst.l %d0 # see if j = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9932) beq.b PostLoop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9934) add.l %d3,%d3 # Q := 2Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9935) add.l %d2,%d2 # lo(R) = 2lo(R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9936) roxl.l &1,%d1 # hi(R) = 2hi(R) + carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9937) scs %d6 # set Carry if 2(R) overflows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9938) addq.l &1,%a1 # k := k+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9939) subq.l &1,%d0 # j := j - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9940) #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9942) bra.b Mod_Loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9944) PostLoop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9945) #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9947) #..normalize R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9948) mov.l L_SCR1(%a6),%d0 # new biased expo of R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9949) tst.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9950) bne.b HiR_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9952) HiR_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9953) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9954) clr.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9955) sub.l &32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9956) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9957) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9958) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9959) sub.l %d6,%d0 # (D0,D1,D2) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9960) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9961) bra.b Get_Mod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9963) HiR_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9964) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9965) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9966) bmi.b Get_Mod # already normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9967) sub.l %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9968) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9969) mov.l %d2,%d7 # a copy of D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9970) lsl.l %d6,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9971) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9972) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9973) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9974) or.l %d7,%d1 # (D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9976) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9977) Get_Mod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9978) cmp.l %d0,&0x000041FE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9979) bge.b No_Scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9980) Do_Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9981) mov.w %d0,R(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9982) mov.l %d1,R_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9983) mov.l %d2,R_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9984) mov.l L_SCR1(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9985) mov.w %d6,Y(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9986) mov.l %d4,Y_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9987) mov.l %d5,Y_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9988) fmov.x R(%a6),%fp0 # no exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9989) mov.b &1,Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9990) bra.b ModOrRem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9991) No_Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9992) mov.l %d1,R_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9993) mov.l %d2,R_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9994) sub.l &0x3FFE,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9995) mov.w %d0,R(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9996) mov.l L_SCR1(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9997) sub.l &0x3FFE,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9998) mov.l %d6,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9999) fmov.x R(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10000) mov.w %d6,Y(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10001) mov.l %d4,Y_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10002) mov.l %d5,Y_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10003) clr.b Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10005) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10006) ModOrRem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10007) tst.b Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10008) beq.b Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10010) mov.l L_SCR1(%a6),%d6 # new biased expo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10011) subq.l &1,%d6 # biased expo(Y/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10012) cmp.l %d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10013) blt.b Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10014) bgt.b Last_Sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10016) cmp.l %d1,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10017) bne.b Not_EQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10018) cmp.l %d2,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10019) bne.b Not_EQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10020) bra.w Tie_Case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10022) Not_EQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10023) bcs.b Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10025) Last_Sub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10026) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10027) fsub.x Y(%a6),%fp0 # no exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10028) addq.l &1,%d3 # Q := Q + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10030) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10031) Fix_Sign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10032) #..Get sign of X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10033) mov.w SignX(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10034) bge.b Get_Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10035) fneg.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10037) #..Get Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10038) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10039) Get_Q:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10040) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10041) mov.w SignQ(%a6),%d6 # D6 is sign(Q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10042) mov.l &8,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10043) lsr.l %d7,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10044) and.l &0x0000007F,%d3 # 7 bits of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10045) or.l %d6,%d3 # sign and bits of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10046) # swap %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10047) # fmov.l %fpsr,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10048) # and.l &0xFF00FFFF,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10049) # or.l %d3,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10050) # fmov.l %d6,%fpsr # put Q in fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10051) mov.b %d3,FPSR_QBYTE(%a6) # put Q in fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10053) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10054) Restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10055) movm.l (%sp)+,&0xfc # {%d2-%d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10056) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10057) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10058) tst.b Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10059) beq.b Finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10060) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10061) fmul.x Scale(%pc),%fp0 # may cause underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10062) bra t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10063) # the '040 package did this apparently to see if the dst operand for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10064) # preceding fmul was a denorm. but, it better not have been since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10065) # algorithm just got done playing with fp0 and expected no exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10066) # as a result. trust me...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10067) # bra t_avoid_unsupp # check for denorm as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10068) # ;result of the scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10070) Finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10071) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10072) fmov.x %fp0,%fp0 # capture exceptions & round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10073) bra t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10075) Rem_is_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10076) #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10077) addq.l &1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10078) cmp.l %d0,&8 # D0 is j
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10079) bge.b Q_Big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10081) lsl.l %d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10082) bra.b Set_R_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10084) Q_Big:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10085) clr.l %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10087) Set_R_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10088) fmov.s &0x00000000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10089) clr.b Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10090) bra.w Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10092) Tie_Case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10093) #..Check parity of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10094) mov.l %d3,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10095) and.l &0x00000001,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10096) tst.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10097) beq.w Fix_Sign # Q is even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10099) #..Q is odd, Q := Q + 1, signX := -signX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10100) addq.l &1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10101) mov.w SignX(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10102) eor.l &0x00008000,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10103) mov.w %d6,SignX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10104) bra.w Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10106) qnan: long 0x7fff0000, 0xffffffff, 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10108) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10109) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10110) # t_dz(): Handle DZ exception during transcendental emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10111) # Sets N bit according to sign of source operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10112) # t_dz2(): Handle DZ exception during transcendental emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10113) # Sets N bit always. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10114) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10115) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10116) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10117) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10118) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10119) # a0 = pointer to source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10120) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10121) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10122) # fp0 = default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10123) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10124) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10125) # - Store properly signed INF into fp0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10126) # - Set FPSR exception status dz bit, ccode inf bit, and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10127) # accrued dz bit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10128) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10129) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10131) global t_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10132) t_dz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10133) tst.b SRC_EX(%a0) # no; is src negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10134) bmi.b t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10136) dz_pinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10137) fmov.s &0x7f800000,%fp0 # return +INF in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10138) ori.l &dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10139) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10141) global t_dz2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10142) t_dz2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10143) fmov.s &0xff800000,%fp0 # return -INF in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10144) ori.l &dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10145) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10147) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10148) # OPERR exception: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10149) # - set FPSR exception status operr bit, condition code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10150) # nan bit; Store default NAN into fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10151) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10152) global t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10153) t_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10154) ori.l &opnan_mask,USER_FPSR(%a6) # set NaN/OPERR/AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10155) fmovm.x qnan(%pc),&0x80 # return default NAN in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10156) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10158) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10159) # Extended DENORM: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10160) # - For all functions that have a denormalized input and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10161) # that f(x)=x, this is the entry point. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10162) # - we only return the EXOP here if either underflow or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10163) # inexact is enabled. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10164) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10166) # Entry point for scale w/ extended denorm. The function does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10167) # NOT set INEX2/AUNFL/AINEX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10168) global t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10169) t_resdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10170) ori.l &unfl_mask,USER_FPSR(%a6) # set UNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10171) bra.b xdnrm_con
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10173) global t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10174) t_extdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10175) ori.l &unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10177) xdnrm_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10178) mov.l %a0,%a1 # make copy of src ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10179) mov.l %d0,%d1 # make copy of rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10180) andi.b &0xc0,%d1 # extended precision?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10181) bne.b xdnrm_sd # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10183) # result precision is extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10184) tst.b LOCAL_EX(%a0) # is denorm negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10185) bpl.b xdnrm_exit # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10187) bset &neg_bit,FPSR_CC(%a6) # yes; set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10188) bra.b xdnrm_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10190) # result precision is single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10191) xdnrm_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10192) mov.l %a1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10193) tst.b LOCAL_EX(%a0) # is denorm pos or neg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10194) smi.b %d1 # set d0 accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10195) bsr.l unf_sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10196) mov.l (%sp)+,%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10197) xdnrm_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10198) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10200) mov.b FPCR_ENABLE(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10201) andi.b &0x0a,%d0 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10202) bne.b xdnrm_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10203) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10205) ################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10206) # unfl enabled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10207) ################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10208) # we have a DENORM that needs to be converted into an EXOP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10209) # so, normalize the mantissa, add 0x6000 to the new exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10210) # and return the result in fp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10211) xdnrm_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10212) mov.w LOCAL_EX(%a1),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10213) mov.l LOCAL_HI(%a1),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10214) mov.l LOCAL_LO(%a1),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10216) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10217) bsr.l norm # normalize mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10218) addi.l &0x6000,%d0 # add extra bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10219) andi.w &0x8000,FP_SCR0_EX(%a6) # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10220) or.w %d0,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10222) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10223) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10225) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10226) # UNFL exception: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10227) # - This routine is for cases where even an EXOP isn't #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10228) # large enough to hold the range of this result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10229) # In such a case, the EXOP equals zero. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10230) # - Return the default result to the proper precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10231) # with the sign of this result being the same as that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10232) # of the src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10233) # - t_unfl2() is provided to force the result sign to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10234) # positive which is the desired result for fetox(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10235) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10236) global t_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10237) t_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10238) ori.l &unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10240) tst.b (%a0) # is result pos or neg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10241) smi.b %d1 # set d1 accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10242) bsr.l unf_sub # calc default unfl result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10243) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10245) fmov.s &0x00000000,%fp1 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10246) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10248) # t_unfl2 ALWAYS tells unf_sub to create a positive result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10249) global t_unfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10250) t_unfl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10251) ori.l &unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10253) sf.b %d1 # set d0 to represent positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10254) bsr.l unf_sub # calc default unfl result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10255) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10257) fmov.s &0x0000000,%fp1 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10258) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10260) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10261) # OVFL exception: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10262) # - This routine is for cases where even an EXOP isn't #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10263) # large enough to hold the range of this result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10264) # - Return the default result to the proper precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10265) # with the sign of this result being the same as that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10266) # of the src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10267) # - t_ovfl2() is provided to force the result sign to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10268) # positive which is the desired result for fcosh(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10269) # - t_ovfl_sc() is provided for scale() which only sets #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10270) # the inexact bits if the number is inexact for the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10271) # precision indicated. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10272) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10274) global t_ovfl_sc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10275) t_ovfl_sc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10276) ori.l &ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10278) mov.b %d0,%d1 # fetch rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10279) andi.b &0xc0,%d1 # extract rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10280) beq.b ovfl_work # prec is extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10282) tst.b LOCAL_HI(%a0) # is dst a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10283) bmi.b ovfl_sc_norm # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10285) # dst op is a DENORM. we have to normalize the mantissa to see if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10286) # result would be inexact for the given precision. make a copy of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10287) # dst so we don't screw up the version passed to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10288) mov.w LOCAL_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10289) mov.l LOCAL_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10290) mov.l LOCAL_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10291) lea FP_SCR0(%a6),%a0 # pass ptr to FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10292) movm.l &0xc080,-(%sp) # save d0-d1/a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10293) bsr.l norm # normalize mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10294) movm.l (%sp)+,&0x0103 # restore d0-d1/a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10296) ovfl_sc_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10297) cmpi.b %d1,&0x40 # is prec dbl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10298) bne.b ovfl_sc_dbl # no; sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10299) ovfl_sc_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10300) tst.l LOCAL_LO(%a0) # is lo lw of sgl set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10301) bne.b ovfl_sc_inx # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10302) tst.b 3+LOCAL_HI(%a0) # is lo byte of hi lw set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10303) bne.b ovfl_sc_inx # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10304) bra.b ovfl_work # don't set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10305) ovfl_sc_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10306) mov.l LOCAL_LO(%a0),%d1 # are any of lo 11 bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10307) andi.l &0x7ff,%d1 # dbl mantissa set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10308) beq.b ovfl_work # no; don't set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10309) ovfl_sc_inx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10310) ori.l &inex2_mask,USER_FPSR(%a6) # set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10311) bra.b ovfl_work # continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10313) global t_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10314) t_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10315) ori.l &ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10317) ovfl_work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10318) tst.b LOCAL_EX(%a0) # what is the sign?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10319) smi.b %d1 # set d1 accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10320) bsr.l ovf_res # calc default ovfl result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10321) mov.b %d0,FPSR_CC(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10322) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10324) fmov.s &0x00000000,%fp1 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10325) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10327) # t_ovfl2 ALWAYS tells ovf_res to create a positive result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10328) global t_ovfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10329) t_ovfl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10330) ori.l &ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10332) sf.b %d1 # clear sign flag for positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10333) bsr.l ovf_res # calc default ovfl result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10334) mov.b %d0,FPSR_CC(%a6) # insert new ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10335) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10337) fmov.s &0x00000000,%fp1 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10338) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10340) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10341) # t_catch(): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10342) # - the last operation of a transcendental emulation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10343) # routine may have caused an underflow or overflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10344) # we find out if this occurred by doing an fsave and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10345) # checking the exception bit. if one did occur, then we #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10346) # jump to fgen_except() which creates the default #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10347) # result and EXOP for us. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10348) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10349) global t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10350) t_catch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10352) fsave -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10353) tst.b 0x2(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10354) bmi.b catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10355) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10357) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10358) # INEX2 exception: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10359) # - The inex2 and ainex bits are set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10360) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10361) global t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10362) t_inx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10363) fblt.w t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10364) fbeq.w inx2_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10366) global t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10367) t_pinx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10368) ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10369) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10371) global t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10372) t_minx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10373) ori.l &inx2a_mask+neg_mask,USER_FPSR(%a6) # set N/INEX2/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10374) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10376) inx2_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10377) mov.b &z_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10378) ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10379) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10381) # an underflow or overflow exception occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10382) # we must set INEX/AINEX since the fmul/fdiv/fmov emulation may not!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10383) catch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10384) ori.w &inx2a_mask,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10385) catch2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10386) bsr.l fgen_except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10387) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10388) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10390) global t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10391) t_catch2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10393) fsave -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10395) tst.b 0x2(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10396) bmi.b catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10397) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10399) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10400) or.l %d0,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10402) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10404) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10406) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10407) # unf_res(): underflow default result calculation for transcendentals #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10408) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10409) # INPUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10410) # d0 : rnd mode,precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10411) # d1.b : sign bit of result ('11111111 = (-) ; '00000000 = (+)) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10412) # OUTPUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10413) # a0 : points to result (in instruction memory) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10414) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10415) unf_sub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10416) ori.l &unfinx_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10418) andi.w &0x10,%d1 # keep sign bit in 4th spot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10420) lsr.b &0x4,%d0 # shift rnd prec,mode to lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10421) andi.b &0xf,%d0 # strip hi rnd mode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10422) or.b %d1,%d0 # concat {sgn,mode,prec}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10424) mov.l %d0,%d1 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10425) lsl.b &0x1,%d1 # mult index 2 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10427) mov.b (tbl_unf_cc.b,%pc,%d0.w*1),FPSR_CC(%a6) # insert ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10428) lea (tbl_unf_result.b,%pc,%d1.w*8),%a0 # grab result ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10429) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10431) tbl_unf_cc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10432) byte 0x4, 0x4, 0x4, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10433) byte 0x4, 0x4, 0x4, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10434) byte 0x4, 0x4, 0x4, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10435) byte 0x0, 0x0, 0x0, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10436) byte 0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10437) byte 0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10438) byte 0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10440) tbl_unf_result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10441) long 0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10442) long 0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10443) long 0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10444) long 0x00000000, 0x00000000, 0x00000001, 0x0 # MIN; ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10446) long 0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10447) long 0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10448) long 0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10449) long 0x3f810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10451) long 0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10452) long 0x3c010000, 0x00000000, 0x00000000, 0x0 # ZER0;dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10453) long 0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10454) long 0x3c010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10456) long 0x0,0x0,0x0,0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10457) long 0x0,0x0,0x0,0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10458) long 0x0,0x0,0x0,0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10459) long 0x0,0x0,0x0,0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10461) long 0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10462) long 0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10463) long 0x80000000, 0x00000000, 0x00000001, 0x0 # MIN; ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10464) long 0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10466) long 0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10467) long 0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10468) long 0xbf810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10469) long 0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10471) long 0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10472) long 0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10473) long 0xbc010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10474) long 0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10476) ############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10478) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10479) # src_zero(): Return signed zero according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10480) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10481) global src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10482) src_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10483) tst.b SRC_EX(%a0) # get sign of src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10484) bmi.b ld_mzero # if neg, load neg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10486) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10487) # ld_pzero(): return a positive zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10488) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10489) global ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10490) ld_pzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10491) fmov.s &0x00000000,%fp0 # load +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10492) mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10493) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10495) # ld_mzero(): return a negative zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10496) global ld_mzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10497) ld_mzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10498) fmov.s &0x80000000,%fp0 # load -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10499) mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10500) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10502) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10503) # dst_zero(): Return signed zero according to sign of dst operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10504) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10505) global dst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10506) dst_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10507) tst.b DST_EX(%a1) # get sign of dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10508) bmi.b ld_mzero # if neg, load neg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10509) bra.b ld_pzero # load positive zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10511) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10512) # src_inf(): Return signed inf according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10513) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10514) global src_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10515) src_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10516) tst.b SRC_EX(%a0) # get sign of src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10517) bmi.b ld_minf # if negative branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10519) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10520) # ld_pinf(): return a positive infinity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10521) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10522) global ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10523) ld_pinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10524) fmov.s &0x7f800000,%fp0 # load +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10525) mov.b &inf_bmask,FPSR_CC(%a6) # set 'INF' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10526) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10528) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10529) # ld_minf():return a negative infinity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10530) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10531) global ld_minf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10532) ld_minf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10533) fmov.s &0xff800000,%fp0 # load -INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10534) mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10535) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10537) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10538) # dst_inf(): Return signed inf according to sign of dst operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10539) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10540) global dst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10541) dst_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10542) tst.b DST_EX(%a1) # get sign of dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10543) bmi.b ld_minf # if negative branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10544) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10546) global szr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10547) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10548) # szr_inf(): Return +ZERO for a negative src operand or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10549) # +INF for a positive src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10550) # Routine used for fetox, ftwotox, and ftentox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10551) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10552) szr_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10553) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10554) bmi.b ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10555) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10557) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10558) # sopr_inf(): Return +INF for a positive src operand or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10559) # jump to operand error routine for a negative src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10560) # Routine used for flogn, flognp1, flog10, and flog2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10561) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10562) global sopr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10563) sopr_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10564) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10565) bmi.w t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10566) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10568) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10569) # setoxm1i(): Return minus one for a negative src operand or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10570) # positive infinity for a positive src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10571) # Routine used for fetoxm1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10572) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10573) global setoxm1i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10574) setoxm1i:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10575) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10576) bmi.b ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10577) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10579) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10580) # src_one(): Return signed one according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10581) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10582) global src_one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10583) src_one:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10584) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10585) bmi.b ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10587) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10588) # ld_pone(): return positive one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10589) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10590) global ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10591) ld_pone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10592) fmov.s &0x3f800000,%fp0 # load +1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10593) clr.b FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10594) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10596) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10597) # ld_mone(): return negative one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10598) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10599) global ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10600) ld_mone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10601) fmov.s &0xbf800000,%fp0 # load -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10602) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10603) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10605) ppiby2: long 0x3fff0000, 0xc90fdaa2, 0x2168c235
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10606) mpiby2: long 0xbfff0000, 0xc90fdaa2, 0x2168c235
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10608) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10609) # spi_2(): Return signed PI/2 according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10610) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10611) global spi_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10612) spi_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10613) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10614) bmi.b ld_mpi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10616) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10617) # ld_ppi2(): return positive PI/2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10618) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10619) global ld_ppi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10620) ld_ppi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10621) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10622) fmov.x ppiby2(%pc),%fp0 # load +pi/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10623) bra.w t_pinx2 # set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10625) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10626) # ld_mpi2(): return negative PI/2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10627) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10628) global ld_mpi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10629) ld_mpi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10630) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10631) fmov.x mpiby2(%pc),%fp0 # load -pi/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10632) bra.w t_minx2 # set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10634) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10635) # The following routines give support for fsincos. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10636) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10638) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10639) # ssincosz(): When the src operand is ZERO, store a one in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10640) # cosine register and return a ZERO in fp0 w/ the same sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10641) # as the src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10642) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10643) global ssincosz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10644) ssincosz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10645) fmov.s &0x3f800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10646) tst.b SRC_EX(%a0) # test sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10647) bpl.b sincoszp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10648) fmov.s &0x80000000,%fp0 # return sin result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10649) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10650) bra.b sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10651) sincoszp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10652) fmov.s &0x00000000,%fp0 # return sin result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10653) mov.b &z_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10654) bra.b sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10656) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10657) # ssincosi(): When the src operand is INF, store a QNAN in the cosine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10658) # register and jump to the operand error routine for negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10659) # src operands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10660) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10661) global ssincosi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10662) ssincosi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10663) fmov.x qnan(%pc),%fp1 # load NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10664) bsr.l sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10665) bra.w t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10667) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10668) # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10669) # register and branch to the src QNAN routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10670) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10671) global ssincosqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10672) ssincosqnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10673) fmov.x LOCAL_EX(%a0),%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10674) bsr.l sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10675) bra.w src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10677) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10678) # ssincossnan(): When the src operand is an SNAN, store the SNAN w/ the SNAN bit set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10679) # in the cosine register and branch to the src SNAN routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10680) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10681) global ssincossnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10682) ssincossnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10683) fmov.x LOCAL_EX(%a0),%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10684) bsr.l sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10685) bra.w src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10687) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10689) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10690) # sto_cos(): store fp1 to the fpreg designated by the CMDREG dst field. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10691) # fp1 holds the result of the cosine portion of ssincos(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10692) # the value in fp1 will not take any exceptions when moved. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10693) # INPUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10694) # fp1 : fp value to store #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10695) # MODIFIED: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10696) # d0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10697) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10698) global sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10699) sto_cos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10700) mov.b 1+EXC_CMDREG(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10701) andi.w &0x7,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10702) mov.w (tbl_sto_cos.b,%pc,%d0.w*2),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10703) jmp (tbl_sto_cos.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10705) tbl_sto_cos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10706) short sto_cos_0 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10707) short sto_cos_1 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10708) short sto_cos_2 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10709) short sto_cos_3 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10710) short sto_cos_4 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10711) short sto_cos_5 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10712) short sto_cos_6 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10713) short sto_cos_7 - tbl_sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10715) sto_cos_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10716) fmovm.x &0x40,EXC_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10717) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10718) sto_cos_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10719) fmovm.x &0x40,EXC_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10720) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10721) sto_cos_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10722) fmov.x %fp1,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10723) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10724) sto_cos_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10725) fmov.x %fp1,%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10726) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10727) sto_cos_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10728) fmov.x %fp1,%fp4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10729) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10730) sto_cos_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10731) fmov.x %fp1,%fp5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10732) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10733) sto_cos_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10734) fmov.x %fp1,%fp6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10735) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10736) sto_cos_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10737) fmov.x %fp1,%fp7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10738) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10740) ##################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10741) global smod_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10742) global smod_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10743) smod_sdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10744) smod_snorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10745) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10746) beq.l smod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10747) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10748) beq.w smod_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10749) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10750) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10751) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10752) beq.l smod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10753) cmpi.b %d1,&SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10754) beq.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10755) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10757) global smod_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10758) smod_szero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10759) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10760) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10761) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10762) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10763) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10764) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10765) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10766) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10767) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10768) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10769) bra.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10771) global smod_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10772) smod_sinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10773) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10774) beq.l smod_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10775) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10776) beq.l smod_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10777) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10778) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10779) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10780) beq.l smod_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10781) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10782) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10783) bra.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10785) smod_zro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10786) srem_zro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10787) mov.b SRC_EX(%a0),%d1 # get src sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10788) mov.b DST_EX(%a1),%d0 # get dst sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10789) eor.b %d0,%d1 # get qbyte sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10790) andi.b &0x80,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10791) mov.b %d1,FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10792) tst.b %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10793) bpl.w ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10794) bra.w ld_mzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10796) smod_fpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10797) srem_fpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10798) clr.b FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10799) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10800) mov.b SRC_EX(%a0),%d1 # get src sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10801) mov.b DST_EX(%a1),%d0 # get dst sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10802) eor.b %d0,%d1 # get qbyte sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10803) andi.b &0x80,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10804) mov.b %d1,FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10805) cmpi.b DTAG(%a6),&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10806) bne.b smod_nrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10807) lea DST(%a1),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10808) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10809) bra t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10810) smod_nrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10811) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10812) fmov.x DST(%a1),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10813) tst.b DST_EX(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10814) bmi.b smod_nrm_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10815) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10817) smod_nrm_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10818) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10819) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10821) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10822) global srem_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10823) global srem_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10824) srem_sdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10825) srem_snorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10826) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10827) beq.l srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10828) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10829) beq.w srem_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10830) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10831) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10832) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10833) beq.l srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10834) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10835) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10836) bra.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10838) global srem_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10839) srem_szero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10840) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10841) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10842) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10843) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10844) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10845) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10846) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10847) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10848) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10849) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10850) bra.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10852) global srem_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10853) srem_sinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10854) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10855) beq.w srem_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10856) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10857) beq.w srem_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10858) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10859) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10860) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10861) beq.l srem_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10862) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10863) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10864) bra.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10866) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10867) global sscale_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10868) global sscale_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10869) sscale_snorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10870) sscale_sdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10871) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10872) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10873) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10874) beq.l dst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10875) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10876) beq.l dst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10877) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10878) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10879) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10880) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10881) bra.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10883) global sscale_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10884) sscale_szero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10885) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10886) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10887) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10888) beq.l dst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10889) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10890) beq.l dst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10891) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10892) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10893) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10894) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10895) bra.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10897) global sscale_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10898) sscale_sinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10899) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10900) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10901) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10902) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10903) cmpi.b %d1,&SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10904) beq.l dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10905) bra.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10907) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10909) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10910) # sop_sqnan(): The src op for frem/fmod/fscale was a QNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10911) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10912) global sop_sqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10913) sop_sqnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10914) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10915) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10916) beq.b dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10917) cmpi.b %d1,&SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10918) beq.b dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10919) bra.b src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10921) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10922) # sop_ssnan(): The src op for frem/fmod/fscale was an SNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10923) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10924) global sop_ssnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10925) sop_ssnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10926) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10927) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10928) beq.b dst_qnan_src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10929) cmpi.b %d1,&SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10930) beq.b dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10931) bra.b src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10933) dst_qnan_src_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10934) ori.l &snaniop_mask,USER_FPSR(%a6) # set NAN/SNAN/AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10935) bra.b dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10937) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10938) # dst_qnan(): Return the dst SNAN w/ the SNAN bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10939) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10940) global dst_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10941) dst_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10942) fmov.x DST(%a1),%fp0 # the fmove sets the SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10943) fmov.l %fpsr,%d0 # catch resulting status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10944) or.l %d0,USER_FPSR(%a6) # store status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10945) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10947) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10948) # dst_qnan(): Return the dst QNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10949) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10950) global dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10951) dst_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10952) fmov.x DST(%a1),%fp0 # return the non-signalling nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10953) tst.b DST_EX(%a1) # set ccodes according to QNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10954) bmi.b dst_qnan_m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10955) dst_qnan_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10956) mov.b &nan_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10957) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10958) dst_qnan_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10959) mov.b &neg_bmask+nan_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10960) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10962) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10963) # src_snan(): Return the src SNAN w/ the SNAN bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10964) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10965) global src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10966) src_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10967) fmov.x SRC(%a0),%fp0 # the fmove sets the SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10968) fmov.l %fpsr,%d0 # catch resulting status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10969) or.l %d0,USER_FPSR(%a6) # store status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10970) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10972) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10973) # src_qnan(): Return the src QNAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10974) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10975) global src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10976) src_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10977) fmov.x SRC(%a0),%fp0 # return the non-signalling nan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10978) tst.b SRC_EX(%a0) # set ccodes according to QNAN sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10979) bmi.b dst_qnan_m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10980) src_qnan_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10981) mov.b &nan_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10982) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10983) src_qnan_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10984) mov.b &neg_bmask+nan_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10985) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10987) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10988) # fkern2.s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10989) # These entry points are used by the exception handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10990) # routines where an instruction is selected by an index into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10991) # a large jump table corresponding to a given instruction which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10992) # has been decoded. Flow continues here where we now decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10993) # further according to the source operand type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10994) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10996) global fsinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10997) fsinh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10998) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10999) beq.l ssinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11000) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11001) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11002) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11003) beq.l src_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11004) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11005) beq.l ssinhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11006) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11007) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11008) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11010) global flognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11011) flognp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11012) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11013) beq.l slognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11014) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11015) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11016) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11017) beq.l sopr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11018) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11019) beq.l slognp1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11020) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11021) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11022) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11024) global fetoxm1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11025) fetoxm1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11026) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11027) beq.l setoxm1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11028) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11029) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11030) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11031) beq.l setoxm1i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11032) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11033) beq.l setoxm1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11034) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11035) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11036) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11038) global ftanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11039) ftanh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11040) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11041) beq.l stanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11042) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11043) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11044) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11045) beq.l src_one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11046) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11047) beq.l stanhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11048) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11049) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11050) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11052) global fatan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11053) fatan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11054) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11055) beq.l satan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11056) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11057) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11058) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11059) beq.l spi_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11060) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11061) beq.l satand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11062) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11063) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11064) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11066) global fasin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11067) fasin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11068) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11069) beq.l sasin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11070) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11071) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11072) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11073) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11074) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11075) beq.l sasind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11076) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11077) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11078) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11080) global fatanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11081) fatanh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11082) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11083) beq.l satanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11084) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11085) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11086) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11087) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11088) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11089) beq.l satanhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11090) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11091) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11092) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11094) global fsine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11095) fsine:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11096) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11097) beq.l ssin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11098) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11099) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11100) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11101) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11102) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11103) beq.l ssind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11104) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11105) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11106) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11108) global ftan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11109) ftan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11110) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11111) beq.l stan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11112) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11113) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11114) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11115) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11116) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11117) beq.l stand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11118) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11119) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11120) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11122) global fetox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11123) fetox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11124) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11125) beq.l setox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11126) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11127) beq.l ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11128) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11129) beq.l szr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11130) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11131) beq.l setoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11132) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11133) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11134) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11136) global ftwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11137) ftwotox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11138) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11139) beq.l stwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11140) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11141) beq.l ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11142) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11143) beq.l szr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11144) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11145) beq.l stwotoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11146) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11147) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11148) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11150) global ftentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11151) ftentox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11152) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11153) beq.l stentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11154) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11155) beq.l ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11156) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11157) beq.l szr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11158) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11159) beq.l stentoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11160) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11161) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11162) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11164) global flogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11165) flogn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11166) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11167) beq.l slogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11168) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11169) beq.l t_dz2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11170) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11171) beq.l sopr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11172) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11173) beq.l slognd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11174) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11175) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11176) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11178) global flog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11179) flog10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11180) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11181) beq.l slog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11182) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11183) beq.l t_dz2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11184) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11185) beq.l sopr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11186) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11187) beq.l slog10d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11188) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11189) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11190) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11192) global flog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11193) flog2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11194) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11195) beq.l slog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11196) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11197) beq.l t_dz2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11198) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11199) beq.l sopr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11200) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11201) beq.l slog2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11202) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11203) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11204) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11206) global fcosh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11207) fcosh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11208) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11209) beq.l scosh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11210) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11211) beq.l ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11212) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11213) beq.l ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11214) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11215) beq.l scoshd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11216) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11217) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11218) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11220) global facos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11221) facos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11222) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11223) beq.l sacos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11224) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11225) beq.l ld_ppi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11226) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11227) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11228) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11229) beq.l sacosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11230) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11231) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11232) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11234) global fcos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11235) fcos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11236) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11237) beq.l scos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11238) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11239) beq.l ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11240) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11241) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11242) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11243) beq.l scosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11244) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11245) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11246) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11248) global fgetexp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11249) fgetexp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11250) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11251) beq.l sgetexp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11252) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11253) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11254) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11255) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11256) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11257) beq.l sgetexpd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11258) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11259) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11260) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11262) global fgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11263) fgetman:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11264) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11265) beq.l sgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11266) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11267) beq.l src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11268) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11269) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11270) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11271) beq.l sgetmand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11272) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11273) beq.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11274) bra.l src_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11276) global fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11277) fsincos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11278) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11279) beq.l ssincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11280) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11281) beq.l ssincosz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11282) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11283) beq.l ssincosi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11284) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11285) beq.l ssincosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11286) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11287) beq.l ssincosqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11288) bra.l ssincossnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11290) global fmod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11291) fmod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11292) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11293) beq.l smod_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11294) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11295) beq.l smod_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11296) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11297) beq.l smod_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11298) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11299) beq.l smod_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11300) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11301) beq.l sop_sqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11302) bra.l sop_ssnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11304) global frem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11305) frem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11306) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11307) beq.l srem_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11308) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11309) beq.l srem_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11310) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11311) beq.l srem_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11312) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11313) beq.l srem_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11314) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11315) beq.l sop_sqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11316) bra.l sop_ssnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11318) global fscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11319) fscale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11320) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11321) beq.l sscale_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11322) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11323) beq.l sscale_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11324) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11325) beq.l sscale_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11326) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11327) beq.l sscale_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11328) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11329) beq.l sop_sqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11330) bra.l sop_ssnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11332) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11333) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11334) # fgen_except(): catch an exception during transcendental #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11335) # emulation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11336) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11337) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11338) # fmul() - emulate a multiply instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11339) # fadd() - emulate an add instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11340) # fin() - emulate an fmove instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11341) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11342) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11343) # fp0 = destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11344) # d0 = type of instruction that took exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11345) # fsave frame = source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11346) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11347) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11348) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11349) # fp1 = EXOP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11350) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11351) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11352) # An exception occurred on the last instruction of the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11353) # transcendental emulation. hopefully, this won't be happening much #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11354) # because it will be VERY slow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11355) # The only exceptions capable of passing through here are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11356) # Overflow, Underflow, and Unsupported Data Type. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11357) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11358) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11360) global fgen_except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11361) fgen_except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11362) cmpi.b 0x3(%sp),&0x7 # is exception UNSUPP?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11363) beq.b fge_unsupp # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11365) mov.b &NORM,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11367) fge_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11368) mov.b &NORM,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11370) # ok, I have a problem with putting the dst op at FP_DST. the emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11371) # routines aren't supposed to alter the operands but we've just squashed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11372) # FP_DST here...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11374) # 8/17/93 - this turns out to be more of a "cleanliness" standpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11375) # then a potential bug. to begin with, only the dyadic functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11376) # frem,fmod, and fscale would get the dst trashed here. But, for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11377) # the 060SP, the FP_DST is never used again anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11378) fmovm.x &0x80,FP_DST(%a6) # dst op is in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11380) lea 0x4(%sp),%a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11381) lea FP_DST(%a6),%a1 # pass: ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11383) cmpi.b %d1,&FMOV_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11384) beq.b fge_fin # it was an "fmov"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11385) cmpi.b %d1,&FADD_OP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11386) beq.b fge_fadd # it was an "fadd"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11387) fge_fmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11388) bsr.l fmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11389) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11390) fge_fadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11391) bsr.l fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11392) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11393) fge_fin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11394) bsr.l fin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11395) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11397) fge_unsupp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11398) mov.b &DENORM,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11399) bra.b fge_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11401) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11402) # This table holds the offsets of the emulation routines for each individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11403) # math operation relative to the address of this table. Included are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11404) # routines like fadd/fmul/fabs as well as the transcendentals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11405) # The location within the table is determined by the extension bits of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11406) # operation longword.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11407) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11409) swbeg &109
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11410) tbl_unsupp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11411) long fin - tbl_unsupp # 00: fmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11412) long fint - tbl_unsupp # 01: fint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11413) long fsinh - tbl_unsupp # 02: fsinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11414) long fintrz - tbl_unsupp # 03: fintrz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11415) long fsqrt - tbl_unsupp # 04: fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11416) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11417) long flognp1 - tbl_unsupp # 06: flognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11418) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11419) long fetoxm1 - tbl_unsupp # 08: fetoxm1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11420) long ftanh - tbl_unsupp # 09: ftanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11421) long fatan - tbl_unsupp # 0a: fatan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11422) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11423) long fasin - tbl_unsupp # 0c: fasin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11424) long fatanh - tbl_unsupp # 0d: fatanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11425) long fsine - tbl_unsupp # 0e: fsin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11426) long ftan - tbl_unsupp # 0f: ftan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11427) long fetox - tbl_unsupp # 10: fetox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11428) long ftwotox - tbl_unsupp # 11: ftwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11429) long ftentox - tbl_unsupp # 12: ftentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11430) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11431) long flogn - tbl_unsupp # 14: flogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11432) long flog10 - tbl_unsupp # 15: flog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11433) long flog2 - tbl_unsupp # 16: flog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11434) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11435) long fabs - tbl_unsupp # 18: fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11436) long fcosh - tbl_unsupp # 19: fcosh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11437) long fneg - tbl_unsupp # 1a: fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11438) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11439) long facos - tbl_unsupp # 1c: facos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11440) long fcos - tbl_unsupp # 1d: fcos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11441) long fgetexp - tbl_unsupp # 1e: fgetexp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11442) long fgetman - tbl_unsupp # 1f: fgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11443) long fdiv - tbl_unsupp # 20: fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11444) long fmod - tbl_unsupp # 21: fmod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11445) long fadd - tbl_unsupp # 22: fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11446) long fmul - tbl_unsupp # 23: fmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11447) long fsgldiv - tbl_unsupp # 24: fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11448) long frem - tbl_unsupp # 25: frem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11449) long fscale - tbl_unsupp # 26: fscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11450) long fsglmul - tbl_unsupp # 27: fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11451) long fsub - tbl_unsupp # 28: fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11452) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11453) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11454) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11455) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11456) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11457) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11458) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11459) long fsincos - tbl_unsupp # 30: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11460) long fsincos - tbl_unsupp # 31: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11461) long fsincos - tbl_unsupp # 32: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11462) long fsincos - tbl_unsupp # 33: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11463) long fsincos - tbl_unsupp # 34: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11464) long fsincos - tbl_unsupp # 35: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11465) long fsincos - tbl_unsupp # 36: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11466) long fsincos - tbl_unsupp # 37: fsincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11467) long fcmp - tbl_unsupp # 38: fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11468) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11469) long ftst - tbl_unsupp # 3a: ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11470) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11471) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11472) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11473) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11474) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11475) long fsin - tbl_unsupp # 40: fsmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11476) long fssqrt - tbl_unsupp # 41: fssqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11477) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11478) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11479) long fdin - tbl_unsupp # 44: fdmove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11480) long fdsqrt - tbl_unsupp # 45: fdsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11481) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11482) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11483) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11484) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11485) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11486) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11487) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11488) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11489) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11490) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11491) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11492) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11493) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11494) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11495) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11496) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11497) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11498) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11499) long fsabs - tbl_unsupp # 58: fsabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11500) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11501) long fsneg - tbl_unsupp # 5a: fsneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11502) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11503) long fdabs - tbl_unsupp # 5c: fdabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11504) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11505) long fdneg - tbl_unsupp # 5e: fdneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11506) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11507) long fsdiv - tbl_unsupp # 60: fsdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11508) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11509) long fsadd - tbl_unsupp # 62: fsadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11510) long fsmul - tbl_unsupp # 63: fsmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11511) long fddiv - tbl_unsupp # 64: fddiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11512) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11513) long fdadd - tbl_unsupp # 66: fdadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11514) long fdmul - tbl_unsupp # 67: fdmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11515) long fssub - tbl_unsupp # 68: fssub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11516) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11517) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11518) long tbl_unsupp - tbl_unsupp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11519) long fdsub - tbl_unsupp # 6c: fdsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11521) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11522) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11523) # fmul(): emulates the fmul instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11524) # fsmul(): emulates the fsmul instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11525) # fdmul(): emulates the fdmul instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11526) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11527) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11528) # scale_to_zero_src() - scale src exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11529) # scale_to_zero_dst() - scale dst exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11530) # unf_res() - return default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11531) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11532) # res_qnan() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11533) # res_snan() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11534) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11535) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11536) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11537) # a1 = pointer to extended precision destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11538) # d0 rnd prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11539) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11540) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11541) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11542) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11543) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11544) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11545) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11546) # norms/denorms into ext/sgl/dbl precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11547) # For norms/denorms, scale the exponents such that a multiply #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11548) # instruction won't cause an exception. Use the regular fmul to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11549) # compute a result. Check if the regular operands would have taken #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11550) # an exception. If so, return the default overflow/underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11551) # and return the EXOP if exceptions are enabled. Else, scale the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11552) # result operand to the proper exponent. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11553) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11554) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11556) align 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11557) tbl_fmul_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11558) long 0x3fff - 0x7ffe # ext_max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11559) long 0x3fff - 0x407e # sgl_max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11560) long 0x3fff - 0x43fe # dbl_max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11561) tbl_fmul_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11562) long 0x3fff + 0x0001 # ext_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11563) long 0x3fff - 0x3f80 # sgl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11564) long 0x3fff - 0x3c00 # dbl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11566) global fsmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11567) fsmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11568) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11569) ori.b &s_mode*0x10,%d0 # insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11570) bra.b fmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11572) global fdmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11573) fdmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11574) andi.b &0x30,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11575) ori.b &d_mode*0x10,%d0 # insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11577) global fmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11578) fmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11579) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11581) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11582) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11583) lsl.b &0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11584) or.b STAG(%a6),%d1 # combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11585) bne.w fmul_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11587) fmul_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11588) mov.w DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11589) mov.l DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11590) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11592) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11593) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11594) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11596) bsr.l scale_to_zero_src # scale src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11597) mov.l %d0,-(%sp) # save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11599) bsr.l scale_to_zero_dst # scale dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11601) add.l %d0,(%sp) # SCALE_FACTOR = scale1 + scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11603) mov.w 2+L_SCR3(%a6),%d1 # fetch precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11604) lsr.b &0x6,%d1 # shift to lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11605) mov.l (%sp)+,%d0 # load S.F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11606) cmp.l %d0,(tbl_fmul_ovfl.w,%pc,%d1.w*4) # would result ovfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11607) beq.w fmul_may_ovfl # result may rnd to overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11608) blt.w fmul_ovfl # result will overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11610) cmp.l %d0,(tbl_fmul_unfl.w,%pc,%d1.w*4) # would result unfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11611) beq.w fmul_may_unfl # result may rnd to no unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11612) bgt.w fmul_unfl # result will underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11614) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11615) # NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11616) # - the result of the multiply operation will neither overflow nor underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11617) # - do the multiply to the proper precision and rounding mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11618) # - scale the result exponent using the scale factor. if both operands were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11619) # normalized then we really don't need to go through this scaling. but for now,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11620) # this will do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11621) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11622) fmul_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11623) fmovm.x FP_SCR1(%a6),&0x80 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11625) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11626) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11628) fmul.x FP_SCR0(%a6),%fp0 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11630) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11631) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11633) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11635) fmul_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11636) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11637) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11638) mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11639) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11640) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11641) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11642) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11643) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11644) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11645) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11646) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11647) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11649) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11650) # OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11651) # - the result of the multiply operation is an overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11652) # - do the multiply to the proper precision and rounding mode in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11653) # set the inexact bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11654) # - calculate the default result and return it in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11655) # - if overflow or inexact is enabled, we need a multiply result rounded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11656) # extended precision. if the original operation was extended, then we have this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11657) # result. if the original operation was single or double, we have to do another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11658) # multiply using extended precision and the correct rounding mode. the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11659) # of this operation then has its exponent scaled by -0x6000 to create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11660) # exceptional operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11661) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11662) fmul_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11663) fmovm.x FP_SCR1(%a6),&0x80 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11665) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11666) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11668) fmul.x FP_SCR0(%a6),%fp0 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11670) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11671) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11673) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11675) # save setting this until now because this is where fmul_may_ovfl may jump in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11676) fmul_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11677) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11679) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11680) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11681) bne.b fmul_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11683) # calculate the default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11684) fmul_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11685) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11686) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11687) mov.l L_SCR3(%a6),%d0 # pass rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11688) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11689) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11690) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11691) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11693) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11694) # OVFL is enabled; Create EXOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11695) # - if precision is extended, then we have the EXOP. simply bias the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11696) # with an extra -0x6000. if the precision is single or double, we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11697) # calculate a result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11698) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11699) fmul_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11700) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11701) andi.b &0xc0,%d1 # test the rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11702) bne.b fmul_ovfl_ena_sd # it's sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11704) fmul_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11705) fmovm.x &0x80,FP_SCR0(%a6) # move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11707) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11708) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11709) mov.w %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11710) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11711) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11712) subi.l &0x6000,%d1 # subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11713) andi.w &0x7fff,%d1 # clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11714) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11715) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11716) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11717) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11718) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11719) bra.b fmul_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11721) fmul_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11722) fmovm.x FP_SCR1(%a6),&0x80 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11724) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11725) andi.b &0x30,%d1 # keep rnd mode only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11726) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11728) fmul.x FP_SCR0(%a6),%fp0 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11730) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11731) bra.b fmul_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11733) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11734) # may OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11735) # - the result of the multiply operation MAY overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11736) # - do the multiply to the proper precision and rounding mode in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11737) # set the inexact bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11738) # - calculate the default result and return it in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11739) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11740) fmul_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11741) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11743) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11744) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11746) fmul.x FP_SCR0(%a6),%fp0 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11748) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11749) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11751) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11753) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11754) fcmp.b %fp1,&0x2 # is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11755) fbge.w fmul_ovfl_tst # yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11757) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11758) bra.w fmul_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11760) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11761) # UNDERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11762) # - the result of the multiply operation is an underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11763) # - do the multiply to the proper precision and rounding mode in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11764) # set the inexact bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11765) # - calculate the default result and return it in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11766) # - if overflow or inexact is enabled, we need a multiply result rounded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11767) # extended precision. if the original operation was extended, then we have this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11768) # result. if the original operation was single or double, we have to do another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11769) # multiply using extended precision and the correct rounding mode. the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11770) # of this operation then has its exponent scaled by -0x6000 to create the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11771) # exceptional operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11772) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11773) fmul_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11774) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11776) # for fun, let's use only extended precision, round to zero. then, let
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11777) # the unf_res() routine figure out all the rest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11778) # will we get the correct answer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11779) fmovm.x FP_SCR1(%a6),&0x80 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11781) fmov.l &rz_mode*0x10,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11782) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11784) fmul.x FP_SCR0(%a6),%fp0 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11786) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11787) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11789) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11791) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11792) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11793) bne.b fmul_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11795) fmul_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11796) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11798) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11799) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11800) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11801) or.b %d0,FPSR_CC(%a6) # unf_res2 may have set 'Z'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11802) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11803) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11805) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11806) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11807) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11808) fmul_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11809) fmovm.x FP_SCR1(%a6),&0x40 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11811) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11812) andi.b &0xc0,%d1 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11813) bne.b fmul_unfl_ena_sd # no, sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11815) # 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 11816) # multiplication because we used RZ for all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11817) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11819) fmul_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11820) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11822) fmul.x FP_SCR0(%a6),%fp1 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11824) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11826) fmovm.x &0x40,FP_SCR0(%a6) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11827) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11828) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11829) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11830) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11831) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11832) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11833) addi.l &0x6000,%d1 # add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11834) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11835) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11836) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11837) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11838) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11839) bra.w fmul_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11841) fmul_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11842) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11843) andi.b &0x30,%d1 # use only rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11844) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11846) bra.b fmul_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11848) # MAY UNDERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11849) # -use the correct rounding mode and precision. this code favors operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11850) # that do not underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11851) fmul_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11852) fmovm.x FP_SCR1(%a6),&0x80 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11854) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11855) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11857) fmul.x FP_SCR0(%a6),%fp0 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11859) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11860) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11862) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11864) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11865) fcmp.b %fp1,&0x2 # is |result| > 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11866) fbgt.w fmul_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11867) fblt.w fmul_unfl # yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11869) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11870) # we still don't know if underflow occurred. result is ~ equal to 2. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11871) # 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 11872) # a normalized number that rounded down to a 2. so, redo the entire operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11873) # using RZ as the rounding mode to see what the pre-rounded result is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11874) # this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11875) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11876) fmovm.x FP_SCR1(%a6),&0x40 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11878) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11879) andi.b &0xc0,%d1 # keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11880) ori.b &rz_mode*0x10,%d1 # insert RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11882) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11883) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11885) fmul.x FP_SCR0(%a6),%fp1 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11887) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11888) fabs.x %fp1 # make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11889) fcmp.b %fp1,&0x2 # is |result| < 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11890) fbge.w fmul_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11891) bra.w fmul_unfl # yes, underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11893) ################################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11895) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11896) # Multiply: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11897) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11898) fmul_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11899) mov.w (tbl_fmul_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11900) jmp (tbl_fmul_op.b,%pc,%d1.w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11902) swbeg &48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11903) tbl_fmul_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11904) short fmul_norm - tbl_fmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11905) short fmul_zero - tbl_fmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11906) short fmul_inf_src - tbl_fmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11907) short fmul_res_qnan - tbl_fmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11908) short fmul_norm - tbl_fmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11909) short fmul_res_snan - tbl_fmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11910) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11911) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11913) short fmul_zero - tbl_fmul_op # ZERO x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11914) short fmul_zero - tbl_fmul_op # ZERO x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11915) short fmul_res_operr - tbl_fmul_op # ZERO x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11916) short fmul_res_qnan - tbl_fmul_op # ZERO x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11917) short fmul_zero - tbl_fmul_op # ZERO x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11918) short fmul_res_snan - tbl_fmul_op # ZERO x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11919) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11920) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11922) short fmul_inf_dst - tbl_fmul_op # INF x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11923) short fmul_res_operr - tbl_fmul_op # INF x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11924) short fmul_inf_dst - tbl_fmul_op # INF x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11925) short fmul_res_qnan - tbl_fmul_op # INF x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11926) short fmul_inf_dst - tbl_fmul_op # INF x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11927) short fmul_res_snan - tbl_fmul_op # INF x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11928) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11929) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11931) short fmul_res_qnan - tbl_fmul_op # QNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11932) short fmul_res_qnan - tbl_fmul_op # QNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11933) short fmul_res_qnan - tbl_fmul_op # QNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11934) short fmul_res_qnan - tbl_fmul_op # QNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11935) short fmul_res_qnan - tbl_fmul_op # QNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11936) short fmul_res_snan - tbl_fmul_op # QNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11937) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11938) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11940) short fmul_norm - tbl_fmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11941) short fmul_zero - tbl_fmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11942) short fmul_inf_src - tbl_fmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11943) short fmul_res_qnan - tbl_fmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11944) short fmul_norm - tbl_fmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11945) short fmul_res_snan - tbl_fmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11946) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11947) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11949) short fmul_res_snan - tbl_fmul_op # SNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11950) short fmul_res_snan - tbl_fmul_op # SNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11951) short fmul_res_snan - tbl_fmul_op # SNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11952) short fmul_res_snan - tbl_fmul_op # SNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11953) short fmul_res_snan - tbl_fmul_op # SNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11954) short fmul_res_snan - tbl_fmul_op # SNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11955) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11956) short tbl_fmul_op - tbl_fmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11958) fmul_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11959) bra.l res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11960) fmul_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11961) bra.l res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11962) fmul_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11963) bra.l res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11965) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11966) # Multiply: (Zero x Zero) || (Zero x norm) || (Zero x denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11967) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11968) global fmul_zero # global for fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11969) fmul_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11970) mov.b SRC_EX(%a0),%d0 # exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11971) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11972) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11973) bpl.b fmul_zero_p # result ZERO is pos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11974) fmul_zero_n:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11975) fmov.s &0x80000000,%fp0 # load -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11976) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11977) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11978) fmul_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11979) fmov.s &0x00000000,%fp0 # load +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11980) mov.b &z_bmask,FPSR_CC(%a6) # set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11981) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11983) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11984) # Multiply: (inf x inf) || (inf x norm) || (inf x denorm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11985) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11986) # Note: The j-bit for an infinity is a don't-care. However, to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11987) # strictly compatible w/ the 68881/882, we make sure to return an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11988) # INF w/ the j-bit set if the input INF j-bit was set. Destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11989) # INFs take priority.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11990) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11991) global fmul_inf_dst # global for fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11992) fmul_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11993) fmovm.x DST(%a1),&0x80 # return INF result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11994) mov.b SRC_EX(%a0),%d0 # exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11995) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11996) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11997) bpl.b fmul_inf_dst_p # result INF is pos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11998) fmul_inf_dst_n:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11999) fabs.x %fp0 # clear result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12000) fneg.x %fp0 # set result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12001) mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12002) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12003) fmul_inf_dst_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12004) fabs.x %fp0 # clear result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12005) mov.b &inf_bmask,FPSR_CC(%a6) # set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12006) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12008) global fmul_inf_src # global for fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12009) fmul_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12010) fmovm.x SRC(%a0),&0x80 # return INF result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12011) mov.b SRC_EX(%a0),%d0 # exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12012) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12013) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12014) bpl.b fmul_inf_dst_p # result INF is pos.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12015) bra.b fmul_inf_dst_n
^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) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12019) # fin(): emulates the fmove instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12020) # fsin(): emulates the fsmove instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12021) # fdin(): emulates the fdmove instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12022) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12023) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12024) # norm() - normalize mantissa for EXOP on denorm #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12025) # scale_to_zero_src() - scale src exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12026) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12027) # unf_res() - return default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12028) # res_qnan_1op() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12029) # res_snan_1op() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12030) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12031) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12032) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12033) # d0 = round prec/mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12034) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12035) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12036) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12037) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12038) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12039) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12040) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12041) # norms into extended, single, and double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12042) # Norms can be emulated w/ a regular fmove instruction. For #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12043) # sgl/dbl, must scale exponent and perform an "fmove". Check to see #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12044) # if the result would have overflowed/underflowed. If so, use unf_res() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12045) # or ovf_res() to return the default result. Also return EXOP if #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12046) # exception is enabled. If no exception, return the default result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12047) # Unnorms don't pass through here. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12048) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12049) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12051) global fsin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12052) fsin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12053) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12054) ori.b &s_mode*0x10,%d0 # insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12055) bra.b fin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12057) global fdin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12058) fdin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12059) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12060) ori.b &d_mode*0x10,%d0 # insert dbl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12062) global fin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12063) fin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12064) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12066) mov.b STAG(%a6),%d1 # fetch src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12067) bne.w fin_not_norm # optimize on non-norm input
^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) # FP MOVE IN: NORMs and DENORMs ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12071) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12072) fin_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12073) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12074) bne.w fin_not_ext # no, so go handle dbl or sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12076) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12077) # precision selected is extended. so...we cannot get an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12078) # or overflow because of rounding to the correct precision. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12079) # skip the scaling and unscaling...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12080) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12081) tst.b SRC_EX(%a0) # is the operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12082) bpl.b fin_norm_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12083) bset &neg_bit,FPSR_CC(%a6) # yes, so set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12084) fin_norm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12085) fmovm.x SRC(%a0),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12086) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12088) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12089) # for an extended precision DENORM, the UNFL exception bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12090) # the accrued bit is NOT set in this instance(no inexactness!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12091) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12092) fin_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12093) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12094) bne.w fin_not_ext # no, so go handle dbl or sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12096) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12097) tst.b SRC_EX(%a0) # is the operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12098) bpl.b fin_denorm_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12099) bset &neg_bit,FPSR_CC(%a6) # yes, so set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12100) fin_denorm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12101) fmovm.x SRC(%a0),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12102) btst &unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12103) bne.b fin_denorm_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12104) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12106) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12107) # the input is an extended DENORM and underflow is enabled in the FPCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12108) # normalize the mantissa and add the bias of 0x6000 to the resulting negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12109) # exponent and insert back into the operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12110) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12111) fin_denorm_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12112) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12113) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12114) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12115) lea FP_SCR0(%a6),%a0 # pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12116) bsr.l norm # normalize result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12117) neg.w %d0 # new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12118) addi.w &0x6000,%d0 # add new bias to exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12119) mov.w FP_SCR0_EX(%a6),%d1 # fetch old sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12120) andi.w &0x8000,%d1 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12121) andi.w &0x7fff,%d0 # clear sign position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12122) or.w %d1,%d0 # concat new exo,old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12123) mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12124) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12125) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12127) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12128) # operand is to be rounded to single or double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12129) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12130) fin_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12131) cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12132) bne.b fin_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12134) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12135) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12136) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12137) fin_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12138) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12139) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12140) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12141) bsr.l scale_to_zero_src # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12143) cmpi.l %d0,&0x3fff-0x3f80 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12144) bge.w fin_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12145) cmpi.l %d0,&0x3fff-0x407e # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12146) beq.w fin_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12147) blt.w fin_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12149) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12150) # operand will NOT overflow or underflow when moved into the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12151) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12152) fin_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12153) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12154) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12156) fmov.x FP_SCR0(%a6),%fp0 # perform move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12158) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12159) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12161) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12163) fin_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12164) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12165) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12166) mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12167) mov.w %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12168) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12169) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12170) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12171) or.w %d1,%d2 # concat old sign,new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12172) mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12173) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12174) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12175) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12177) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12178) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12179) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12180) fin_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12181) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12182) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12183) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12184) bsr.l scale_to_zero_src # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12186) cmpi.l %d0,&0x3fff-0x3c00 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12187) bge.w fin_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12188) cmpi.l %d0,&0x3fff-0x43fe # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12189) beq.w fin_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12190) blt.w fin_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12191) bra.w fin_sd_normal # no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12193) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12194) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12195) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12196) fin_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12197) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12199) tst.b FP_SCR0_EX(%a6) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12200) bpl.b fin_sd_unfl_tst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12201) bset &neg_bit,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12203) # if underflow or inexact is enabled, then go calculate the EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12204) fin_sd_unfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12205) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12206) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12207) bne.b fin_sd_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12209) fin_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12210) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12211) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12212) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12213) or.b %d0,FPSR_CC(%a6) # unf_res may have set 'Z'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12214) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12215) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12217) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12218) # operand will underflow AND underflow or inexact is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12219) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12220) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12221) fin_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12222) mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12223) mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12224) mov.w FP_SCR0_EX(%a6),%d1 # load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12226) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12227) mov.w %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12228) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12229) sub.l %d0,%d1 # subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12230) andi.w &0x8000,%d2 # extract old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12231) addi.l &0x6000,%d1 # add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12232) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12233) or.w %d1,%d2 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12234) mov.w %d2,FP_SCR1_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12235) fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12236) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12237) bra.b fin_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12239) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12240) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12241) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12242) fin_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12243) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12244) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12246) fmov.x FP_SCR0(%a6),%fp0 # perform move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12248) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12249) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12251) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12253) fin_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12254) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12256) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12257) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12258) bne.b fin_sd_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12260) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12261) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12262) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12263) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12264) fin_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12265) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12266) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12267) mov.l L_SCR3(%a6),%d0 # pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12268) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12269) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12270) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12271) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12273) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12274) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12275) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12276) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12277) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12278) fin_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12279) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12280) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12281) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12282) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12283) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12284) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12285) sub.l &0x6000,%d1 # subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12286) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12287) or.w %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12288) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12289) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12290) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12291) bra.b fin_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12293) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12294) # the move in MAY overflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12295) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12296) fin_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12297) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12298) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12300) fmov.x FP_SCR0(%a6),%fp0 # perform the move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12302) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12303) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12305) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12307) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12308) fcmp.b %fp1,&0x2 # is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12309) fbge.w fin_sd_ovfl_tst # yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12311) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12312) bra.w fin_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12314) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12316) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12317) # operand is not a NORM: check its optype and branch accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12318) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12319) fin_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12320) cmpi.b %d1,&DENORM # weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12321) beq.w fin_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12322) cmpi.b %d1,&SNAN # weed out SNANs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12323) beq.l res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12324) cmpi.b %d1,&QNAN # weed out QNANs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12325) beq.l res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12327) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12328) # do the fmove in; at this point, only possible ops are ZERO and INF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12329) # use fmov to determine ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12330) # prec:mode should be zero at this point but it won't affect answer anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12331) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12332) fmov.x SRC(%a0),%fp0 # do fmove in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12333) fmov.l %fpsr,%d0 # no exceptions possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12334) rol.l &0x8,%d0 # put ccodes in lo byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12335) mov.b %d0,FPSR_CC(%a6) # insert correct ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12336) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12338) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12339) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12340) # fdiv(): emulates the fdiv instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12341) # fsdiv(): emulates the fsdiv instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12342) # fddiv(): emulates the fddiv instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12343) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12344) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12345) # scale_to_zero_src() - scale src exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12346) # scale_to_zero_dst() - scale dst exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12347) # unf_res() - return default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12348) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12349) # res_qnan() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12350) # res_snan() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12351) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12352) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12353) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12354) # a1 = pointer to extended precision destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12355) # d0 rnd prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12356) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12357) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12358) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12359) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12360) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12361) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12362) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12363) # norms/denorms into ext/sgl/dbl precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12364) # For norms/denorms, scale the exponents such that a divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12365) # instruction won't cause an exception. Use the regular fdiv to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12366) # compute a result. Check if the regular operands would have taken #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12367) # an exception. If so, return the default overflow/underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12368) # and return the EXOP if exceptions are enabled. Else, scale the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12369) # result operand to the proper exponent. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12370) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12371) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12373) align 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12374) tbl_fdiv_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12375) long 0x3fff - 0x0000 # ext_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12376) long 0x3fff - 0x3f81 # sgl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12377) long 0x3fff - 0x3c01 # dbl_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12379) tbl_fdiv_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12380) long 0x3fff - 0x7ffe # ext overflow exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12381) long 0x3fff - 0x407e # sgl overflow exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12382) long 0x3fff - 0x43fe # dbl overflow exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12384) global fsdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12385) fsdiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12386) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12387) ori.b &s_mode*0x10,%d0 # insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12388) bra.b fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12390) global fddiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12391) fddiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12392) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12393) ori.b &d_mode*0x10,%d0 # insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12395) global fdiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12396) fdiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12397) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12399) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12400) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12401) lsl.b &0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12402) or.b STAG(%a6),%d1 # combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12404) bne.w fdiv_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12406) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12407) # DIVIDE: NORMs and DENORMs ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12408) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12409) fdiv_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12410) mov.w DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12411) mov.l DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12412) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12414) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12415) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12416) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12418) bsr.l scale_to_zero_src # scale src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12419) mov.l %d0,-(%sp) # save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12421) bsr.l scale_to_zero_dst # scale dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12423) neg.l (%sp) # SCALE FACTOR = scale1 - scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12424) add.l %d0,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12426) mov.w 2+L_SCR3(%a6),%d1 # fetch precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12427) lsr.b &0x6,%d1 # shift to lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12428) mov.l (%sp)+,%d0 # load S.F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12429) cmp.l %d0,(tbl_fdiv_ovfl.b,%pc,%d1.w*4) # will result overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12430) ble.w fdiv_may_ovfl # result will overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12432) cmp.l %d0,(tbl_fdiv_unfl.w,%pc,%d1.w*4) # will result underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12433) beq.w fdiv_may_unfl # maybe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12434) bgt.w fdiv_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12436) fdiv_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12437) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12439) fmov.l L_SCR3(%a6),%fpcr # save FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12440) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12442) fdiv.x FP_SCR0(%a6),%fp0 # perform divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12444) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12445) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12447) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12449) fdiv_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12450) fmovm.x &0x80,FP_SCR0(%a6) # store result on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12451) mov.l %d2,-(%sp) # store d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12452) mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12453) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12454) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12455) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12456) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12457) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12458) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12459) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12460) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12461) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12463) tbl_fdiv_ovfl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12464) long 0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12465) long 0x407f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12466) long 0x43ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12468) fdiv_no_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12469) mov.l (%sp)+,%d0 # restore scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12470) bra.b fdiv_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12472) fdiv_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12473) mov.l %d0,-(%sp) # save scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12475) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12477) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12478) fmov.l &0x0,%fpsr # set FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12480) fdiv.x FP_SCR0(%a6),%fp0 # execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12482) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12483) fmov.l &0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12485) or.l %d0,USER_FPSR(%a6) # save INEX,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12487) fmovm.x &0x01,-(%sp) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12488) mov.w (%sp),%d0 # fetch new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12489) add.l &0xc,%sp # clear result from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12490) andi.l &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12491) sub.l (%sp),%d0 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12492) cmp.l %d0,(tbl_fdiv_ovfl2.b,%pc,%d1.w*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12493) blt.b fdiv_no_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12494) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12496) fdiv_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12497) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12499) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12500) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12501) bne.b fdiv_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12503) fdiv_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12504) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12505) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12506) mov.l L_SCR3(%a6),%d0 # pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12507) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12508) or.b %d0,FPSR_CC(%a6) # set INF if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12509) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12510) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12512) fdiv_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12513) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12514) andi.b &0xc0,%d1 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12515) bne.b fdiv_ovfl_ena_sd # no, do sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12517) fdiv_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12518) fmovm.x &0x80,FP_SCR0(%a6) # move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12520) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12521) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12522) mov.w %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12523) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12524) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12525) subi.l &0x6000,%d1 # subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12526) andi.w &0x7fff,%d1 # clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12527) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12528) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12529) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12530) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12531) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12532) bra.b fdiv_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12534) fdiv_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12535) fmovm.x FP_SCR1(%a6),&0x80 # load dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12537) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12538) andi.b &0x30,%d1 # keep rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12539) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12541) fdiv.x FP_SCR0(%a6),%fp0 # execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12543) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12544) bra.b fdiv_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12546) fdiv_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12547) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12549) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12551) fmov.l &rz_mode*0x10,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12552) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12554) fdiv.x FP_SCR0(%a6),%fp0 # execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12556) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12557) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12559) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12561) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12562) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12563) bne.b fdiv_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12565) fdiv_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12566) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12568) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12569) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12570) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12571) or.b %d0,FPSR_CC(%a6) # 'Z' may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12572) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12573) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12575) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12576) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12577) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12578) fdiv_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12579) fmovm.x FP_SCR1(%a6),&0x40 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12581) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12582) andi.b &0xc0,%d1 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12583) bne.b fdiv_unfl_ena_sd # no, sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12585) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12587) fdiv_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12588) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12590) fdiv.x FP_SCR0(%a6),%fp1 # execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12592) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12594) fmovm.x &0x40,FP_SCR0(%a6) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12595) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12596) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12597) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12598) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12599) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12600) sub.l %d0,%d1 # add scale factoer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12601) addi.l &0x6000,%d1 # add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12602) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12603) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12604) mov.w %d1,FP_SCR0_EX(%a6) # insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12605) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12606) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12607) bra.w fdiv_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12609) fdiv_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12610) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12611) andi.b &0x30,%d1 # use only rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12612) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12614) bra.b fdiv_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12616) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12617) # the divide operation MAY underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12618) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12619) fdiv_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12620) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12622) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12623) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12625) fdiv.x FP_SCR0(%a6),%fp0 # execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12627) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12628) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12630) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12632) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12633) fcmp.b %fp1,&0x1 # is |result| > 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12634) fbgt.w fdiv_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12635) fblt.w fdiv_unfl # yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12637) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12638) # we still don't know if underflow occurred. result is ~ equal to 1. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12639) # 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 12640) # or a normalized number that rounded down to a 1. so, redo the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12641) # operation using RZ as the rounding mode to see what the pre-rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12642) # result is. this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12643) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12644) fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12646) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12647) andi.b &0xc0,%d1 # keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12648) ori.b &rz_mode*0x10,%d1 # insert RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12650) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12651) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12653) fdiv.x FP_SCR0(%a6),%fp1 # execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12655) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12656) fabs.x %fp1 # make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12657) fcmp.b %fp1,&0x1 # is |result| < 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12658) fbge.w fdiv_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12659) bra.w fdiv_unfl # yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12661) ############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12663) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12664) # Divide: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12665) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12666) fdiv_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12667) mov.w (tbl_fdiv_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12668) jmp (tbl_fdiv_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12670) swbeg &48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12671) tbl_fdiv_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12672) short fdiv_norm - tbl_fdiv_op # NORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12673) short fdiv_inf_load - tbl_fdiv_op # NORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12674) short fdiv_zero_load - tbl_fdiv_op # NORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12675) short fdiv_res_qnan - tbl_fdiv_op # NORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12676) short fdiv_norm - tbl_fdiv_op # NORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12677) short fdiv_res_snan - tbl_fdiv_op # NORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12678) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12679) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12681) short fdiv_zero_load - tbl_fdiv_op # ZERO / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12682) short fdiv_res_operr - tbl_fdiv_op # ZERO / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12683) short fdiv_zero_load - tbl_fdiv_op # ZERO / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12684) short fdiv_res_qnan - tbl_fdiv_op # ZERO / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12685) short fdiv_zero_load - tbl_fdiv_op # ZERO / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12686) short fdiv_res_snan - tbl_fdiv_op # ZERO / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12687) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12688) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12690) short fdiv_inf_dst - tbl_fdiv_op # INF / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12691) short fdiv_inf_dst - tbl_fdiv_op # INF / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12692) short fdiv_res_operr - tbl_fdiv_op # INF / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12693) short fdiv_res_qnan - tbl_fdiv_op # INF / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12694) short fdiv_inf_dst - tbl_fdiv_op # INF / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12695) short fdiv_res_snan - tbl_fdiv_op # INF / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12696) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12697) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12699) short fdiv_res_qnan - tbl_fdiv_op # QNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12700) short fdiv_res_qnan - tbl_fdiv_op # QNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12701) short fdiv_res_qnan - tbl_fdiv_op # QNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12702) short fdiv_res_qnan - tbl_fdiv_op # QNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12703) short fdiv_res_qnan - tbl_fdiv_op # QNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12704) short fdiv_res_snan - tbl_fdiv_op # QNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12705) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12706) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12708) short fdiv_norm - tbl_fdiv_op # DENORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12709) short fdiv_inf_load - tbl_fdiv_op # DENORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12710) short fdiv_zero_load - tbl_fdiv_op # DENORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12711) short fdiv_res_qnan - tbl_fdiv_op # DENORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12712) short fdiv_norm - tbl_fdiv_op # DENORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12713) short fdiv_res_snan - tbl_fdiv_op # DENORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12714) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12715) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12717) short fdiv_res_snan - tbl_fdiv_op # SNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12718) short fdiv_res_snan - tbl_fdiv_op # SNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12719) short fdiv_res_snan - tbl_fdiv_op # SNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12720) short fdiv_res_snan - tbl_fdiv_op # SNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12721) short fdiv_res_snan - tbl_fdiv_op # SNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12722) short fdiv_res_snan - tbl_fdiv_op # SNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12723) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12724) short tbl_fdiv_op - tbl_fdiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12726) fdiv_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12727) bra.l res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12728) fdiv_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12729) bra.l res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12730) fdiv_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12731) bra.l res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12733) global fdiv_zero_load # global for fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12734) fdiv_zero_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12735) mov.b SRC_EX(%a0),%d0 # result sign is exclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12736) mov.b DST_EX(%a1),%d1 # or of input signs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12737) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12738) bpl.b fdiv_zero_load_p # result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12739) fmov.s &0x80000000,%fp0 # load a -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12740) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12741) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12742) fdiv_zero_load_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12743) fmov.s &0x00000000,%fp0 # load a +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12744) mov.b &z_bmask,FPSR_CC(%a6) # set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12745) rts
^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) # The destination was In Range and the source was a ZERO. The result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12749) # Therefore, is an INF w/ the proper sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12750) # So, determine the sign and return a new INF (w/ the j-bit cleared).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12751) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12752) global fdiv_inf_load # global for fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12753) fdiv_inf_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12754) ori.w &dz_mask+adz_mask,2+USER_FPSR(%a6) # no; set DZ/ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12755) mov.b SRC_EX(%a0),%d0 # load both signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12756) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12757) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12758) bpl.b fdiv_inf_load_p # result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12759) fmov.s &0xff800000,%fp0 # make result -INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12760) mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12761) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12762) fdiv_inf_load_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12763) fmov.s &0x7f800000,%fp0 # make result +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12764) mov.b &inf_bmask,FPSR_CC(%a6) # set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12765) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12767) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12768) # The destination was an INF w/ an In Range or ZERO source, the result is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12769) # an INF w/ the proper sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12770) # 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 12771) # dst INF is set, then then j-bit of the result INF is also set).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12772) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12773) global fdiv_inf_dst # global for fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12774) fdiv_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12775) mov.b DST_EX(%a1),%d0 # load both signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12776) mov.b SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12777) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12778) bpl.b fdiv_inf_dst_p # result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12780) fmovm.x DST(%a1),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12781) fabs.x %fp0 # clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12782) fneg.x %fp0 # set sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12783) mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12784) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12786) fdiv_inf_dst_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12787) fmovm.x DST(%a1),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12788) fabs.x %fp0 # return positive INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12789) mov.b &inf_bmask,FPSR_CC(%a6) # set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12790) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12792) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12793) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12794) # fneg(): emulates the fneg instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12795) # fsneg(): emulates the fsneg instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12796) # fdneg(): emulates the fdneg instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12797) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12798) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12799) # norm() - normalize a denorm to provide EXOP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12800) # scale_to_zero_src() - scale sgl/dbl source exponent #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12801) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12802) # unf_res() - return default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12803) # res_qnan_1op() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12804) # res_snan_1op() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12805) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12806) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12807) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12808) # d0 = rnd prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12809) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12810) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12811) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12812) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12813) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12814) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12815) # Handle NANs, zeroes, and infinities as special cases. Separate #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12816) # norms/denorms into ext/sgl/dbl precisions. Extended precision can be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12817) # emulated by simply setting sign bit. Sgl/dbl operands must be scaled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12818) # and an actual fneg performed to see if overflow/underflow would have #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12819) # occurred. If so, return default underflow/overflow result. Else, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12820) # scale the result exponent and return result. FPSR gets set based on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12821) # the result value. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12822) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12823) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12825) global fsneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12826) fsneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12827) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12828) ori.b &s_mode*0x10,%d0 # insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12829) bra.b fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12831) global fdneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12832) fdneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12833) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12834) ori.b &d_mode*0x10,%d0 # insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12836) global fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12837) fneg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12838) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12839) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12840) bne.w fneg_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12842) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12843) # NEGATE SIGN : norms and denorms ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12844) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12845) fneg_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12846) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12847) bne.w fneg_not_ext # no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12849) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12850) # precision selected is extended. so...we can not get an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12851) # or overflow because of rounding to the correct precision. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12852) # skip the scaling and unscaling...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12853) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12854) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12855) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12856) mov.w SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12857) eori.w &0x8000,%d0 # negate sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12858) bpl.b fneg_norm_load # sign is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12859) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12860) fneg_norm_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12861) mov.w %d0,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12862) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12863) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12865) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12866) # for an extended precision DENORM, the UNFL exception bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12867) # the accrued bit is NOT set in this instance(no inexactness!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12868) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12869) fneg_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12870) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12871) bne.b fneg_not_ext # no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12873) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12875) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12876) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12877) mov.w SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12878) eori.w &0x8000,%d0 # negate sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12879) bpl.b fneg_denorm_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12880) mov.b &neg_bmask,FPSR_CC(%a6) # yes, set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12881) fneg_denorm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12882) mov.w %d0,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12883) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12885) btst &unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12886) bne.b fneg_ext_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12887) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12889) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12890) # the input is an extended DENORM and underflow is enabled in the FPCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12891) # normalize the mantissa and add the bias of 0x6000 to the resulting negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12892) # exponent and insert back into the operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12893) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12894) fneg_ext_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12895) lea FP_SCR0(%a6),%a0 # pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12896) bsr.l norm # normalize result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12897) neg.w %d0 # new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12898) addi.w &0x6000,%d0 # add new bias to exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12899) mov.w FP_SCR0_EX(%a6),%d1 # fetch old sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12900) andi.w &0x8000,%d1 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12901) andi.w &0x7fff,%d0 # clear sign position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12902) or.w %d1,%d0 # concat old sign, new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12903) mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12904) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12905) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12907) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12908) # operand is either single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12909) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12910) fneg_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12911) cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12912) bne.b fneg_dbl
^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) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12916) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12917) fneg_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12918) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12919) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12920) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12921) bsr.l scale_to_zero_src # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12923) cmpi.l %d0,&0x3fff-0x3f80 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12924) bge.w fneg_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12925) cmpi.l %d0,&0x3fff-0x407e # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12926) beq.w fneg_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12927) blt.w fneg_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12929) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12930) # operand will NOT overflow or underflow when moved in to the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12931) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12932) fneg_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12933) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12934) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12936) fneg.x FP_SCR0(%a6),%fp0 # perform negation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12938) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12939) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12941) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12943) fneg_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12944) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12945) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12946) mov.w FP_SCR0_EX(%a6),%d1 # load sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12947) mov.w %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12948) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12949) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12950) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12951) or.w %d1,%d2 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12952) mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12953) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12954) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12955) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12957) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12958) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12959) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12960) fneg_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12961) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12962) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12963) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12964) bsr.l scale_to_zero_src # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12966) cmpi.l %d0,&0x3fff-0x3c00 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12967) bge.b fneg_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12968) cmpi.l %d0,&0x3fff-0x43fe # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12969) beq.w fneg_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12970) blt.w fneg_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12971) bra.w fneg_sd_normal # no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12973) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12974) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12975) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12976) fneg_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12977) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12979) eori.b &0x80,FP_SCR0_EX(%a6) # negate sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12980) bpl.b fneg_sd_unfl_tst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12981) bset &neg_bit,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12983) # if underflow or inexact is enabled, go calculate EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12984) fneg_sd_unfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12985) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12986) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12987) bne.b fneg_sd_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12989) fneg_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12990) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12991) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12992) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12993) or.b %d0,FPSR_CC(%a6) # unf_res may have set 'Z'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12994) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12995) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12997) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12998) # operand will underflow AND underflow is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12999) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13000) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13001) fneg_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13002) mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13003) mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13004) mov.w FP_SCR0_EX(%a6),%d1 # load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13006) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13007) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13008) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13009) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13010) sub.l %d0,%d1 # subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13011) addi.l &0x6000,%d1 # add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13012) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13013) or.w %d2,%d1 # concat new sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13014) mov.w %d1,FP_SCR1_EX(%a6) # insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13015) fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13016) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13017) bra.b fneg_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13019) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13020) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13021) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13022) fneg_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13023) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13024) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13026) fneg.x FP_SCR0(%a6),%fp0 # perform negation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13028) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13029) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13031) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13033) fneg_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13034) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13036) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13037) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13038) bne.b fneg_sd_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13040) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13041) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13042) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13043) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13044) fneg_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13045) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13046) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13047) mov.l L_SCR3(%a6),%d0 # pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13048) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13049) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13050) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13051) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13053) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13054) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13055) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13056) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13057) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13058) fneg_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13059) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13060) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13061) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13062) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13063) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13064) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13065) subi.l &0x6000,%d1 # subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13066) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13067) or.w %d2,%d1 # concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13068) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13069) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13070) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13071) bra.b fneg_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13073) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13074) # the move in MAY underflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13075) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13076) fneg_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13077) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13078) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13080) fneg.x FP_SCR0(%a6),%fp0 # perform negation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13082) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13083) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13085) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13087) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13088) fcmp.b %fp1,&0x2 # is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13089) fbge.w fneg_sd_ovfl_tst # yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13091) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13092) bra.w fneg_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13094) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13096) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13097) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13098) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13099) fneg_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13100) cmpi.b %d1,&DENORM # weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13101) beq.w fneg_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13102) cmpi.b %d1,&SNAN # weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13103) beq.l res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13104) cmpi.b %d1,&QNAN # weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13105) beq.l res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13107) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13108) # do the fneg; at this point, only possible ops are ZERO and INF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13109) # use fneg to determine ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13110) # prec:mode should be zero at this point but it won't affect answer anyways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13111) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13112) fneg.x SRC_EX(%a0),%fp0 # do fneg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13113) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13114) rol.l &0x8,%d0 # put ccodes in lo byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13115) mov.b %d0,FPSR_CC(%a6) # insert correct ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13116) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13118) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13119) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13120) # ftst(): emulates the ftest instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13121) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13122) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13123) # res{s,q}nan_1op() - set NAN result for monadic instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13124) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13125) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13126) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13127) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13128) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13129) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13130) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13131) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13132) # Check the source operand tag (STAG) and set the FPCR according #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13133) # to the operand type and sign. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13134) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13135) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13137) global ftst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13138) ftst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13139) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13140) bne.b ftst_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13142) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13143) # Norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13144) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13145) ftst_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13146) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13147) bmi.b ftst_norm_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13148) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13149) ftst_norm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13150) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13151) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13153) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13154) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13155) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13156) ftst_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13157) cmpi.b %d1,&ZERO # weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13158) beq.b ftst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13159) cmpi.b %d1,&INF # weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13160) beq.b ftst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13161) cmpi.b %d1,&SNAN # weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13162) beq.l res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13163) cmpi.b %d1,&QNAN # weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13164) beq.l res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13166) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13167) # Denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13168) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13169) ftst_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13170) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13171) bmi.b ftst_denorm_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13172) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13173) ftst_denorm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13174) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13175) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13177) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13178) # Infinity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13179) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13180) ftst_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13181) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13182) bmi.b ftst_inf_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13183) ftst_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13184) mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13185) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13186) ftst_inf_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13187) mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'I','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13188) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13190) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13191) # Zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13192) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13193) ftst_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13194) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13195) bmi.b ftst_zero_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13196) ftst_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13197) mov.b &z_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13198) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13199) ftst_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13200) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13201) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13203) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13204) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13205) # fint(): emulates the fint instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13206) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13207) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13208) # res_{s,q}nan_1op() - set NAN result for monadic operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13209) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13210) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13211) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13212) # d0 = round precision/mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13213) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13214) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13215) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13216) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13217) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13218) # Separate according to operand type. Unnorms don't pass through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13219) # here. For norms, load the rounding mode/prec, execute a "fint", then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13220) # store the resulting FPSR bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13221) # For denorms, force the j-bit to a one and do the same as for #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13222) # norms. Denorms are so low that the answer will either be a zero or a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13223) # one. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13224) # For zeroes/infs/NANs, return the same while setting the FPSR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13225) # as appropriate. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13226) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13227) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13229) global fint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13230) fint:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13231) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13232) bne.b fint_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13234) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13235) # Norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13236) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13237) fint_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13238) andi.b &0x30,%d0 # set prec = ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13240) fmov.l %d0,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13241) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13243) fint.x SRC(%a0),%fp0 # execute fint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13245) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13246) fmov.l %fpsr,%d0 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13247) or.l %d0,USER_FPSR(%a6) # set exception bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13249) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13251) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13252) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13253) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13254) fint_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13255) cmpi.b %d1,&ZERO # weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13256) beq.b fint_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13257) cmpi.b %d1,&INF # weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13258) beq.b fint_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13259) cmpi.b %d1,&DENORM # weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13260) beq.b fint_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13261) cmpi.b %d1,&SNAN # weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13262) beq.l res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13263) bra.l res_qnan_1op # weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13265) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13266) # Denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13267) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13268) # for DENORMs, the result will be either (+/-)ZERO or (+/-)1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13269) # also, the INEX2 and AINEX exception bits will be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13270) # so, we could either set these manually or force the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13271) # to a very small NORM and ship it to the NORM routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13272) # I do the latter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13273) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13274) fint_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13275) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13276) mov.b &0x80,FP_SCR0_HI(%a6) # force DENORM ==> small NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13277) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13278) bra.b fint_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13280) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13281) # Zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13282) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13283) fint_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13284) tst.b SRC_EX(%a0) # is ZERO negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13285) bmi.b fint_zero_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13286) fint_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13287) fmov.s &0x00000000,%fp0 # return +ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13288) mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13289) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13290) fint_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13291) fmov.s &0x80000000,%fp0 # return -ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13292) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13293) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13295) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13296) # Infinity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13297) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13298) fint_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13299) fmovm.x SRC(%a0),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13300) tst.b SRC_EX(%a0) # is INF negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13301) bmi.b fint_inf_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13302) fint_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13303) mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13304) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13305) fint_inf_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13306) mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13307) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13309) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13310) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13311) # fintrz(): emulates the fintrz instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13312) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13313) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13314) # res_{s,q}nan_1op() - set NAN result for monadic operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13315) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13316) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13317) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13318) # d0 = round precision/mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13319) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13320) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13321) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13322) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13323) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13324) # Separate according to operand type. Unnorms don't pass through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13325) # here. For norms, load the rounding mode/prec, execute a "fintrz", #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13326) # then store the resulting FPSR bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13327) # For denorms, force the j-bit to a one and do the same as for #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13328) # norms. Denorms are so low that the answer will either be a zero or a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13329) # one. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13330) # For zeroes/infs/NANs, return the same while setting the FPSR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13331) # as appropriate. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13332) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13333) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13335) global fintrz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13336) fintrz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13337) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13338) bne.b fintrz_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13340) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13341) # Norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13342) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13343) fintrz_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13344) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13346) fintrz.x SRC(%a0),%fp0 # execute fintrz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13348) fmov.l %fpsr,%d0 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13349) or.l %d0,USER_FPSR(%a6) # set exception bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13351) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13353) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13354) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13355) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13356) fintrz_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13357) cmpi.b %d1,&ZERO # weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13358) beq.b fintrz_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13359) cmpi.b %d1,&INF # weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13360) beq.b fintrz_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13361) cmpi.b %d1,&DENORM # weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13362) beq.b fintrz_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13363) cmpi.b %d1,&SNAN # weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13364) beq.l res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13365) bra.l res_qnan_1op # weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13367) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13368) # Denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13369) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13370) # for DENORMs, the result will be (+/-)ZERO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13371) # also, the INEX2 and AINEX exception bits will be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13372) # so, we could either set these manually or force the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13373) # to a very small NORM and ship it to the NORM routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13374) # I do the latter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13375) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13376) fintrz_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13377) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13378) mov.b &0x80,FP_SCR0_HI(%a6) # force DENORM ==> small NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13379) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13380) bra.b fintrz_norm
^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) # Zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13384) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13385) fintrz_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13386) tst.b SRC_EX(%a0) # is ZERO negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13387) bmi.b fintrz_zero_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13388) fintrz_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13389) fmov.s &0x00000000,%fp0 # return +ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13390) mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13391) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13392) fintrz_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13393) fmov.s &0x80000000,%fp0 # return -ZERO in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13394) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13395) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13397) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13398) # Infinity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13399) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13400) fintrz_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13401) fmovm.x SRC(%a0),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13402) tst.b SRC_EX(%a0) # is INF negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13403) bmi.b fintrz_inf_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13404) fintrz_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13405) mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13406) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13407) fintrz_inf_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13408) mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13409) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13411) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13412) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13413) # fabs(): emulates the fabs instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13414) # fsabs(): emulates the fsabs instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13415) # fdabs(): emulates the fdabs instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13416) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13417) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13418) # norm() - normalize denorm mantissa to provide EXOP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13419) # scale_to_zero_src() - make exponent. = 0; get scale factor #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13420) # unf_res() - calculate underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13421) # ovf_res() - calculate overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13422) # res_{s,q}nan_1op() - set NAN result for monadic operation #
^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 extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13426) # d0 = rnd precision/mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13427) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13428) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13429) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13430) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13431) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13432) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13433) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13434) # norms into extended, single, and double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13435) # Simply clear sign for extended precision norm. Ext prec denorm #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13436) # gets an EXOP created for it since it's an underflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13437) # Double and single precision can overflow and underflow. First, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13438) # scale the operand such that the exponent is zero. Perform an "fabs" #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13439) # using the correct rnd mode/prec. Check to see if the original #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13440) # exponent would take an exception. If so, use unf_res() or ovf_res() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13441) # to calculate the default result. Also, create the EXOP for the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13442) # exceptional case. If no exception should occur, insert the correct #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13443) # result exponent and return. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13444) # Unnorms don't pass through here. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13445) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13446) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13448) global fsabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13449) fsabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13450) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13451) ori.b &s_mode*0x10,%d0 # insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13452) bra.b fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13454) global fdabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13455) fdabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13456) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13457) ori.b &d_mode*0x10,%d0 # insert dbl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13459) global fabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13460) fabs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13461) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13462) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13463) bne.w fabs_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13465) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13466) # ABSOLUTE VALUE: norms and denorms ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13467) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13468) fabs_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13469) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13470) bne.b fabs_not_ext # no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13472) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13473) # precision selected is extended. so...we can not get an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13474) # or overflow because of rounding to the correct precision. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13475) # skip the scaling and unscaling...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13476) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13477) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13478) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13479) mov.w SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13480) bclr &15,%d1 # force absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13481) mov.w %d1,FP_SCR0_EX(%a6) # insert exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13482) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13483) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13485) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13486) # for an extended precision DENORM, the UNFL exception bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13487) # the accrued bit is NOT set in this instance(no inexactness!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13488) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13489) fabs_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13490) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13491) bne.b fabs_not_ext # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13493) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13495) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13496) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13497) mov.w SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13498) bclr &15,%d0 # clear sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13499) mov.w %d0,FP_SCR0_EX(%a6) # insert exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13501) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13503) btst &unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13504) bne.b fabs_ext_unfl_ena
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13505) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13507) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13508) # the input is an extended DENORM and underflow is enabled in the FPCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13509) # normalize the mantissa and add the bias of 0x6000 to the resulting negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13510) # exponent and insert back into the operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13511) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13512) fabs_ext_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13513) lea FP_SCR0(%a6),%a0 # pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13514) bsr.l norm # normalize result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13515) neg.w %d0 # new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13516) addi.w &0x6000,%d0 # add new bias to exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13517) mov.w FP_SCR0_EX(%a6),%d1 # fetch old sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13518) andi.w &0x8000,%d1 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13519) andi.w &0x7fff,%d0 # clear sign position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13520) or.w %d1,%d0 # concat old sign, new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13521) mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13522) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13523) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13525) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13526) # operand is either single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13527) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13528) fabs_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13529) cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13530) bne.b fabs_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13532) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13533) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13534) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13535) fabs_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13536) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13537) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13538) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13539) bsr.l scale_to_zero_src # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13541) cmpi.l %d0,&0x3fff-0x3f80 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13542) bge.w fabs_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13543) cmpi.l %d0,&0x3fff-0x407e # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13544) beq.w fabs_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13545) blt.w fabs_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13547) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13548) # operand will NOT overflow or underflow when moved in to the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13549) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13550) fabs_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13551) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13552) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13554) fabs.x FP_SCR0(%a6),%fp0 # perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13556) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13557) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13559) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13561) fabs_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13562) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13563) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13564) mov.w FP_SCR0_EX(%a6),%d1 # load sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13565) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13566) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13567) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13568) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13569) or.w %d1,%d2 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13570) mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13571) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13572) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13573) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13575) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13576) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13577) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13578) fabs_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13579) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13580) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13581) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13582) bsr.l scale_to_zero_src # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13584) cmpi.l %d0,&0x3fff-0x3c00 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13585) bge.b fabs_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13586) cmpi.l %d0,&0x3fff-0x43fe # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13587) beq.w fabs_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13588) blt.w fabs_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13589) bra.w fabs_sd_normal # no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13591) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13592) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13593) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13594) fabs_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13595) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13597) bclr &0x7,FP_SCR0_EX(%a6) # force absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13599) # if underflow or inexact is enabled, go calculate EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13600) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13601) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13602) bne.b fabs_sd_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13604) fabs_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13605) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13606) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13607) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13608) or.b %d0,FPSR_CC(%a6) # set possible 'Z' ccode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13609) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13610) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13612) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13613) # operand will underflow AND underflow is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13614) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13615) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13616) fabs_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13617) mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13618) mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13619) mov.w FP_SCR0_EX(%a6),%d1 # load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13621) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13622) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13623) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13624) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13625) sub.l %d0,%d1 # subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13626) addi.l &0x6000,%d1 # add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13627) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13628) or.w %d2,%d1 # concat new sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13629) mov.w %d1,FP_SCR1_EX(%a6) # insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13630) fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13631) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13632) bra.b fabs_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13634) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13635) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13636) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13637) fabs_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13638) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13639) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13641) fabs.x FP_SCR0(%a6),%fp0 # perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13643) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13644) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13646) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13648) fabs_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13649) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13651) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13652) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13653) bne.b fabs_sd_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13655) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13656) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13657) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13658) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13659) fabs_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13660) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13661) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13662) mov.l L_SCR3(%a6),%d0 # pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13663) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13664) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13665) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13666) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13668) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13669) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13670) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13671) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13672) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13673) fabs_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13674) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13675) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13676) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13677) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13678) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13679) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13680) subi.l &0x6000,%d1 # subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13681) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13682) or.w %d2,%d1 # concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13683) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13684) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13685) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13686) bra.b fabs_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13688) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13689) # the move in MAY underflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13690) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13691) fabs_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13692) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13693) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13695) fabs.x FP_SCR0(%a6),%fp0 # perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13697) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13698) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13700) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13702) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13703) fcmp.b %fp1,&0x2 # is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13704) fbge.w fabs_sd_ovfl_tst # yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13706) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13707) bra.w fabs_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13709) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13711) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13712) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13713) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13714) fabs_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13715) cmpi.b %d1,&DENORM # weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13716) beq.w fabs_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13717) cmpi.b %d1,&SNAN # weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13718) beq.l res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13719) cmpi.b %d1,&QNAN # weed out QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13720) beq.l res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13722) fabs.x SRC(%a0),%fp0 # force absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13724) cmpi.b %d1,&INF # weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13725) beq.b fabs_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13726) fabs_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13727) mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13728) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13729) fabs_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13730) mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13731) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13733) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13734) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13735) # fcmp(): fp compare op routine #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13736) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13737) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13738) # res_qnan() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13739) # res_snan() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13740) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13741) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13742) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13743) # a1 = pointer to extended precision destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13744) # d0 = round prec/mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13745) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13746) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13747) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13748) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13749) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13750) # Handle NANs and denorms as special cases. For everything else, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13751) # just use the actual fcmp instruction to produce the correct condition #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13752) # codes. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13753) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13754) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13756) global fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13757) fcmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13758) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13759) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13760) lsl.b &0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13761) or.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13762) bne.b fcmp_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13764) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13765) # COMPARE FP OPs : NORMs, ZEROs, INFs, and "corrected" DENORMs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13766) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13767) fcmp_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13768) fmovm.x DST(%a1),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13770) fcmp.x %fp0,SRC(%a0) # do compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13772) fmov.l %fpsr,%d0 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13773) rol.l &0x8,%d0 # extract ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13774) mov.b %d0,FPSR_CC(%a6) # set ccode bits(no exc bits are set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13776) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13778) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13779) # fcmp: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13780) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13781) fcmp_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13782) mov.w (tbl_fcmp_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13783) jmp (tbl_fcmp_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13785) swbeg &48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13786) tbl_fcmp_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13787) short fcmp_norm - tbl_fcmp_op # NORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13788) short fcmp_norm - tbl_fcmp_op # NORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13789) short fcmp_norm - tbl_fcmp_op # NORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13790) short fcmp_res_qnan - tbl_fcmp_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13791) short fcmp_nrm_dnrm - tbl_fcmp_op # NORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13792) short fcmp_res_snan - tbl_fcmp_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13793) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13794) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13796) short fcmp_norm - tbl_fcmp_op # ZERO - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13797) short fcmp_norm - tbl_fcmp_op # ZERO - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13798) short fcmp_norm - tbl_fcmp_op # ZERO - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13799) short fcmp_res_qnan - tbl_fcmp_op # ZERO - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13800) short fcmp_dnrm_s - tbl_fcmp_op # ZERO - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13801) short fcmp_res_snan - tbl_fcmp_op # ZERO - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13802) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13803) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13805) short fcmp_norm - tbl_fcmp_op # INF - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13806) short fcmp_norm - tbl_fcmp_op # INF - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13807) short fcmp_norm - tbl_fcmp_op # INF - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13808) short fcmp_res_qnan - tbl_fcmp_op # INF - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13809) short fcmp_dnrm_s - tbl_fcmp_op # INF - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13810) short fcmp_res_snan - tbl_fcmp_op # INF - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13811) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13812) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13814) short fcmp_res_qnan - tbl_fcmp_op # QNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13815) short fcmp_res_qnan - tbl_fcmp_op # QNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13816) short fcmp_res_qnan - tbl_fcmp_op # QNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13817) short fcmp_res_qnan - tbl_fcmp_op # QNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13818) short fcmp_res_qnan - tbl_fcmp_op # QNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13819) short fcmp_res_snan - tbl_fcmp_op # QNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13820) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13821) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13823) short fcmp_dnrm_nrm - tbl_fcmp_op # DENORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13824) short fcmp_dnrm_d - tbl_fcmp_op # DENORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13825) short fcmp_dnrm_d - tbl_fcmp_op # DENORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13826) short fcmp_res_qnan - tbl_fcmp_op # DENORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13827) short fcmp_dnrm_sd - tbl_fcmp_op # DENORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13828) short fcmp_res_snan - tbl_fcmp_op # DENORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13829) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13830) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13832) short fcmp_res_snan - tbl_fcmp_op # SNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13833) short fcmp_res_snan - tbl_fcmp_op # SNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13834) short fcmp_res_snan - tbl_fcmp_op # SNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13835) short fcmp_res_snan - tbl_fcmp_op # SNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13836) short fcmp_res_snan - tbl_fcmp_op # SNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13837) short fcmp_res_snan - tbl_fcmp_op # SNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13838) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13839) short tbl_fcmp_op - tbl_fcmp_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13841) # unlike all other functions for QNAN and SNAN, fcmp does NOT set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13842) # 'N' bit for a negative QNAN or SNAN input so we must squelch it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13843) fcmp_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13844) bsr.l res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13845) andi.b &0xf7,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13846) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13847) fcmp_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13848) bsr.l res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13849) andi.b &0xf7,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13850) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13852) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13853) # DENORMs are a little more difficult.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13854) # 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 13855) # and use the fcmp_norm routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13856) # 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 13857) # and use the fcmp_norm routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13858) # 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 13859) # 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 13860) # (1) signs are (+) and the DENORM is the dst or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13861) # (2) signs are (-) and the DENORM is the src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13862) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13864) fcmp_dnrm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13865) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13866) mov.l SRC_HI(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13867) bset &31,%d0 # DENORM src; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13868) mov.l %d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13869) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13870) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13871) bra.w fcmp_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13873) fcmp_dnrm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13874) mov.l DST_EX(%a1),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13875) mov.l DST_HI(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13876) bset &31,%d0 # DENORM src; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13877) mov.l %d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13878) mov.l DST_LO(%a1),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13879) lea FP_SCR0(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13880) bra.w fcmp_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13882) fcmp_dnrm_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13883) mov.w DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13884) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13885) mov.l DST_HI(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13886) bset &31,%d0 # DENORM dst; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13887) mov.l %d0,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13888) mov.l SRC_HI(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13889) bset &31,%d0 # DENORM dst; make into small norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13890) mov.l %d0,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13891) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13892) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13893) lea FP_SCR1(%a6),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13894) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13895) bra.w fcmp_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13897) fcmp_nrm_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13898) mov.b SRC_EX(%a0),%d0 # determine if like signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13899) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13900) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13901) bmi.w fcmp_dnrm_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13903) # signs are the same, so must determine the answer ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13904) tst.b %d0 # is src op negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13905) bmi.b fcmp_nrm_dnrm_m # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13906) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13907) fcmp_nrm_dnrm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13908) mov.b &neg_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13909) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13911) fcmp_dnrm_nrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13912) mov.b SRC_EX(%a0),%d0 # determine if like signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13913) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13914) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13915) bmi.w fcmp_dnrm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13917) # signs are the same, so must determine the answer ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13918) tst.b %d0 # is src op negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13919) bpl.b fcmp_dnrm_nrm_m # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13920) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13921) fcmp_dnrm_nrm_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13922) mov.b &neg_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13923) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13925) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13926) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13927) # fsglmul(): emulates the fsglmul instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13928) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13929) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13930) # scale_to_zero_src() - scale src exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13931) # scale_to_zero_dst() - scale dst exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13932) # unf_res4() - return default underflow result for sglop #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13933) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13934) # res_qnan() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13935) # res_snan() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13936) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13937) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13938) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13939) # a1 = pointer to extended precision destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13940) # d0 rnd prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13941) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13942) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13943) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13944) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13945) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13946) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13947) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13948) # norms/denorms into ext/sgl/dbl precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13949) # For norms/denorms, scale the exponents such that a multiply #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13950) # instruction won't cause an exception. Use the regular fsglmul to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13951) # compute a result. Check if the regular operands would have taken #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13952) # an exception. If so, return the default overflow/underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13953) # and return the EXOP if exceptions are enabled. Else, scale the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13954) # result operand to the proper exponent. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13955) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13956) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13958) global fsglmul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13959) fsglmul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13960) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13962) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13963) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13964) lsl.b &0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13965) or.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13967) bne.w fsglmul_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13969) fsglmul_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13970) mov.w DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13971) mov.l DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13972) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13974) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13975) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13976) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13978) bsr.l scale_to_zero_src # scale exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13979) mov.l %d0,-(%sp) # save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13981) bsr.l scale_to_zero_dst # scale dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13983) add.l (%sp)+,%d0 # SCALE_FACTOR = scale1 + scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13985) cmpi.l %d0,&0x3fff-0x7ffe # would result ovfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13986) beq.w fsglmul_may_ovfl # result may rnd to overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13987) blt.w fsglmul_ovfl # result will overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13989) cmpi.l %d0,&0x3fff+0x0001 # would result unfl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13990) beq.w fsglmul_may_unfl # result may rnd to no unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13991) bgt.w fsglmul_unfl # result will underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13993) fsglmul_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13994) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13996) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13997) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13999) fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14001) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14002) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14004) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14006) fsglmul_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14007) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14008) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14009) mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14010) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14011) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14012) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14013) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14014) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14015) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14016) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14017) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14018) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14020) fsglmul_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14021) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14023) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14024) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14026) fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14028) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14029) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14031) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14033) fsglmul_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14035) # save setting this until now because this is where fsglmul_may_ovfl may jump in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14036) or.l &ovfl_inx_mask, USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14038) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14039) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14040) bne.b fsglmul_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14042) fsglmul_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14043) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14044) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14045) mov.l L_SCR3(%a6),%d0 # pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14046) andi.b &0x30,%d0 # force prec = ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14047) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14048) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14049) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14050) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14052) fsglmul_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14053) fmovm.x &0x80,FP_SCR0(%a6) # move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14055) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14056) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14057) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14058) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14059) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14060) subi.l &0x6000,%d1 # subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14061) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14062) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14063) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14064) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14065) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14066) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14067) bra.b fsglmul_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14069) fsglmul_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14070) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14072) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14073) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14075) fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14077) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14078) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14080) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14082) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14083) fcmp.b %fp1,&0x2 # is |result| >= 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14084) fbge.w fsglmul_ovfl_tst # yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14086) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14087) bra.w fsglmul_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14089) fsglmul_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14090) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14092) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14094) fmov.l &rz_mode*0x10,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14095) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14097) fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14099) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14100) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14102) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14104) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14105) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14106) bne.b fsglmul_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14108) fsglmul_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14109) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14111) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14112) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14113) bsr.l unf_res4 # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14114) or.b %d0,FPSR_CC(%a6) # 'Z' bit may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14115) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14116) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14118) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14119) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14120) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14121) fsglmul_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14122) fmovm.x FP_SCR1(%a6),&0x40 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14124) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14125) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14127) fsglmul.x FP_SCR0(%a6),%fp1 # execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14129) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14131) fmovm.x &0x40,FP_SCR0(%a6) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14132) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14133) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14134) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14135) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14136) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14137) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14138) addi.l &0x6000,%d1 # add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14139) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14140) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14141) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14142) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14143) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14144) bra.w fsglmul_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14146) fsglmul_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14147) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14149) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14150) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14152) fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14154) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14155) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14157) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14159) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14160) fcmp.b %fp1,&0x2 # is |result| > 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14161) fbgt.w fsglmul_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14162) fblt.w fsglmul_unfl # yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14164) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14165) # we still don't know if underflow occurred. result is ~ equal to 2. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14166) # 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 14167) # a normalized number that rounded down to a 2. so, redo the entire operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14168) # using RZ as the rounding mode to see what the pre-rounded result is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14169) # this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14170) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14171) fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14173) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14174) andi.b &0xc0,%d1 # keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14175) ori.b &rz_mode*0x10,%d1 # insert RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14177) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14178) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14180) fsglmul.x FP_SCR0(%a6),%fp1 # execute sgl multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14182) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14183) fabs.x %fp1 # make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14184) fcmp.b %fp1,&0x2 # is |result| < 2.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14185) fbge.w fsglmul_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14186) bra.w fsglmul_unfl # yes, underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14188) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14190) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14191) # Single Precision Multiply: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14192) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14193) fsglmul_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14194) mov.w (tbl_fsglmul_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14195) jmp (tbl_fsglmul_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14197) swbeg &48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14198) tbl_fsglmul_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14199) short fsglmul_norm - tbl_fsglmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14200) short fsglmul_zero - tbl_fsglmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14201) short fsglmul_inf_src - tbl_fsglmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14202) short fsglmul_res_qnan - tbl_fsglmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14203) short fsglmul_norm - tbl_fsglmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14204) short fsglmul_res_snan - tbl_fsglmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14205) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14206) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14208) short fsglmul_zero - tbl_fsglmul_op # ZERO x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14209) short fsglmul_zero - tbl_fsglmul_op # ZERO x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14210) short fsglmul_res_operr - tbl_fsglmul_op # ZERO x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14211) short fsglmul_res_qnan - tbl_fsglmul_op # ZERO x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14212) short fsglmul_zero - tbl_fsglmul_op # ZERO x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14213) short fsglmul_res_snan - tbl_fsglmul_op # ZERO x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14214) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14215) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14217) short fsglmul_inf_dst - tbl_fsglmul_op # INF x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14218) short fsglmul_res_operr - tbl_fsglmul_op # INF x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14219) short fsglmul_inf_dst - tbl_fsglmul_op # INF x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14220) short fsglmul_res_qnan - tbl_fsglmul_op # INF x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14221) short fsglmul_inf_dst - tbl_fsglmul_op # INF x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14222) short fsglmul_res_snan - tbl_fsglmul_op # INF x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14223) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14224) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14226) short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14227) short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14228) short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14229) short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14230) short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14231) short fsglmul_res_snan - tbl_fsglmul_op # QNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14232) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14233) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14235) short fsglmul_norm - tbl_fsglmul_op # NORM x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14236) short fsglmul_zero - tbl_fsglmul_op # NORM x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14237) short fsglmul_inf_src - tbl_fsglmul_op # NORM x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14238) short fsglmul_res_qnan - tbl_fsglmul_op # NORM x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14239) short fsglmul_norm - tbl_fsglmul_op # NORM x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14240) short fsglmul_res_snan - tbl_fsglmul_op # NORM x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14241) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14242) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14244) short fsglmul_res_snan - tbl_fsglmul_op # SNAN x NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14245) short fsglmul_res_snan - tbl_fsglmul_op # SNAN x ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14246) short fsglmul_res_snan - tbl_fsglmul_op # SNAN x INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14247) short fsglmul_res_snan - tbl_fsglmul_op # SNAN x QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14248) short fsglmul_res_snan - tbl_fsglmul_op # SNAN x DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14249) short fsglmul_res_snan - tbl_fsglmul_op # SNAN x SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14250) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14251) short tbl_fsglmul_op - tbl_fsglmul_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14253) fsglmul_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14254) bra.l res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14255) fsglmul_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14256) bra.l res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14257) fsglmul_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14258) bra.l res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14259) fsglmul_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14260) bra.l fmul_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14261) fsglmul_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14262) bra.l fmul_inf_src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14263) fsglmul_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14264) bra.l fmul_inf_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14266) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14267) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14268) # fsgldiv(): emulates the fsgldiv instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14269) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14270) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14271) # scale_to_zero_src() - scale src exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14272) # scale_to_zero_dst() - scale dst exponent to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14273) # unf_res4() - return default underflow result for sglop #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14274) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14275) # res_qnan() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14276) # res_snan() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14277) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14278) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14279) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14280) # a1 = pointer to extended precision destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14281) # d0 rnd prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14282) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14283) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14284) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14285) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14286) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14287) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14288) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14289) # norms/denorms into ext/sgl/dbl precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14290) # For norms/denorms, scale the exponents such that a divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14291) # instruction won't cause an exception. Use the regular fsgldiv to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14292) # compute a result. Check if the regular operands would have taken #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14293) # an exception. If so, return the default overflow/underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14294) # and return the EXOP if exceptions are enabled. Else, scale the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14295) # result operand to the proper exponent. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14296) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14297) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14299) global fsgldiv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14300) fsgldiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14301) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14303) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14304) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14305) lsl.b &0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14306) or.b STAG(%a6),%d1 # combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14308) bne.w fsgldiv_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14310) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14311) # DIVIDE: NORMs and DENORMs ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14312) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14313) fsgldiv_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14314) mov.w DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14315) mov.l DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14316) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14318) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14319) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14320) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14322) bsr.l scale_to_zero_src # calculate scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14323) mov.l %d0,-(%sp) # save scale factor 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14325) bsr.l scale_to_zero_dst # calculate scale factor 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14327) neg.l (%sp) # S.F. = scale1 - scale2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14328) add.l %d0,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14330) mov.w 2+L_SCR3(%a6),%d1 # fetch precision,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14331) lsr.b &0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14332) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14333) cmpi.l %d0,&0x3fff-0x7ffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14334) ble.w fsgldiv_may_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14336) cmpi.l %d0,&0x3fff-0x0000 # will result underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14337) beq.w fsgldiv_may_unfl # maybe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14338) bgt.w fsgldiv_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14340) fsgldiv_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14341) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14343) fmov.l L_SCR3(%a6),%fpcr # save FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14344) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14346) fsgldiv.x FP_SCR0(%a6),%fp0 # perform sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14348) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14349) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14351) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14353) fsgldiv_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14354) fmovm.x &0x80,FP_SCR0(%a6) # store result on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14355) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14356) mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14357) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14358) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14359) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14360) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14361) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14362) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14363) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14364) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14365) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14367) fsgldiv_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14368) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14370) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14371) fmov.l &0x0,%fpsr # set FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14373) fsgldiv.x FP_SCR0(%a6),%fp0 # execute divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14375) fmov.l %fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14376) fmov.l &0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14378) or.l %d1,USER_FPSR(%a6) # save INEX,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14380) fmovm.x &0x01,-(%sp) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14381) mov.w (%sp),%d1 # fetch new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14382) add.l &0xc,%sp # clear result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14383) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14384) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14385) cmp.l %d1,&0x7fff # did divide overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14386) blt.b fsgldiv_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14388) fsgldiv_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14389) or.w &ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14391) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14392) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14393) bne.b fsgldiv_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14395) fsgldiv_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14396) btst &neg_bit,FPSR_CC(%a6) # is result negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14397) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14398) mov.l L_SCR3(%a6),%d0 # pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14399) andi.b &0x30,%d0 # kill precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14400) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14401) or.b %d0,FPSR_CC(%a6) # set INF if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14402) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14403) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14405) fsgldiv_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14406) fmovm.x &0x80,FP_SCR0(%a6) # move result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14408) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14409) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14410) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14411) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14412) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14413) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14414) subi.l &0x6000,%d1 # subtract new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14415) andi.w &0x7fff,%d1 # clear ms bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14416) or.w %d2,%d1 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14417) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14418) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14419) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14420) bra.b fsgldiv_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14422) fsgldiv_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14423) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14425) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14427) fmov.l &rz_mode*0x10,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14428) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14430) fsgldiv.x FP_SCR0(%a6),%fp0 # execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14432) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14433) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14435) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14437) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14438) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14439) bne.b fsgldiv_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14441) fsgldiv_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14442) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14444) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14445) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14446) bsr.l unf_res4 # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14447) or.b %d0,FPSR_CC(%a6) # 'Z' bit may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14448) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14449) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14451) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14452) # UNFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14453) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14454) fsgldiv_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14455) fmovm.x FP_SCR1(%a6),&0x40 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14457) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14458) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14460) fsgldiv.x FP_SCR0(%a6),%fp1 # execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14462) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14464) fmovm.x &0x40,FP_SCR0(%a6) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14465) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14466) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14467) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14468) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14469) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14470) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14471) addi.l &0x6000,%d1 # add bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14472) andi.w &0x7fff,%d1 # clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14473) or.w %d2,%d1 # concat old sign, new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14474) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14475) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14476) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14477) bra.b fsgldiv_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14479) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14480) # the divide operation MAY underflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14481) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14482) fsgldiv_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14483) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14485) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14486) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14488) fsgldiv.x FP_SCR0(%a6),%fp0 # execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14490) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14491) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14493) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14495) fabs.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14496) fcmp.b %fp1,&0x1 # is |result| > 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14497) fbgt.w fsgldiv_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14498) fblt.w fsgldiv_unfl # yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14500) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14501) # we still don't know if underflow occurred. result is ~ equal to 1. but,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14502) # 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 14503) # or a normalized number that rounded down to a 1. so, redo the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14504) # operation using RZ as the rounding mode to see what the pre-rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14505) # result is. this case should be relatively rare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14506) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14507) fmovm.x FP_SCR1(%a6),&0x40 # load dst op into %fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14509) clr.l %d1 # clear scratch register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14510) ori.b &rz_mode*0x10,%d1 # force RZ rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14512) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14513) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14515) fsgldiv.x FP_SCR0(%a6),%fp1 # execute sgl divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14517) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14518) fabs.x %fp1 # make absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14519) fcmp.b %fp1,&0x1 # is |result| < 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14520) fbge.w fsgldiv_normal_exit # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14521) bra.w fsgldiv_unfl # yes; underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14523) ############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14525) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14526) # Divide: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14527) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14528) fsgldiv_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14529) mov.w (tbl_fsgldiv_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14530) jmp (tbl_fsgldiv_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14532) swbeg &48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14533) tbl_fsgldiv_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14534) short fsgldiv_norm - tbl_fsgldiv_op # NORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14535) short fsgldiv_inf_load - tbl_fsgldiv_op # NORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14536) short fsgldiv_zero_load - tbl_fsgldiv_op # NORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14537) short fsgldiv_res_qnan - tbl_fsgldiv_op # NORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14538) short fsgldiv_norm - tbl_fsgldiv_op # NORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14539) short fsgldiv_res_snan - tbl_fsgldiv_op # NORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14540) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14541) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14543) short fsgldiv_zero_load - tbl_fsgldiv_op # ZERO / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14544) short fsgldiv_res_operr - tbl_fsgldiv_op # ZERO / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14545) short fsgldiv_zero_load - tbl_fsgldiv_op # ZERO / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14546) short fsgldiv_res_qnan - tbl_fsgldiv_op # ZERO / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14547) short fsgldiv_zero_load - tbl_fsgldiv_op # ZERO / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14548) short fsgldiv_res_snan - tbl_fsgldiv_op # ZERO / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14549) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14550) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14552) short fsgldiv_inf_dst - tbl_fsgldiv_op # INF / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14553) short fsgldiv_inf_dst - tbl_fsgldiv_op # INF / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14554) short fsgldiv_res_operr - tbl_fsgldiv_op # INF / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14555) short fsgldiv_res_qnan - tbl_fsgldiv_op # INF / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14556) short fsgldiv_inf_dst - tbl_fsgldiv_op # INF / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14557) short fsgldiv_res_snan - tbl_fsgldiv_op # INF / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14558) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14559) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14561) short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14562) short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14563) short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14564) short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14565) short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14566) short fsgldiv_res_snan - tbl_fsgldiv_op # QNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14567) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14568) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14570) short fsgldiv_norm - tbl_fsgldiv_op # DENORM / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14571) short fsgldiv_inf_load - tbl_fsgldiv_op # DENORM / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14572) short fsgldiv_zero_load - tbl_fsgldiv_op # DENORM / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14573) short fsgldiv_res_qnan - tbl_fsgldiv_op # DENORM / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14574) short fsgldiv_norm - tbl_fsgldiv_op # DENORM / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14575) short fsgldiv_res_snan - tbl_fsgldiv_op # DENORM / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14576) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14577) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14579) short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14580) short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14581) short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14582) short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14583) short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14584) short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14585) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14586) short tbl_fsgldiv_op - tbl_fsgldiv_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14588) fsgldiv_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14589) bra.l res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14590) fsgldiv_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14591) bra.l res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14592) fsgldiv_res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14593) bra.l res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14594) fsgldiv_inf_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14595) bra.l fdiv_inf_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14596) fsgldiv_zero_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14597) bra.l fdiv_zero_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14598) fsgldiv_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14599) bra.l fdiv_inf_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14601) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14602) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14603) # fadd(): emulates the fadd instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14604) # fsadd(): emulates the fadd instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14605) # fdadd(): emulates the fdadd instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14606) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14607) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14608) # addsub_scaler2() - scale the operands so they won't take exc #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14609) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14610) # unf_res() - return default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14611) # res_qnan() - set QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14612) # res_snan() - set SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14613) # res_operr() - set OPERR result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14614) # scale_to_zero_src() - set src operand exponent equal to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14615) # scale_to_zero_dst() - set dst operand exponent equal to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14616) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14617) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14618) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14619) # a1 = pointer to extended precision destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14620) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14621) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14622) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14623) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14624) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14625) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14626) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14627) # norms into extended, single, and double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14628) # Do addition after scaling exponents such that exception won't #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14629) # occur. Then, check result exponent to see if exception would have #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14630) # occurred. If so, return default result and maybe EXOP. Else, insert #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14631) # the correct result exponent and return. Set FPSR bits as appropriate. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14632) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14633) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14635) global fsadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14636) fsadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14637) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14638) ori.b &s_mode*0x10,%d0 # insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14639) bra.b fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14641) global fdadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14642) fdadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14643) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14644) ori.b &d_mode*0x10,%d0 # insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14646) global fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14647) fadd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14648) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14650) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14651) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14652) lsl.b &0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14653) or.b STAG(%a6),%d1 # combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14655) bne.w fadd_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14657) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14658) # ADD: norms and denorms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14659) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14660) fadd_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14661) bsr.l addsub_scaler2 # scale exponents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14663) fadd_zero_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14664) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14666) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14667) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14669) fadd.x FP_SCR0(%a6),%fp0 # execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14671) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14672) fmov.l %fpsr,%d1 # fetch INEX2,N,Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14674) or.l %d1,USER_FPSR(%a6) # save exc and ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14676) fbeq.w fadd_zero_exit # if result is zero, end now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14678) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14680) fmovm.x &0x01,-(%sp) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14682) mov.w 2+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14683) lsr.b &0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14685) mov.w (%sp),%d2 # fetch new sign, exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14686) andi.l &0x7fff,%d2 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14687) sub.l %d0,%d2 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14689) cmp.l %d2,(tbl_fadd_ovfl.b,%pc,%d1.w*4) # is it an overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14690) bge.b fadd_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14692) cmp.l %d2,(tbl_fadd_unfl.b,%pc,%d1.w*4) # is it an underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14693) blt.w fadd_unfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14694) beq.w fadd_may_unfl # maybe; go find out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14696) fadd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14697) mov.w (%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14698) andi.w &0x8000,%d1 # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14699) or.w %d2,%d1 # concat sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14700) mov.w %d1,(%sp) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14702) fmovm.x (%sp)+,&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14704) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14705) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14707) fadd_zero_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14708) # fmov.s &0x00000000,%fp0 # return zero in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14709) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14711) tbl_fadd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14712) long 0x7fff # ext ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14713) long 0x407f # sgl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14714) long 0x43ff # dbl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14716) tbl_fadd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14717) long 0x0000 # ext unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14718) long 0x3f81 # sgl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14719) long 0x3c01 # dbl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14721) fadd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14722) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14724) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14725) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14726) bne.b fadd_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14728) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14729) fadd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14730) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14731) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14732) mov.l L_SCR3(%a6),%d0 # pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14733) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14734) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14735) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14736) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14737) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14739) fadd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14740) mov.b L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14741) andi.b &0xc0,%d1 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14742) bne.b fadd_ovfl_ena_sd # no; prec = sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14744) fadd_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14745) mov.w (%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14746) andi.w &0x8000,%d1 # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14747) subi.l &0x6000,%d2 # add extra bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14748) andi.w &0x7fff,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14749) or.w %d2,%d1 # concat sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14750) mov.w %d1,(%sp) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14752) fmovm.x (%sp)+,&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14753) bra.b fadd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14755) fadd_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14756) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14758) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14759) andi.b &0x30,%d1 # keep rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14760) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14762) fadd.x FP_SCR0(%a6),%fp0 # execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14764) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14766) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14767) fmovm.x &0x01,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14768) bra.b fadd_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14770) fadd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14771) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14773) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14775) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14777) fmov.l &rz_mode*0x10,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14778) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14780) fadd.x FP_SCR0(%a6),%fp0 # execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14782) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14783) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14785) or.l %d1,USER_FPSR(%a6) # save INEX,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14787) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14788) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14789) bne.b fadd_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14791) fadd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14792) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14794) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14795) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14796) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14797) or.b %d0,FPSR_CC(%a6) # 'Z' bit may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14798) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14799) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14800) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14802) fadd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14803) fmovm.x FP_SCR1(%a6),&0x40 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14805) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14806) andi.b &0xc0,%d1 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14807) bne.b fadd_unfl_ena_sd # no; sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14809) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14811) fadd_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14812) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14814) fadd.x FP_SCR0(%a6),%fp1 # execute multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14816) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14818) fmovm.x &0x40,FP_SCR0(%a6) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14819) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14820) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14821) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14822) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14823) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14824) addi.l &0x6000,%d1 # add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14825) andi.w &0x7fff,%d1 # clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14826) or.w %d2,%d1 # concat sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14827) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14828) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14829) bra.w fadd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14831) fadd_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14832) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14833) andi.b &0x30,%d1 # use only rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14834) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14836) bra.b fadd_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14838) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14839) # result is equal to the smallest normalized number in the selected precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14840) # if the precision is extended, this result could not have come from an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14841) # underflow that rounded up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14842) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14843) fadd_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14844) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14845) andi.b &0xc0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14846) beq.w fadd_normal # yes; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14848) mov.l 0x4(%sp),%d1 # extract hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14849) cmpi.l %d1,&0x80000000 # is hi(man) = 0x80000000?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14850) bne.w fadd_normal # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14852) tst.l 0x8(%sp) # is lo(man) = 0x0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14853) bne.w fadd_normal # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14855) btst &inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14856) beq.w fadd_normal # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14858) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14859) # ok, so now the result has a exponent equal to the smallest normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14860) # exponent for the selected precision. also, the mantissa is equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14861) # 0x8000000000000000 and this mantissa is the result of rounding non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14862) # g,r,s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14863) # now, we must determine whether the pre-rounded result was an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14864) # rounded "up" or a normalized number rounded "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14865) # 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 14866) # seeing if the new result is smaller or equal to the current result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14867) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14868) fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14870) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14871) andi.b &0xc0,%d1 # keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14872) ori.b &rz_mode*0x10,%d1 # insert rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14873) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14874) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14876) fadd.x FP_SCR0(%a6),%fp1 # execute add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14878) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14880) fabs.x %fp0 # compare absolute values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14881) fabs.x %fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14882) fcmp.x %fp0,%fp1 # is first result > second?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14884) fbgt.w fadd_unfl # yes; it's an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14885) bra.w fadd_normal # no; it's not an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14887) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14889) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14890) # Add: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14891) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14892) fadd_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14893) mov.w (tbl_fadd_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14894) jmp (tbl_fadd_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14896) swbeg &48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14897) tbl_fadd_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14898) short fadd_norm - tbl_fadd_op # NORM + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14899) short fadd_zero_src - tbl_fadd_op # NORM + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14900) short fadd_inf_src - tbl_fadd_op # NORM + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14901) short fadd_res_qnan - tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14902) short fadd_norm - tbl_fadd_op # NORM + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14903) short fadd_res_snan - tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14904) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14905) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14907) short fadd_zero_dst - tbl_fadd_op # ZERO + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14908) short fadd_zero_2 - tbl_fadd_op # ZERO + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14909) short fadd_inf_src - tbl_fadd_op # ZERO + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14910) short fadd_res_qnan - tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14911) short fadd_zero_dst - tbl_fadd_op # ZERO + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14912) short fadd_res_snan - tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14913) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14914) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14916) short fadd_inf_dst - tbl_fadd_op # INF + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14917) short fadd_inf_dst - tbl_fadd_op # INF + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14918) short fadd_inf_2 - tbl_fadd_op # INF + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14919) short fadd_res_qnan - tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14920) short fadd_inf_dst - tbl_fadd_op # INF + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14921) short fadd_res_snan - tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14922) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14923) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14925) short fadd_res_qnan - tbl_fadd_op # QNAN + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14926) short fadd_res_qnan - tbl_fadd_op # QNAN + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14927) short fadd_res_qnan - tbl_fadd_op # QNAN + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14928) short fadd_res_qnan - tbl_fadd_op # QNAN + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14929) short fadd_res_qnan - tbl_fadd_op # QNAN + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14930) short fadd_res_snan - tbl_fadd_op # QNAN + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14931) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14932) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14934) short fadd_norm - tbl_fadd_op # DENORM + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14935) short fadd_zero_src - tbl_fadd_op # DENORM + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14936) short fadd_inf_src - tbl_fadd_op # DENORM + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14937) short fadd_res_qnan - tbl_fadd_op # NORM + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14938) short fadd_norm - tbl_fadd_op # DENORM + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14939) short fadd_res_snan - tbl_fadd_op # NORM + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14940) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14941) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14943) short fadd_res_snan - tbl_fadd_op # SNAN + NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14944) short fadd_res_snan - tbl_fadd_op # SNAN + ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14945) short fadd_res_snan - tbl_fadd_op # SNAN + INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14946) short fadd_res_snan - tbl_fadd_op # SNAN + QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14947) short fadd_res_snan - tbl_fadd_op # SNAN + DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14948) short fadd_res_snan - tbl_fadd_op # SNAN + SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14949) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14950) short tbl_fadd_op - tbl_fadd_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14952) fadd_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14953) bra.l res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14954) fadd_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14955) bra.l res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14957) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14958) # both operands are ZEROes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14959) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14960) fadd_zero_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14961) mov.b SRC_EX(%a0),%d0 # are the signs opposite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14962) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14963) eor.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14964) bmi.w fadd_zero_2_chk_rm # weed out (-ZERO)+(+ZERO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14966) # the signs are the same. so determine whether they are positive or negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14967) # and return the appropriately signed zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14968) tst.b %d0 # are ZEROes positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14969) bmi.b fadd_zero_rm # negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14970) fmov.s &0x00000000,%fp0 # return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14971) mov.b &z_bmask,FPSR_CC(%a6) # set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14972) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14974) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14975) # the ZEROes have opposite signs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14976) # - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14977) # - -ZERO is returned in the case of RM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14978) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14979) fadd_zero_2_chk_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14980) mov.b 3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14981) andi.b &0x30,%d1 # extract rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14982) cmpi.b %d1,&rm_mode*0x10 # is rnd mode == RM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14983) beq.b fadd_zero_rm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14984) fmov.s &0x00000000,%fp0 # return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14985) mov.b &z_bmask,FPSR_CC(%a6) # set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14986) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14988) fadd_zero_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14989) fmov.s &0x80000000,%fp0 # return -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14990) mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set NEG/Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14991) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14993) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14994) # one operand is a ZERO and the other is a DENORM or NORM. scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14995) # the DENORM or NORM and jump to the regular fadd routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14996) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14997) fadd_zero_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14998) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14999) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15000) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15001) bsr.l scale_to_zero_src # scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15002) clr.w FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15003) clr.l FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15004) clr.l FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15005) bra.w fadd_zero_entry # go execute fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15007) fadd_zero_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15008) mov.w DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15009) mov.l DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15010) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15011) bsr.l scale_to_zero_dst # scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15012) clr.w FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15013) clr.l FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15014) clr.l FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15015) bra.w fadd_zero_entry # go execute fadd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15017) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15018) # both operands are INFs. an OPERR will result if the INFs have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15019) # different signs. else, an INF of the same sign is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15020) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15021) fadd_inf_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15022) mov.b SRC_EX(%a0),%d0 # exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15023) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15024) eor.b %d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15025) bmi.l res_operr # weed out (-INF)+(+INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15027) # 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 15028) # src INF since that's where the 881/882 gets the j-bit from...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15030) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15031) # operands are INF and one of {ZERO, INF, DENORM, NORM}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15032) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15033) fadd_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15034) fmovm.x SRC(%a0),&0x80 # return src INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15035) tst.b SRC_EX(%a0) # is INF positive?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15036) bpl.b fadd_inf_done # yes; we're done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15037) mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15038) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15040) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15041) # operands are INF and one of {ZERO, INF, DENORM, NORM}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15042) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15043) fadd_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15044) fmovm.x DST(%a1),&0x80 # return dst INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15045) tst.b DST_EX(%a1) # is INF positive?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15046) bpl.b fadd_inf_done # yes; we're done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15047) mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15048) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15050) fadd_inf_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15051) mov.b &inf_bmask,FPSR_CC(%a6) # set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15052) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15054) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15055) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15056) # fsub(): emulates the fsub instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15057) # fssub(): emulates the fssub instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15058) # fdsub(): emulates the fdsub instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15059) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15060) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15061) # addsub_scaler2() - scale the operands so they won't take exc #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15062) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15063) # unf_res() - return default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15064) # res_qnan() - set QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15065) # res_snan() - set SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15066) # res_operr() - set OPERR result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15067) # scale_to_zero_src() - set src operand exponent equal to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15068) # scale_to_zero_dst() - set dst operand exponent equal to zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15069) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15070) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15071) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15072) # a1 = pointer to extended precision destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15073) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15074) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15075) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15076) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15077) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15078) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15079) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15080) # norms into extended, single, and double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15081) # Do subtraction after scaling exponents such that exception won't#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15082) # occur. Then, check result exponent to see if exception would have #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15083) # occurred. If so, return default result and maybe EXOP. Else, insert #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15084) # the correct result exponent and return. Set FPSR bits as appropriate. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15085) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15086) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15088) global fssub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15089) fssub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15090) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15091) ori.b &s_mode*0x10,%d0 # insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15092) bra.b fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15094) global fdsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15095) fdsub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15096) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15097) ori.b &d_mode*0x10,%d0 # insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15099) global fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15100) fsub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15101) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15103) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15104) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15105) lsl.b &0x3,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15106) or.b STAG(%a6),%d1 # combine src tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15108) bne.w fsub_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15110) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15111) # SUB: norms and denorms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15112) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15113) fsub_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15114) bsr.l addsub_scaler2 # scale exponents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15116) fsub_zero_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15117) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15119) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15120) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15122) fsub.x FP_SCR0(%a6),%fp0 # execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15124) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15125) fmov.l %fpsr,%d1 # fetch INEX2, N, Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15127) or.l %d1,USER_FPSR(%a6) # save exc and ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15129) fbeq.w fsub_zero_exit # if result zero, end now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15131) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15133) fmovm.x &0x01,-(%sp) # save result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15135) mov.w 2+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15136) lsr.b &0x6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15138) mov.w (%sp),%d2 # fetch new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15139) andi.l &0x7fff,%d2 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15140) sub.l %d0,%d2 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15142) cmp.l %d2,(tbl_fsub_ovfl.b,%pc,%d1.w*4) # is it an overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15143) bge.b fsub_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15145) cmp.l %d2,(tbl_fsub_unfl.b,%pc,%d1.w*4) # is it an underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15146) blt.w fsub_unfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15147) beq.w fsub_may_unfl # maybe; go find out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15149) fsub_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15150) mov.w (%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15151) andi.w &0x8000,%d1 # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15152) or.w %d2,%d1 # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15153) mov.w %d1,(%sp) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15155) fmovm.x (%sp)+,&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15157) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15158) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15160) fsub_zero_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15161) # fmov.s &0x00000000,%fp0 # return zero in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15162) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15164) tbl_fsub_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15165) long 0x7fff # ext ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15166) long 0x407f # sgl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15167) long 0x43ff # dbl ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15169) tbl_fsub_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15170) long 0x0000 # ext unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15171) long 0x3f81 # sgl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15172) long 0x3c01 # dbl unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15174) fsub_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15175) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15177) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15178) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15179) bne.b fsub_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15181) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15182) fsub_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15183) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15184) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15185) mov.l L_SCR3(%a6),%d0 # pass prec:rnd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15186) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15187) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15188) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15189) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15190) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15192) fsub_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15193) mov.b L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15194) andi.b &0xc0,%d1 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15195) bne.b fsub_ovfl_ena_sd # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15197) fsub_ovfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15198) mov.w (%sp),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15199) andi.w &0x8000,%d1 # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15200) subi.l &0x6000,%d2 # subtract new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15201) andi.w &0x7fff,%d2 # clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15202) or.w %d2,%d1 # concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15203) mov.w %d1,(%sp) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15205) fmovm.x (%sp)+,&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15206) bra.b fsub_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15208) fsub_ovfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15209) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15211) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15212) andi.b &0x30,%d1 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15213) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15215) fsub.x FP_SCR0(%a6),%fp0 # execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15217) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15219) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15220) fmovm.x &0x01,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15221) bra.b fsub_ovfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15223) fsub_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15224) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15226) add.l &0xc,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15228) fmovm.x FP_SCR1(%a6),&0x80 # load dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15230) fmov.l &rz_mode*0x10,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15231) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15233) fsub.x FP_SCR0(%a6),%fp0 # execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15235) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15236) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15238) or.l %d1,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15240) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15241) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15242) bne.b fsub_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15244) fsub_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15245) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15247) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15248) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15249) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15250) or.b %d0,FPSR_CC(%a6) # 'Z' may have been set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15251) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15252) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15253) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15255) fsub_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15256) fmovm.x FP_SCR1(%a6),&0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15258) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15259) andi.b &0xc0,%d1 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15260) bne.b fsub_unfl_ena_sd # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15262) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15264) fsub_unfl_ena_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15265) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15267) fsub.x FP_SCR0(%a6),%fp1 # execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15269) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15271) fmovm.x &0x40,FP_SCR0(%a6) # store result to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15272) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15273) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15274) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15275) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15276) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15277) addi.l &0x6000,%d1 # subtract new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15278) andi.w &0x7fff,%d1 # clear top bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15279) or.w %d2,%d1 # concat sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15280) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15281) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15282) bra.w fsub_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15284) fsub_unfl_ena_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15285) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15286) andi.b &0x30,%d1 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15287) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15289) bra.b fsub_unfl_ena_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15291) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15292) # result is equal to the smallest normalized number in the selected precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15293) # if the precision is extended, this result could not have come from an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15294) # underflow that rounded up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15295) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15296) fsub_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15297) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15298) andi.b &0xc0,%d1 # fetch rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15299) beq.w fsub_normal # yes; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15301) mov.l 0x4(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15302) cmpi.l %d1,&0x80000000 # is hi(man) = 0x80000000?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15303) bne.w fsub_normal # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15305) tst.l 0x8(%sp) # is lo(man) = 0x0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15306) bne.w fsub_normal # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15308) btst &inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15309) beq.w fsub_normal # no; no underflow occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15311) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15312) # ok, so now the result has a exponent equal to the smallest normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15313) # exponent for the selected precision. also, the mantissa is equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15314) # 0x8000000000000000 and this mantissa is the result of rounding non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15315) # g,r,s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15316) # now, we must determine whether the pre-rounded result was an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15317) # rounded "up" or a normalized number rounded "down".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15318) # 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 15319) # seeing if the new result is smaller or equal to the current result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15320) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15321) fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15323) mov.l L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15324) andi.b &0xc0,%d1 # keep rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15325) ori.b &rz_mode*0x10,%d1 # insert rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15326) fmov.l %d1,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15327) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15329) fsub.x FP_SCR0(%a6),%fp1 # execute subtract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15331) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15333) fabs.x %fp0 # compare absolute values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15334) fabs.x %fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15335) fcmp.x %fp0,%fp1 # is first result > second?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15337) fbgt.w fsub_unfl # yes; it's an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15338) bra.w fsub_normal # no; it's not an underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15340) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15342) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15343) # Sub: inputs are not both normalized; what are they?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15344) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15345) fsub_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15346) mov.w (tbl_fsub_op.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15347) jmp (tbl_fsub_op.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15349) swbeg &48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15350) tbl_fsub_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15351) short fsub_norm - tbl_fsub_op # NORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15352) short fsub_zero_src - tbl_fsub_op # NORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15353) short fsub_inf_src - tbl_fsub_op # NORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15354) short fsub_res_qnan - tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15355) short fsub_norm - tbl_fsub_op # NORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15356) short fsub_res_snan - tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15357) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15358) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15360) short fsub_zero_dst - tbl_fsub_op # ZERO - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15361) short fsub_zero_2 - tbl_fsub_op # ZERO - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15362) short fsub_inf_src - tbl_fsub_op # ZERO - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15363) short fsub_res_qnan - tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15364) short fsub_zero_dst - tbl_fsub_op # ZERO - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15365) short fsub_res_snan - tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15366) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15367) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15369) short fsub_inf_dst - tbl_fsub_op # INF - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15370) short fsub_inf_dst - tbl_fsub_op # INF - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15371) short fsub_inf_2 - tbl_fsub_op # INF - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15372) short fsub_res_qnan - tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15373) short fsub_inf_dst - tbl_fsub_op # INF - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15374) short fsub_res_snan - tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15375) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15376) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15378) short fsub_res_qnan - tbl_fsub_op # QNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15379) short fsub_res_qnan - tbl_fsub_op # QNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15380) short fsub_res_qnan - tbl_fsub_op # QNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15381) short fsub_res_qnan - tbl_fsub_op # QNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15382) short fsub_res_qnan - tbl_fsub_op # QNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15383) short fsub_res_snan - tbl_fsub_op # QNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15384) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15385) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15387) short fsub_norm - tbl_fsub_op # DENORM - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15388) short fsub_zero_src - tbl_fsub_op # DENORM - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15389) short fsub_inf_src - tbl_fsub_op # DENORM - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15390) short fsub_res_qnan - tbl_fsub_op # NORM - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15391) short fsub_norm - tbl_fsub_op # DENORM - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15392) short fsub_res_snan - tbl_fsub_op # NORM - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15393) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15394) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15396) short fsub_res_snan - tbl_fsub_op # SNAN - NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15397) short fsub_res_snan - tbl_fsub_op # SNAN - ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15398) short fsub_res_snan - tbl_fsub_op # SNAN - INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15399) short fsub_res_snan - tbl_fsub_op # SNAN - QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15400) short fsub_res_snan - tbl_fsub_op # SNAN - DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15401) short fsub_res_snan - tbl_fsub_op # SNAN - SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15402) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15403) short tbl_fsub_op - tbl_fsub_op #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15405) fsub_res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15406) bra.l res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15407) fsub_res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15408) bra.l res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15410) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15411) # both operands are ZEROes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15412) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15413) fsub_zero_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15414) mov.b SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15415) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15416) eor.b %d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15417) bpl.b fsub_zero_2_chk_rm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15419) # the signs are opposite, so, return a ZERO w/ the sign of the dst ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15420) tst.b %d0 # is dst negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15421) bmi.b fsub_zero_2_rm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15422) fmov.s &0x00000000,%fp0 # no; return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15423) mov.b &z_bmask,FPSR_CC(%a6) # set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15424) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15426) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15427) # the ZEROes have the same signs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15428) # - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15429) # - -ZERO is returned in the case of RM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15430) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15431) fsub_zero_2_chk_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15432) mov.b 3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15433) andi.b &0x30,%d1 # extract rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15434) cmpi.b %d1,&rm_mode*0x10 # is rnd mode = RM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15435) beq.b fsub_zero_2_rm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15436) fmov.s &0x00000000,%fp0 # no; return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15437) mov.b &z_bmask,FPSR_CC(%a6) # set Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15438) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15440) fsub_zero_2_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15441) fmov.s &0x80000000,%fp0 # return -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15442) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15443) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15445) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15446) # one operand is a ZERO and the other is a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15447) # scale the DENORM or NORM and jump to the regular fsub routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15448) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15449) fsub_zero_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15450) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15451) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15452) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15453) bsr.l scale_to_zero_src # scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15454) clr.w FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15455) clr.l FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15456) clr.l FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15457) bra.w fsub_zero_entry # go execute fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15459) fsub_zero_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15460) mov.w DST_EX(%a1),FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15461) mov.l DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15462) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15463) bsr.l scale_to_zero_dst # scale the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15464) clr.w FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15465) clr.l FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15466) clr.l FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15467) bra.w fsub_zero_entry # go execute fsub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15469) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15470) # both operands are INFs. an OPERR will result if the INFs have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15471) # same signs. else,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15472) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15473) fsub_inf_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15474) mov.b SRC_EX(%a0),%d0 # exclusive or the signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15475) mov.b DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15476) eor.b %d1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15477) bpl.l res_operr # weed out (-INF)+(+INF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15479) # ok, so it's not an OPERR. but we do have to remember to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15480) # the src INF since that's where the 881/882 gets the j-bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15482) fsub_inf_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15483) fmovm.x SRC(%a0),&0x80 # return src INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15484) fneg.x %fp0 # invert sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15485) fbge.w fsub_inf_done # sign is now positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15486) mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15487) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15489) fsub_inf_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15490) fmovm.x DST(%a1),&0x80 # return dst INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15491) tst.b DST_EX(%a1) # is INF negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15492) bpl.b fsub_inf_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15493) mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15494) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15496) fsub_inf_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15497) mov.b &inf_bmask,FPSR_CC(%a6) # set INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15498) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15500) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15501) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15502) # fsqrt(): emulates the fsqrt instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15503) # fssqrt(): emulates the fssqrt instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15504) # fdsqrt(): emulates the fdsqrt instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15505) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15506) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15507) # scale_sqrt() - scale the source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15508) # unf_res() - return default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15509) # ovf_res() - return default overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15510) # res_qnan_1op() - return QNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15511) # res_snan_1op() - return SNAN result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15512) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15513) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15514) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15515) # d0 rnd prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15516) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15517) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15518) # fp0 = result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15519) # fp1 = EXOP (if exception occurred) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15520) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15521) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15522) # Handle NANs, infinities, and zeroes as special cases. Divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15523) # norms/denorms into ext/sgl/dbl precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15524) # For norms/denorms, scale the exponents such that a sqrt #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15525) # instruction won't cause an exception. Use the regular fsqrt to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15526) # compute a result. Check if the regular operands would have taken #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15527) # an exception. If so, return the default overflow/underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15528) # and return the EXOP if exceptions are enabled. Else, scale the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15529) # result operand to the proper exponent. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15530) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15531) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15533) global fssqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15534) fssqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15535) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15536) ori.b &s_mode*0x10,%d0 # insert sgl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15537) bra.b fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15539) global fdsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15540) fdsqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15541) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15542) ori.b &d_mode*0x10,%d0 # insert dbl precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15544) global fsqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15545) fsqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15546) mov.l %d0,L_SCR3(%a6) # store rnd info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15547) clr.w %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15548) mov.b STAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15549) bne.w fsqrt_not_norm # optimize on non-norm input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15551) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15552) # SQUARE ROOT: norms and denorms ONLY!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15553) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15554) fsqrt_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15555) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15556) bmi.l res_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15558) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15559) bne.b fsqrt_not_ext # no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15561) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15562) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15564) fsqrt.x (%a0),%fp0 # execute square root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15566) fmov.l %fpsr,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15567) or.l %d1,USER_FPSR(%a6) # set N,INEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15569) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15571) fsqrt_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15572) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15573) bmi.l res_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15575) andi.b &0xc0,%d0 # is precision extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15576) bne.b fsqrt_not_ext # no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15578) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15579) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15580) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15582) bsr.l scale_sqrt # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15584) bra.w fsqrt_sd_normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15586) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15587) # operand is either single or double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15588) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15589) fsqrt_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15590) cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15591) bne.w fsqrt_dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15593) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15594) # operand is to be rounded to single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15595) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15596) fsqrt_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15597) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15598) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15599) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15601) bsr.l scale_sqrt # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15603) cmpi.l %d0,&0x3fff-0x3f81 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15604) beq.w fsqrt_sd_may_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15605) bgt.w fsqrt_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15606) cmpi.l %d0,&0x3fff-0x407f # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15607) beq.w fsqrt_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15608) blt.w fsqrt_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15610) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15611) # operand will NOT overflow or underflow when moved in to the fp reg file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15612) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15613) fsqrt_sd_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15614) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15615) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15617) fsqrt.x FP_SCR0(%a6),%fp0 # perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15619) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15620) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15622) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15624) fsqrt_sd_normal_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15625) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15626) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15627) mov.w FP_SCR0_EX(%a6),%d1 # load sgn,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15628) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15629) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15630) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15631) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15632) or.w %d1,%d2 # concat old sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15633) mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15634) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15635) fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15636) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15638) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15639) # operand is to be rounded to double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15640) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15641) fsqrt_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15642) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15643) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15644) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15646) bsr.l scale_sqrt # calculate scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15648) cmpi.l %d0,&0x3fff-0x3c01 # will move in underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15649) beq.w fsqrt_sd_may_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15650) bgt.b fsqrt_sd_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15651) cmpi.l %d0,&0x3fff-0x43ff # will move in overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15652) beq.w fsqrt_sd_may_ovfl # maybe; go check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15653) blt.w fsqrt_sd_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15654) bra.w fsqrt_sd_normal # no; ho handle normalized op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15656) # we're on the line here and the distinguising characteristic is whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15657) # 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 15658) # elsewise fall through to underflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15659) fsqrt_sd_may_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15660) btst &0x0,1+FP_SCR0_EX(%a6) # is exponent 0x3fff?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15661) bne.w fsqrt_sd_normal # yes, so no underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15663) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15664) # operand WILL underflow when moved in to the fp register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15665) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15666) fsqrt_sd_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15667) bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15669) fmov.l &rz_mode*0x10,%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15670) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15672) fsqrt.x FP_SCR0(%a6),%fp0 # execute square root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15674) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15675) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15677) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15679) # if underflow or inexact is enabled, go calculate EXOP first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15680) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15681) andi.b &0x0b,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15682) bne.b fsqrt_sd_unfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15684) fsqrt_sd_unfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15685) fmovm.x &0x80,FP_SCR0(%a6) # store out result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15687) lea FP_SCR0(%a6),%a0 # pass: result addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15688) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15689) bsr.l unf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15690) or.b %d0,FPSR_CC(%a6) # set possible 'Z' ccode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15691) fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15692) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15694) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15695) # operand will underflow AND underflow is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15696) # Therefore, we must return the result rounded to extended precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15697) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15698) fsqrt_sd_unfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15699) mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15700) mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15701) mov.w FP_SCR0_EX(%a6),%d1 # load current exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15703) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15704) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15705) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15706) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15707) sub.l %d0,%d1 # subtract scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15708) addi.l &0x6000,%d1 # add new bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15709) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15710) or.w %d2,%d1 # concat new sign,new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15711) mov.w %d1,FP_SCR1_EX(%a6) # insert new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15712) fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15713) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15714) bra.b fsqrt_sd_unfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15716) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15717) # operand WILL overflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15718) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15719) fsqrt_sd_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15720) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15721) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15723) fsqrt.x FP_SCR0(%a6),%fp0 # perform square root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15725) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15726) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15728) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15730) fsqrt_sd_ovfl_tst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15731) or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15733) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15734) andi.b &0x13,%d1 # is OVFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15735) bne.b fsqrt_sd_ovfl_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15737) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15738) # OVFL is not enabled; therefore, we must create the default result by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15739) # calling ovf_res().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15740) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15741) fsqrt_sd_ovfl_dis:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15742) btst &neg_bit,FPSR_CC(%a6) # is result negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15743) sne %d1 # set sign param accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15744) mov.l L_SCR3(%a6),%d0 # pass: prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15745) bsr.l ovf_res # calculate default result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15746) or.b %d0,FPSR_CC(%a6) # set INF,N if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15747) fmovm.x (%a0),&0x80 # return default result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15748) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15750) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15751) # OVFL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15752) # the INEX2 bit has already been updated by the round to the correct precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15753) # now, round to extended(and don't alter the FPSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15754) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15755) fsqrt_sd_ovfl_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15756) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15757) mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15758) mov.l %d1,%d2 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15759) andi.l &0x7fff,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15760) andi.w &0x8000,%d2 # keep old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15761) sub.l %d0,%d1 # add scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15762) subi.l &0x6000,%d1 # subtract bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15763) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15764) or.w %d2,%d1 # concat sign,exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15765) mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15766) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15767) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15768) bra.b fsqrt_sd_ovfl_dis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15770) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15771) # the move in MAY underflow. so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15772) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15773) fsqrt_sd_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15774) btst &0x0,1+FP_SCR0_EX(%a6) # is exponent 0x3fff?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15775) bne.w fsqrt_sd_ovfl # yes, so overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15777) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15778) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15780) fsqrt.x FP_SCR0(%a6),%fp0 # perform absolute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15782) fmov.l %fpsr,%d1 # save status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15783) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15785) or.l %d1,USER_FPSR(%a6) # save INEX2,N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15787) fmov.x %fp0,%fp1 # make a copy of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15788) fcmp.b %fp1,&0x1 # is |result| >= 1.b?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15789) fbge.w fsqrt_sd_ovfl_tst # yes; overflow has occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15791) # no, it didn't overflow; we have correct result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15792) bra.w fsqrt_sd_normal_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15794) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15796) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15797) # input is not normalized; what is it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15798) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15799) fsqrt_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15800) cmpi.b %d1,&DENORM # weed out DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15801) beq.w fsqrt_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15802) cmpi.b %d1,&ZERO # weed out ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15803) beq.b fsqrt_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15804) cmpi.b %d1,&INF # weed out INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15805) beq.b fsqrt_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15806) cmpi.b %d1,&SNAN # weed out SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15807) beq.l res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15808) bra.l res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15810) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15811) # fsqrt(+0) = +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15812) # fsqrt(-0) = -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15813) # fsqrt(+INF) = +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15814) # fsqrt(-INF) = OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15815) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15816) fsqrt_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15817) tst.b SRC_EX(%a0) # is ZERO positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15818) bmi.b fsqrt_zero_m # negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15819) fsqrt_zero_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15820) fmov.s &0x00000000,%fp0 # return +ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15821) mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15822) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15823) fsqrt_zero_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15824) fmov.s &0x80000000,%fp0 # return -ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15825) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15826) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15828) fsqrt_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15829) tst.b SRC_EX(%a0) # is INF positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15830) bmi.l res_operr # negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15831) fsqrt_inf_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15832) fmovm.x SRC(%a0),&0x80 # return +INF in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15833) mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15834) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15836) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15838) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15839) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15840) # addsub_scaler2(): scale inputs to fadd/fsub such that no #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15841) # OVFL/UNFL exceptions will result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15842) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15843) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15844) # norm() - normalize mantissa after adjusting exponent #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15845) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15846) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15847) # FP_SRC(a6) = fp op1(src) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15848) # FP_DST(a6) = fp op2(dst) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15849) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15850) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15851) # FP_SRC(a6) = fp op1 scaled(src) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15852) # FP_DST(a6) = fp op2 scaled(dst) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15853) # d0 = scale amount #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15854) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15855) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15856) # If the DST exponent is > the SRC exponent, set the DST exponent #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15857) # equal to 0x3fff and scale the SRC exponent by the value that the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15858) # DST exponent was scaled by. If the SRC exponent is greater or equal, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15859) # do the opposite. Return this scale factor in d0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15860) # If the two exponents differ by > the number of mantissa bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15861) # plus two, then set the smallest exponent to a very small value as a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15862) # quick shortcut. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15863) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15864) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15866) global addsub_scaler2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15867) addsub_scaler2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15868) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15869) mov.l DST_HI(%a1),FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15870) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15871) mov.l DST_LO(%a1),FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15872) mov.w SRC_EX(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15873) mov.w DST_EX(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15874) mov.w %d0,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15875) mov.w %d1,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15877) andi.w &0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15878) andi.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15879) mov.w %d0,L_SCR1(%a6) # store src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15880) mov.w %d1,2+L_SCR1(%a6) # store dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15882) cmp.w %d0, %d1 # is src exp >= dst exp?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15883) bge.l src_exp_ge2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15885) # dst exp is > src exp; scale dst to exp = 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15886) dst_exp_gt2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15887) bsr.l scale_to_zero_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15888) mov.l %d0,-(%sp) # save scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15890) cmpi.b STAG(%a6),&DENORM # is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15891) bne.b cmpexp12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15893) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15894) bsr.l norm # normalize the denorm; result is new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15895) neg.w %d0 # new exp = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15896) mov.w %d0,L_SCR1(%a6) # inset new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15898) cmpexp12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15899) mov.w 2+L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15900) subi.w &mantissalen+2,%d0 # subtract mantissalen+2 from larger exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15902) cmp.w %d0,L_SCR1(%a6) # is difference >= len(mantissa)+2?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15903) bge.b quick_scale12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15905) mov.w L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15906) add.w 0x2(%sp),%d0 # scale src exponent by scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15907) mov.w FP_SCR0_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15908) and.w &0x8000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15909) or.w %d1,%d0 # concat {sgn,new exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15910) mov.w %d0,FP_SCR0_EX(%a6) # insert new dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15912) mov.l (%sp)+,%d0 # return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15913) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15915) quick_scale12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15916) andi.w &0x8000,FP_SCR0_EX(%a6) # zero src exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15917) bset &0x0,1+FP_SCR0_EX(%a6) # set exp = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15919) mov.l (%sp)+,%d0 # return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15920) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15922) # src exp is >= dst exp; scale src to exp = 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15923) src_exp_ge2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15924) bsr.l scale_to_zero_src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15925) mov.l %d0,-(%sp) # save scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15927) cmpi.b DTAG(%a6),&DENORM # is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15928) bne.b cmpexp22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15929) lea FP_SCR1(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15930) bsr.l norm # normalize the denorm; result is new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15931) neg.w %d0 # new exp = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15932) mov.w %d0,2+L_SCR1(%a6) # inset new exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15934) cmpexp22:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15935) mov.w L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15936) subi.w &mantissalen+2,%d0 # subtract mantissalen+2 from larger exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15938) cmp.w %d0,2+L_SCR1(%a6) # is difference >= len(mantissa)+2?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15939) bge.b quick_scale22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15941) mov.w 2+L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15942) add.w 0x2(%sp),%d0 # scale dst exponent by scale factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15943) mov.w FP_SCR1_EX(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15944) andi.w &0x8000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15945) or.w %d1,%d0 # concat {sgn,new exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15946) mov.w %d0,FP_SCR1_EX(%a6) # insert new dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15948) mov.l (%sp)+,%d0 # return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15949) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15951) quick_scale22:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15952) andi.w &0x8000,FP_SCR1_EX(%a6) # zero dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15953) bset &0x0,1+FP_SCR1_EX(%a6) # set exp = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15955) mov.l (%sp)+,%d0 # return SCALE factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15956) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15958) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15960) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15961) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15962) # scale_to_zero_src(): scale the exponent of extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15963) # value at FP_SCR0(a6). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15964) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15965) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15966) # norm() - normalize the mantissa if the operand was a DENORM #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15967) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15968) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15969) # FP_SCR0(a6) = extended precision operand to be scaled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15970) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15971) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15972) # FP_SCR0(a6) = scaled extended precision operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15973) # d0 = scale value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15974) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15975) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15976) # Set the exponent of the input operand to 0x3fff. Save the value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15977) # of the difference between the original and new exponent. Then, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15978) # normalize the operand if it was a DENORM. Add this normalization #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15979) # value to the previous value. Return the result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15980) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15981) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15983) global scale_to_zero_src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15984) scale_to_zero_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15985) mov.w FP_SCR0_EX(%a6),%d1 # extract operand's {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15986) mov.w %d1,%d0 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15988) andi.l &0x7fff,%d1 # extract operand's exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15990) andi.w &0x8000,%d0 # extract operand's sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15991) or.w &0x3fff,%d0 # insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15993) mov.w %d0,FP_SCR0_EX(%a6) # insert biased exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15995) cmpi.b STAG(%a6),&DENORM # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15996) beq.b stzs_denorm # normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15998) stzs_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15999) mov.l &0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16000) sub.l %d1,%d0 # scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16002) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16004) stzs_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16005) lea FP_SCR0(%a6),%a0 # pass ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16006) bsr.l norm # normalize denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16007) neg.l %d0 # new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16008) mov.l %d0,%d1 # prepare for op_norm call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16009) bra.b stzs_norm # finish scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16011) ###
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16013) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16014) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16015) # scale_sqrt(): scale the input operand exponent so a subsequent #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16016) # fsqrt operation won't take an exception. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16017) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16018) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16019) # norm() - normalize the mantissa if the operand was a DENORM #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16020) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16021) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16022) # FP_SCR0(a6) = extended precision operand to be scaled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16023) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16024) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16025) # FP_SCR0(a6) = scaled extended precision operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16026) # d0 = scale value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16027) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16028) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16029) # If the input operand is a DENORM, normalize it. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16030) # If the exponent of the input operand is even, set the exponent #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16031) # to 0x3ffe and return a scale factor of "(exp-0x3ffe)/2". If the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16032) # exponent of the input operand is off, set the exponent to ox3fff and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16033) # return a scale factor of "(exp-0x3fff)/2". #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16034) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16035) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16037) global scale_sqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16038) scale_sqrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16039) cmpi.b STAG(%a6),&DENORM # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16040) beq.b ss_denorm # normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16042) mov.w FP_SCR0_EX(%a6),%d1 # extract operand's {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16043) andi.l &0x7fff,%d1 # extract operand's exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16045) andi.w &0x8000,FP_SCR0_EX(%a6) # extract operand's sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16047) btst &0x0,%d1 # is exp even or odd?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16048) beq.b ss_norm_even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16050) ori.w &0x3fff,FP_SCR0_EX(%a6) # insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16052) mov.l &0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16053) sub.l %d1,%d0 # scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16054) asr.l &0x1,%d0 # divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16055) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16057) ss_norm_even:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16058) ori.w &0x3ffe,FP_SCR0_EX(%a6) # insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16060) mov.l &0x3ffe,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16061) sub.l %d1,%d0 # scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16062) asr.l &0x1,%d0 # divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16063) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16065) ss_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16066) lea FP_SCR0(%a6),%a0 # pass ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16067) bsr.l norm # normalize denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16069) btst &0x0,%d0 # is exp even or odd?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16070) beq.b ss_denorm_even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16072) ori.w &0x3fff,FP_SCR0_EX(%a6) # insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16074) add.l &0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16075) asr.l &0x1,%d0 # divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16076) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16078) ss_denorm_even:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16079) ori.w &0x3ffe,FP_SCR0_EX(%a6) # insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16081) add.l &0x3ffe,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16082) asr.l &0x1,%d0 # divide scale factor by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16083) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16085) ###
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16087) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16088) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16089) # scale_to_zero_dst(): scale the exponent of extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16090) # value at FP_SCR1(a6). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16091) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16092) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16093) # norm() - normalize the mantissa if the operand was a DENORM #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16094) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16095) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16096) # FP_SCR1(a6) = extended precision operand to be scaled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16097) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16098) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16099) # FP_SCR1(a6) = scaled extended precision operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16100) # d0 = scale value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16101) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16102) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16103) # Set the exponent of the input operand to 0x3fff. Save the value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16104) # of the difference between the original and new exponent. Then, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16105) # normalize the operand if it was a DENORM. Add this normalization #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16106) # value to the previous value. Return the result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16107) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16108) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16110) global scale_to_zero_dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16111) scale_to_zero_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16112) mov.w FP_SCR1_EX(%a6),%d1 # extract operand's {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16113) mov.w %d1,%d0 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16115) andi.l &0x7fff,%d1 # extract operand's exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16117) andi.w &0x8000,%d0 # extract operand's sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16118) or.w &0x3fff,%d0 # insert new operand's exponent(=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16120) mov.w %d0,FP_SCR1_EX(%a6) # insert biased exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16122) cmpi.b DTAG(%a6),&DENORM # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16123) beq.b stzd_denorm # normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16125) stzd_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16126) mov.l &0x3fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16127) sub.l %d1,%d0 # scale = BIAS + (-exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16128) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16130) stzd_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16131) lea FP_SCR1(%a6),%a0 # pass ptr to dst op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16132) bsr.l norm # normalize denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16133) neg.l %d0 # new exponent = -(shft val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16134) mov.l %d0,%d1 # prepare for op_norm call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16135) bra.b stzd_norm # finish scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16137) ##########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16139) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16140) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16141) # res_qnan(): return default result w/ QNAN operand for dyadic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16142) # res_snan(): return default result w/ SNAN operand for dyadic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16143) # res_qnan_1op(): return dflt result w/ QNAN operand for monadic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16144) # res_snan_1op(): return dflt result w/ SNAN operand for monadic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16145) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16146) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16147) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16148) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16149) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16150) # FP_SRC(a6) = pointer to extended precision src operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16151) # FP_DST(a6) = pointer to extended precision dst operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16152) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16153) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16154) # fp0 = default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16155) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16156) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16157) # If either operand (but not both operands) of an operation is a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16158) # nonsignalling NAN, then that NAN is returned as the result. If both #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16159) # operands are nonsignalling NANs, then the destination operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16160) # nonsignalling NAN is returned as the result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16161) # If either operand to an operation is a signalling NAN (SNAN), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16162) # then, the SNAN bit is set in the FPSR EXC byte. If the SNAN trap #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16163) # enable bit is set in the FPCR, then the trap is taken and the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16164) # destination is not modified. If the SNAN trap enable bit is not set, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16165) # then the SNAN is converted to a nonsignalling NAN (by setting the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16166) # SNAN bit in the operand to one), and the operation continues as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16167) # described in the preceding paragraph, for nonsignalling NANs. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16168) # Make sure the appropriate FPSR bits are set before exiting. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16169) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16170) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16172) global res_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16173) global res_snan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16174) res_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16175) res_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16176) cmp.b DTAG(%a6), &SNAN # is the dst an SNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16177) beq.b dst_snan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16178) cmp.b DTAG(%a6), &QNAN # is the dst a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16179) beq.b dst_qnan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16180) src_nan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16181) cmp.b STAG(%a6), &QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16182) beq.b src_qnan2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16183) global res_snan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16184) res_snan_1op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16185) src_snan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16186) bset &0x6, FP_SRC_HI(%a6) # set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16187) or.l &nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16188) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16189) bra.b nan_comp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16190) global res_qnan_1op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16191) res_qnan_1op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16192) src_qnan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16193) or.l &nan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16194) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16195) bra.b nan_comp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16196) dst_snan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16197) or.l &nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16198) bset &0x6, FP_DST_HI(%a6) # set SNAN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16199) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16200) bra.b nan_comp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16201) dst_qnan2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16202) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16203) cmp.b STAG(%a6), &SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16204) bne nan_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16205) or.l &aiop_mask+snan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16206) nan_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16207) or.l &nan_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16208) nan_comp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16209) btst &0x7, FTEMP_EX(%a0) # is NAN neg?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16210) beq.b nan_not_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16211) or.l &neg_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16212) nan_not_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16213) fmovm.x (%a0), &0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16214) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16216) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16217) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16218) # res_operr(): return default result during operand error #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16219) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16220) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16221) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16222) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16223) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16224) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16225) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16226) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16227) # fp0 = default operand error result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16228) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16229) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16230) # An nonsignalling NAN is returned as the default result when #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16231) # an operand error occurs for the following cases: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16232) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16233) # Multiply: (Infinity x Zero) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16234) # Divide : (Zero / Zero) || (Infinity / Infinity) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16235) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16236) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16238) global res_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16239) res_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16240) or.l &nan_mask+operr_mask+aiop_mask, USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16241) fmovm.x nan_return(%pc), &0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16242) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16244) nan_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16245) long 0x7fff0000, 0xffffffff, 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16247) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16248) # fdbcc(): routine to emulate the fdbcc instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16249) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16250) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16251) # _fdbcc() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16252) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16253) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16254) # fetch_dreg() - fetch Dn value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16255) # store_dreg_l() - store updated Dn value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16256) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16257) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16258) # d0 = displacement #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16259) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16260) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16261) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16262) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16263) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16264) # This routine checks which conditional predicate is specified by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16265) # the stacked fdbcc instruction opcode and then branches to a routine #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16266) # for that predicate. The corresponding fbcc instruction is then used #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16267) # to see whether the condition (specified by the stacked FPSR) is true #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16268) # or false. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16269) # If a BSUN exception should be indicated, the BSUN and ABSUN #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16270) # bits are set in the stacked FPSR. If the BSUN exception is enabled, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16271) # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16272) # enabled BSUN should not be flagged and the predicate is true, then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16273) # Dn is fetched and decremented by one. If Dn is not equal to -1, add #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16274) # the displacement value to the stacked PC so that when an "rte" is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16275) # finally executed, the branch occurs. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16276) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16277) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16278) global _fdbcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16279) _fdbcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16280) mov.l %d0,L_SCR1(%a6) # save displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16282) mov.w EXC_CMDREG(%a6),%d0 # fetch predicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16284) clr.l %d1 # clear scratch reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16285) mov.b FPSR_CC(%a6),%d1 # fetch fp ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16286) ror.l &0x8,%d1 # rotate to top byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16287) fmov.l %d1,%fpsr # insert into FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16289) mov.w (tbl_fdbcc.b,%pc,%d0.w*2),%d1 # load table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16290) jmp (tbl_fdbcc.b,%pc,%d1.w) # jump to fdbcc routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16292) tbl_fdbcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16293) short fdbcc_f - tbl_fdbcc # 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16294) short fdbcc_eq - tbl_fdbcc # 01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16295) short fdbcc_ogt - tbl_fdbcc # 02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16296) short fdbcc_oge - tbl_fdbcc # 03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16297) short fdbcc_olt - tbl_fdbcc # 04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16298) short fdbcc_ole - tbl_fdbcc # 05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16299) short fdbcc_ogl - tbl_fdbcc # 06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16300) short fdbcc_or - tbl_fdbcc # 07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16301) short fdbcc_un - tbl_fdbcc # 08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16302) short fdbcc_ueq - tbl_fdbcc # 09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16303) short fdbcc_ugt - tbl_fdbcc # 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16304) short fdbcc_uge - tbl_fdbcc # 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16305) short fdbcc_ult - tbl_fdbcc # 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16306) short fdbcc_ule - tbl_fdbcc # 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16307) short fdbcc_neq - tbl_fdbcc # 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16308) short fdbcc_t - tbl_fdbcc # 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16309) short fdbcc_sf - tbl_fdbcc # 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16310) short fdbcc_seq - tbl_fdbcc # 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16311) short fdbcc_gt - tbl_fdbcc # 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16312) short fdbcc_ge - tbl_fdbcc # 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16313) short fdbcc_lt - tbl_fdbcc # 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16314) short fdbcc_le - tbl_fdbcc # 21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16315) short fdbcc_gl - tbl_fdbcc # 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16316) short fdbcc_gle - tbl_fdbcc # 23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16317) short fdbcc_ngle - tbl_fdbcc # 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16318) short fdbcc_ngl - tbl_fdbcc # 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16319) short fdbcc_nle - tbl_fdbcc # 26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16320) short fdbcc_nlt - tbl_fdbcc # 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16321) short fdbcc_nge - tbl_fdbcc # 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16322) short fdbcc_ngt - tbl_fdbcc # 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16323) short fdbcc_sneq - tbl_fdbcc # 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16324) short fdbcc_st - tbl_fdbcc # 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16326) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16327) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16328) # IEEE Nonaware tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16329) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16330) # For the IEEE nonaware tests, only the false branch changes the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16331) # counter. However, the true branch may set bsun so we check to see #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16332) # if the NAN bit is set, in which case BSUN and AIOP will be set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16333) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16334) # The cases EQ and NE are shared by the Aware and Nonaware groups #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16335) # and are incapable of setting the BSUN exception bit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16336) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16337) # Typically, only one of the two possible branch directions could #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16338) # have the NAN bit set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16339) # (This is assuming the mutual exclusiveness of FPSR cc bit groupings #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16340) # is preserved.) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16341) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16342) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16344) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16345) # equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16346) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16347) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16348) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16349) fdbcc_eq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16350) fbeq.w fdbcc_eq_yes # equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16351) fdbcc_eq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16352) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16353) fdbcc_eq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16354) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16356) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16357) # not equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16358) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16359) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16360) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16361) fdbcc_neq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16362) fbneq.w fdbcc_neq_yes # not equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16363) fdbcc_neq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16364) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16365) fdbcc_neq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16366) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16368) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16369) # greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16370) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16371) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16372) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16373) fdbcc_gt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16374) fbgt.w fdbcc_gt_yes # greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16375) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16376) beq.w fdbcc_false # no;go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16377) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16378) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16379) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16380) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16381) fdbcc_gt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16382) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16384) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16385) # not greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16386) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16387) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16388) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16389) fdbcc_ngt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16390) fbngt.w fdbcc_ngt_yes # not greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16391) fdbcc_ngt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16392) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16393) fdbcc_ngt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16394) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16395) beq.b fdbcc_ngt_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16396) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16397) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16398) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16399) fdbcc_ngt_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16400) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16402) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16403) # greater than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16404) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16405) # Zv(NANvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16406) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16407) fdbcc_ge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16408) fbge.w fdbcc_ge_yes # greater than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16409) fdbcc_ge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16410) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16411) beq.w fdbcc_false # no;go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16412) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16413) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16414) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16415) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16416) fdbcc_ge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16417) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16418) beq.b fdbcc_ge_yes_done # no;go do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16419) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16420) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16421) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16422) fdbcc_ge_yes_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16423) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16425) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16426) # not (greater than or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16427) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16428) # NANv(N^Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16429) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16430) fdbcc_nge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16431) fbnge.w fdbcc_nge_yes # not (greater than or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16432) fdbcc_nge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16433) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16434) fdbcc_nge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16435) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16436) beq.b fdbcc_nge_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16437) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16438) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16439) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16440) fdbcc_nge_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16441) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16443) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16444) # less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16445) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16446) # N^(NANvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16447) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16448) fdbcc_lt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16449) fblt.w fdbcc_lt_yes # less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16450) fdbcc_lt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16451) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16452) beq.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16453) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16454) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16455) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16456) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16457) fdbcc_lt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16458) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16460) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16461) # not less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16462) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16463) # NANv(ZvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16464) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16465) fdbcc_nlt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16466) fbnlt.w fdbcc_nlt_yes # not less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16467) fdbcc_nlt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16468) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16469) fdbcc_nlt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16470) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16471) beq.b fdbcc_nlt_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16472) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16473) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16474) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16475) fdbcc_nlt_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16476) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16478) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16479) # less than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16480) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16481) # Zv(N^NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16482) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16483) fdbcc_le:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16484) fble.w fdbcc_le_yes # less than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16485) fdbcc_le_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16486) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16487) beq.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16488) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16489) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16490) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16491) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16492) fdbcc_le_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16493) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16494) beq.b fdbcc_le_yes_done # no; go do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16495) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16496) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16497) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16498) fdbcc_le_yes_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16499) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16501) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16502) # not (less than or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16503) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16504) # NANv(NvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16505) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16506) fdbcc_nle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16507) fbnle.w fdbcc_nle_yes # not (less than or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16508) fdbcc_nle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16509) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16510) fdbcc_nle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16511) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16512) beq.w fdbcc_nle_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16513) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16514) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16515) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16516) fdbcc_nle_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16517) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16519) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16520) # greater or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16521) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16522) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16523) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16524) fdbcc_gl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16525) fbgl.w fdbcc_gl_yes # greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16526) fdbcc_gl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16527) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16528) beq.w fdbcc_false # no; handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16529) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16530) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16531) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16532) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16533) fdbcc_gl_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16534) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16536) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16537) # not (greater or less than):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16538) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16539) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16540) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16541) fdbcc_ngl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16542) fbngl.w fdbcc_ngl_yes # not (greater or less than)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16543) fdbcc_ngl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16544) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16545) fdbcc_ngl_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16546) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16547) beq.b fdbcc_ngl_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16548) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16549) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16550) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16551) fdbcc_ngl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16552) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16554) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16555) # greater, less, or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16556) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16557) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16558) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16559) fdbcc_gle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16560) fbgle.w fdbcc_gle_yes # greater, less, or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16561) fdbcc_gle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16562) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16563) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16564) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16565) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16566) fdbcc_gle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16567) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16569) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16570) # not (greater, less, or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16571) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16572) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16573) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16574) fdbcc_ngle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16575) fbngle.w fdbcc_ngle_yes # not (greater, less, or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16576) fdbcc_ngle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16577) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16578) fdbcc_ngle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16579) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16580) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16581) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16582) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16584) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16585) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16586) # Miscellaneous tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16587) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16588) # For the IEEE miscellaneous tests, all but fdbf and fdbt can set bsun. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16589) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16590) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16592) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16593) # false:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16594) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16595) # False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16596) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16597) fdbcc_f: # no bsun possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16598) bra.w fdbcc_false # go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16600) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16601) # true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16602) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16603) # True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16604) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16605) fdbcc_t: # no bsun possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16606) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16608) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16609) # signalling false:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16610) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16611) # False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16612) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16613) fdbcc_sf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16614) btst &nan_bit, FPSR_CC(%a6) # is NAN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16615) beq.w fdbcc_false # no;go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16616) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16617) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16618) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16619) bra.w fdbcc_false # go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16621) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16622) # signalling true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16623) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16624) # True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16625) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16626) fdbcc_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16627) btst &nan_bit, FPSR_CC(%a6) # is NAN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16628) beq.b fdbcc_st_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16629) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16630) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16631) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16632) fdbcc_st_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16633) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16635) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16636) # signalling equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16637) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16638) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16639) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16640) fdbcc_seq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16641) fbseq.w fdbcc_seq_yes # signalling equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16642) fdbcc_seq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16643) btst &nan_bit, FPSR_CC(%a6) # is NAN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16644) beq.w fdbcc_false # no;go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16645) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16646) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16647) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16648) bra.w fdbcc_false # go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16649) fdbcc_seq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16650) btst &nan_bit, FPSR_CC(%a6) # is NAN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16651) beq.b fdbcc_seq_yes_done # no;go do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16652) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16653) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16654) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16655) fdbcc_seq_yes_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16656) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16658) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16659) # signalling not equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16660) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16661) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16662) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16663) fdbcc_sneq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16664) fbsneq.w fdbcc_sneq_yes # signalling not equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16665) fdbcc_sneq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16666) btst &nan_bit, FPSR_CC(%a6) # is NAN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16667) beq.w fdbcc_false # no;go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16668) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16669) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16670) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16671) bra.w fdbcc_false # go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16672) fdbcc_sneq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16673) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16674) beq.w fdbcc_sneq_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16675) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16676) btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16677) bne.w fdbcc_bsun # yes; we have an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16678) fdbcc_sneq_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16679) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16681) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16682) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16683) # IEEE Aware tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16684) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16685) # For the IEEE aware tests, action is only taken if the result is false.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16686) # Therefore, the opposite branch type is used to jump to the decrement #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16687) # routine. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16688) # The BSUN exception will not be set for any of these tests. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16689) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16690) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16692) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16693) # ordered greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16694) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16695) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16696) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16697) fdbcc_ogt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16698) fbogt.w fdbcc_ogt_yes # ordered greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16699) fdbcc_ogt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16700) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16701) fdbcc_ogt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16702) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16704) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16705) # unordered or less or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16706) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16707) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16708) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16709) fdbcc_ule:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16710) fbule.w fdbcc_ule_yes # unordered or less or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16711) fdbcc_ule_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16712) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16713) fdbcc_ule_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16714) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16716) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16717) # ordered greater than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16718) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16719) # Zv(NANvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16720) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16721) fdbcc_oge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16722) fboge.w fdbcc_oge_yes # ordered greater than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16723) fdbcc_oge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16724) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16725) fdbcc_oge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16726) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16728) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16729) # unordered or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16730) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16731) # NANv(N^Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16732) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16733) fdbcc_ult:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16734) fbult.w fdbcc_ult_yes # unordered or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16735) fdbcc_ult_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16736) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16737) fdbcc_ult_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16738) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16740) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16741) # ordered less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16742) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16743) # N^(NANvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16744) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16745) fdbcc_olt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16746) fbolt.w fdbcc_olt_yes # ordered less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16747) fdbcc_olt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16748) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16749) fdbcc_olt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16750) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16752) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16753) # unordered or greater or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16754) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16755) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16756) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16757) fdbcc_uge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16758) fbuge.w fdbcc_uge_yes # unordered or greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16759) fdbcc_uge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16760) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16761) fdbcc_uge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16762) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16764) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16765) # ordered less than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16766) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16767) # Zv(N^NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16768) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16769) fdbcc_ole:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16770) fbole.w fdbcc_ole_yes # ordered greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16771) fdbcc_ole_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16772) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16773) fdbcc_ole_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16774) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16776) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16777) # unordered or greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16778) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16779) # NANv(NvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16780) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16781) fdbcc_ugt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16782) fbugt.w fdbcc_ugt_yes # unordered or greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16783) fdbcc_ugt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16784) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16785) fdbcc_ugt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16786) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16788) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16789) # ordered greater or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16790) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16791) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16792) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16793) fdbcc_ogl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16794) fbogl.w fdbcc_ogl_yes # ordered greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16795) fdbcc_ogl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16796) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16797) fdbcc_ogl_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16798) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16800) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16801) # unordered or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16802) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16803) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16804) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16805) fdbcc_ueq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16806) fbueq.w fdbcc_ueq_yes # unordered or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16807) fdbcc_ueq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16808) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16809) fdbcc_ueq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16810) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16812) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16813) # ordered:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16814) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16815) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16816) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16817) fdbcc_or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16818) fbor.w fdbcc_or_yes # ordered?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16819) fdbcc_or_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16820) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16821) fdbcc_or_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16822) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16824) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16825) # unordered:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16826) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16827) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16828) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16829) fdbcc_un:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16830) fbun.w fdbcc_un_yes # unordered?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16831) fdbcc_un_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16832) bra.w fdbcc_false # no; go handle counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16833) fdbcc_un_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16834) rts # yes; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16836) #######################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16838) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16839) # the bsun exception bit was not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16840) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16841) # (1) subtract 1 from the count register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16842) # (2) if (cr == -1) then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16843) # pc = pc of next instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16844) # else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16845) # pc += sign_ext(16-bit displacement)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16846) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16847) fdbcc_false:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16848) mov.b 1+EXC_OPWORD(%a6), %d1 # fetch lo opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16849) andi.w &0x7, %d1 # extract count register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16851) bsr.l fetch_dreg # fetch count value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16852) # make sure that d0 isn't corrupted between calls...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16854) subq.w &0x1, %d0 # Dn - 1 -> Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16856) bsr.l store_dreg_l # store new count value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16858) cmpi.w %d0, &-0x1 # is (Dn == -1)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16859) bne.b fdbcc_false_cont # no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16860) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16862) fdbcc_false_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16863) mov.l L_SCR1(%a6),%d0 # fetch displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16864) add.l USER_FPIAR(%a6),%d0 # add instruction PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16865) addq.l &0x4,%d0 # add instruction length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16866) mov.l %d0,EXC_PC(%a6) # set new PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16867) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16869) # the emulation routine set bsun and BSUN was enabled. have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16870) # fix stack and jump to the bsun handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16871) # let the caller of this routine shift the stack frame up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16872) # eliminate the effective address field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16873) fdbcc_bsun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16874) mov.b &fbsun_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16875) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16877) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16878) # ftrapcc(): routine to emulate the ftrapcc instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16879) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16880) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16881) # _ftrapcc() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16882) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16883) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16884) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16885) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16886) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16887) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16888) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16889) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16890) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16891) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16892) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16893) # This routine checks which conditional predicate is specified by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16894) # the stacked ftrapcc instruction opcode and then branches to a routine #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16895) # for that predicate. The corresponding fbcc instruction is then used #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16896) # to see whether the condition (specified by the stacked FPSR) is true #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16897) # or false. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16898) # If a BSUN exception should be indicated, the BSUN and ABSUN #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16899) # bits are set in the stacked FPSR. If the BSUN exception is enabled, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16900) # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16901) # enabled BSUN should not be flagged and the predicate is true, then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16902) # the ftrapcc_flg is set in the SPCOND_FLG location. These special #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16903) # flags indicate to the calling routine to emulate the exceptional #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16904) # condition. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16905) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16906) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16908) global _ftrapcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16909) _ftrapcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16910) mov.w EXC_CMDREG(%a6),%d0 # fetch predicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16912) clr.l %d1 # clear scratch reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16913) mov.b FPSR_CC(%a6),%d1 # fetch fp ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16914) ror.l &0x8,%d1 # rotate to top byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16915) fmov.l %d1,%fpsr # insert into FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16917) mov.w (tbl_ftrapcc.b,%pc,%d0.w*2), %d1 # load table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16918) jmp (tbl_ftrapcc.b,%pc,%d1.w) # jump to ftrapcc routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16920) tbl_ftrapcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16921) short ftrapcc_f - tbl_ftrapcc # 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16922) short ftrapcc_eq - tbl_ftrapcc # 01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16923) short ftrapcc_ogt - tbl_ftrapcc # 02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16924) short ftrapcc_oge - tbl_ftrapcc # 03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16925) short ftrapcc_olt - tbl_ftrapcc # 04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16926) short ftrapcc_ole - tbl_ftrapcc # 05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16927) short ftrapcc_ogl - tbl_ftrapcc # 06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16928) short ftrapcc_or - tbl_ftrapcc # 07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16929) short ftrapcc_un - tbl_ftrapcc # 08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16930) short ftrapcc_ueq - tbl_ftrapcc # 09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16931) short ftrapcc_ugt - tbl_ftrapcc # 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16932) short ftrapcc_uge - tbl_ftrapcc # 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16933) short ftrapcc_ult - tbl_ftrapcc # 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16934) short ftrapcc_ule - tbl_ftrapcc # 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16935) short ftrapcc_neq - tbl_ftrapcc # 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16936) short ftrapcc_t - tbl_ftrapcc # 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16937) short ftrapcc_sf - tbl_ftrapcc # 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16938) short ftrapcc_seq - tbl_ftrapcc # 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16939) short ftrapcc_gt - tbl_ftrapcc # 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16940) short ftrapcc_ge - tbl_ftrapcc # 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16941) short ftrapcc_lt - tbl_ftrapcc # 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16942) short ftrapcc_le - tbl_ftrapcc # 21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16943) short ftrapcc_gl - tbl_ftrapcc # 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16944) short ftrapcc_gle - tbl_ftrapcc # 23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16945) short ftrapcc_ngle - tbl_ftrapcc # 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16946) short ftrapcc_ngl - tbl_ftrapcc # 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16947) short ftrapcc_nle - tbl_ftrapcc # 26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16948) short ftrapcc_nlt - tbl_ftrapcc # 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16949) short ftrapcc_nge - tbl_ftrapcc # 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16950) short ftrapcc_ngt - tbl_ftrapcc # 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16951) short ftrapcc_sneq - tbl_ftrapcc # 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16952) short ftrapcc_st - tbl_ftrapcc # 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16954) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16955) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16956) # IEEE Nonaware tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16957) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16958) # For the IEEE nonaware tests, we set the result based on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16959) # floating point condition codes. In addition, we check to see #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16960) # if the NAN bit is set, in which case BSUN and AIOP will be set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16961) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16962) # The cases EQ and NE are shared by the Aware and Nonaware groups #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16963) # and are incapable of setting the BSUN exception bit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16964) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16965) # Typically, only one of the two possible branch directions could #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16966) # have the NAN bit set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16967) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16968) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16970) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16971) # equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16972) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16973) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16974) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16975) ftrapcc_eq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16976) fbeq.w ftrapcc_trap # equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16977) ftrapcc_eq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16978) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16980) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16981) # not equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16982) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16983) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16984) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16985) ftrapcc_neq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16986) fbneq.w ftrapcc_trap # not equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16987) ftrapcc_neq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16988) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16990) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16991) # greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16992) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16993) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16994) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16995) ftrapcc_gt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16996) fbgt.w ftrapcc_trap # greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16997) ftrapcc_gt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16998) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16999) beq.b ftrapcc_gt_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17000) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17001) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17002) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17003) ftrapcc_gt_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17004) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17006) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17007) # not greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17008) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17009) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17010) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17011) ftrapcc_ngt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17012) fbngt.w ftrapcc_ngt_yes # not greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17013) ftrapcc_ngt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17014) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17015) ftrapcc_ngt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17016) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17017) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17018) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17019) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17020) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17021) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17023) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17024) # greater than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17025) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17026) # Zv(NANvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17027) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17028) ftrapcc_ge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17029) fbge.w ftrapcc_ge_yes # greater than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17030) ftrapcc_ge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17031) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17032) beq.b ftrapcc_ge_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17033) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17034) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17035) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17036) ftrapcc_ge_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17037) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17038) ftrapcc_ge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17039) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17040) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17041) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17042) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17043) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17044) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17046) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17047) # not (greater than or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17048) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17049) # NANv(N^Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17050) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17051) ftrapcc_nge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17052) fbnge.w ftrapcc_nge_yes # not (greater than or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17053) ftrapcc_nge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17054) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17055) ftrapcc_nge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17056) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17057) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17058) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17059) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17060) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17061) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17063) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17064) # less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17065) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17066) # N^(NANvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17067) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17068) ftrapcc_lt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17069) fblt.w ftrapcc_trap # less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17070) ftrapcc_lt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17071) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17072) beq.b ftrapcc_lt_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17073) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17074) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17075) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17076) ftrapcc_lt_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17077) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17079) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17080) # not less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17081) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17082) # NANv(ZvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17083) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17084) ftrapcc_nlt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17085) fbnlt.w ftrapcc_nlt_yes # not less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17086) ftrapcc_nlt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17087) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17088) ftrapcc_nlt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17089) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17090) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17091) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17092) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17093) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17094) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17096) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17097) # less than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17098) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17099) # Zv(N^NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17100) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17101) ftrapcc_le:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17102) fble.w ftrapcc_le_yes # less than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17103) ftrapcc_le_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17104) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17105) beq.b ftrapcc_le_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17106) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17107) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17108) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17109) ftrapcc_le_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17110) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17111) ftrapcc_le_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17112) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17113) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17114) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17115) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17116) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17117) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17119) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17120) # not (less than or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17121) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17122) # NANv(NvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17123) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17124) ftrapcc_nle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17125) fbnle.w ftrapcc_nle_yes # not (less than or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17126) ftrapcc_nle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17127) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17128) ftrapcc_nle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17129) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17130) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17131) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17132) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17133) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17134) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17136) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17137) # greater or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17138) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17139) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17140) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17141) ftrapcc_gl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17142) fbgl.w ftrapcc_trap # greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17143) ftrapcc_gl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17144) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17145) beq.b ftrapcc_gl_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17146) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17147) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17148) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17149) ftrapcc_gl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17150) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17152) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17153) # not (greater or less than):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17154) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17155) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17156) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17157) ftrapcc_ngl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17158) fbngl.w ftrapcc_ngl_yes # not (greater or less than)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17159) ftrapcc_ngl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17160) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17161) ftrapcc_ngl_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17162) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17163) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17164) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17165) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17166) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17167) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17169) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17170) # greater, less, or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17171) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17172) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17173) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17174) ftrapcc_gle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17175) fbgle.w ftrapcc_trap # greater, less, or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17176) ftrapcc_gle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17177) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17178) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17179) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17180) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17182) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17183) # not (greater, less, or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17184) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17185) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17186) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17187) ftrapcc_ngle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17188) fbngle.w ftrapcc_ngle_yes # not (greater, less, or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17189) ftrapcc_ngle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17190) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17191) ftrapcc_ngle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17192) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17193) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17194) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17195) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17197) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17198) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17199) # Miscellaneous tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17200) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17201) # For the IEEE aware tests, we only have to set the result based on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17202) # floating point condition codes. The BSUN exception will not be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17203) # set for any of these tests. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17204) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17205) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17207) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17208) # false:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17209) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17210) # False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17211) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17212) ftrapcc_f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17213) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17215) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17216) # true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17217) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17218) # True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17219) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17220) ftrapcc_t:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17221) bra.w ftrapcc_trap # go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17223) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17224) # signalling false:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17225) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17226) # False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17227) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17228) ftrapcc_sf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17229) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17230) beq.b ftrapcc_sf_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17231) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17232) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17233) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17234) ftrapcc_sf_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17235) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17237) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17238) # signalling true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17239) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17240) # True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17241) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17242) ftrapcc_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17243) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17244) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17245) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17246) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17247) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17248) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17250) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17251) # signalling equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17252) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17253) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17254) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17255) ftrapcc_seq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17256) fbseq.w ftrapcc_seq_yes # signalling equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17257) ftrapcc_seq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17258) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17259) beq.w ftrapcc_seq_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17260) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17261) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17262) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17263) ftrapcc_seq_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17264) rts # no; do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17265) ftrapcc_seq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17266) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17267) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17268) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17269) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17270) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17271) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17273) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17274) # signalling not equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17275) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17276) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17277) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17278) ftrapcc_sneq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17279) fbsneq.w ftrapcc_sneq_yes # signalling equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17280) ftrapcc_sneq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17281) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17282) beq.w ftrapcc_sneq_no_done # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17283) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17284) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17285) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17286) ftrapcc_sneq_no_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17287) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17288) ftrapcc_sneq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17289) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17290) beq.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17291) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17292) btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17293) bne.w ftrapcc_bsun # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17294) bra.w ftrapcc_trap # no; go take trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17296) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17297) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17298) # IEEE Aware tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17299) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17300) # For the IEEE aware tests, we only have to set the result based on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17301) # floating point condition codes. The BSUN exception will not be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17302) # set for any of these tests. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17303) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17304) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17306) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17307) # ordered greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17308) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17309) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17310) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17311) ftrapcc_ogt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17312) fbogt.w ftrapcc_trap # ordered greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17313) ftrapcc_ogt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17314) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17316) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17317) # unordered or less or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17318) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17319) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17320) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17321) ftrapcc_ule:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17322) fbule.w ftrapcc_trap # unordered or less or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17323) ftrapcc_ule_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17324) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17326) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17327) # ordered greater than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17328) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17329) # Zv(NANvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17330) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17331) ftrapcc_oge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17332) fboge.w ftrapcc_trap # ordered greater than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17333) ftrapcc_oge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17334) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17336) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17337) # unordered or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17338) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17339) # NANv(N^Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17340) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17341) ftrapcc_ult:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17342) fbult.w ftrapcc_trap # unordered or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17343) ftrapcc_ult_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17344) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17346) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17347) # ordered less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17348) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17349) # N^(NANvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17350) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17351) ftrapcc_olt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17352) fbolt.w ftrapcc_trap # ordered less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17353) ftrapcc_olt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17354) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17356) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17357) # unordered or greater or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17358) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17359) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17360) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17361) ftrapcc_uge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17362) fbuge.w ftrapcc_trap # unordered or greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17363) ftrapcc_uge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17364) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17366) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17367) # ordered less than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17368) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17369) # Zv(N^NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17370) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17371) ftrapcc_ole:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17372) fbole.w ftrapcc_trap # ordered greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17373) ftrapcc_ole_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17374) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17376) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17377) # unordered or greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17378) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17379) # NANv(NvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17380) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17381) ftrapcc_ugt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17382) fbugt.w ftrapcc_trap # unordered or greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17383) ftrapcc_ugt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17384) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17386) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17387) # ordered greater or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17388) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17389) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17390) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17391) ftrapcc_ogl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17392) fbogl.w ftrapcc_trap # ordered greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17393) ftrapcc_ogl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17394) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17396) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17397) # unordered or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17398) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17399) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17400) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17401) ftrapcc_ueq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17402) fbueq.w ftrapcc_trap # unordered or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17403) ftrapcc_ueq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17404) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17406) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17407) # ordered:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17408) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17409) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17410) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17411) ftrapcc_or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17412) fbor.w ftrapcc_trap # ordered?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17413) ftrapcc_or_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17414) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17416) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17417) # unordered:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17418) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17419) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17420) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17421) ftrapcc_un:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17422) fbun.w ftrapcc_trap # unordered?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17423) ftrapcc_un_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17424) rts # do nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17426) #######################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17428) # the bsun exception bit was not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17429) # we will need to jump to the ftrapcc vector. the stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17430) # is the same size as that of the fp unimp instruction. the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17431) # only difference is that the <ea> field should hold the PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17432) # of the ftrapcc instruction and the vector offset field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17433) # should denote the ftrapcc trap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17434) ftrapcc_trap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17435) mov.b &ftrapcc_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17436) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17438) # the emulation routine set bsun and BSUN was enabled. have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17439) # fix stack and jump to the bsun handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17440) # let the caller of this routine shift the stack frame up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17441) # eliminate the effective address field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17442) ftrapcc_bsun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17443) mov.b &fbsun_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17444) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17446) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17447) # fscc(): routine to emulate the fscc instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17448) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17449) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17450) # _fscc() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17451) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17452) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17453) # store_dreg_b() - store result to data register file #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17454) # dec_areg() - decrement an areg for -(an) mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17455) # inc_areg() - increment an areg for (an)+ mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17456) # _dmem_write_byte() - store result to memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17457) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17458) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17459) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17460) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17461) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17462) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17463) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17464) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17465) # This routine checks which conditional predicate is specified by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17466) # the stacked fscc instruction opcode and then branches to a routine #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17467) # for that predicate. The corresponding fbcc instruction is then used #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17468) # to see whether the condition (specified by the stacked FPSR) is true #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17469) # or false. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17470) # If a BSUN exception should be indicated, the BSUN and ABSUN #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17471) # bits are set in the stacked FPSR. If the BSUN exception is enabled, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17472) # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17473) # enabled BSUN should not be flagged and the predicate is true, then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17474) # the result is stored to the data register file or memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17475) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17476) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17478) global _fscc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17479) _fscc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17480) mov.w EXC_CMDREG(%a6),%d0 # fetch predicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17482) clr.l %d1 # clear scratch reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17483) mov.b FPSR_CC(%a6),%d1 # fetch fp ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17484) ror.l &0x8,%d1 # rotate to top byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17485) fmov.l %d1,%fpsr # insert into FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17487) mov.w (tbl_fscc.b,%pc,%d0.w*2),%d1 # load table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17488) jmp (tbl_fscc.b,%pc,%d1.w) # jump to fscc routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17490) tbl_fscc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17491) short fscc_f - tbl_fscc # 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17492) short fscc_eq - tbl_fscc # 01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17493) short fscc_ogt - tbl_fscc # 02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17494) short fscc_oge - tbl_fscc # 03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17495) short fscc_olt - tbl_fscc # 04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17496) short fscc_ole - tbl_fscc # 05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17497) short fscc_ogl - tbl_fscc # 06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17498) short fscc_or - tbl_fscc # 07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17499) short fscc_un - tbl_fscc # 08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17500) short fscc_ueq - tbl_fscc # 09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17501) short fscc_ugt - tbl_fscc # 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17502) short fscc_uge - tbl_fscc # 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17503) short fscc_ult - tbl_fscc # 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17504) short fscc_ule - tbl_fscc # 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17505) short fscc_neq - tbl_fscc # 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17506) short fscc_t - tbl_fscc # 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17507) short fscc_sf - tbl_fscc # 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17508) short fscc_seq - tbl_fscc # 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17509) short fscc_gt - tbl_fscc # 18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17510) short fscc_ge - tbl_fscc # 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17511) short fscc_lt - tbl_fscc # 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17512) short fscc_le - tbl_fscc # 21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17513) short fscc_gl - tbl_fscc # 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17514) short fscc_gle - tbl_fscc # 23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17515) short fscc_ngle - tbl_fscc # 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17516) short fscc_ngl - tbl_fscc # 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17517) short fscc_nle - tbl_fscc # 26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17518) short fscc_nlt - tbl_fscc # 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17519) short fscc_nge - tbl_fscc # 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17520) short fscc_ngt - tbl_fscc # 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17521) short fscc_sneq - tbl_fscc # 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17522) short fscc_st - tbl_fscc # 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17524) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17525) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17526) # IEEE Nonaware tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17527) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17528) # For the IEEE nonaware tests, we set the result based on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17529) # floating point condition codes. In addition, we check to see #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17530) # if the NAN bit is set, in which case BSUN and AIOP will be set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17531) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17532) # The cases EQ and NE are shared by the Aware and Nonaware groups #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17533) # and are incapable of setting the BSUN exception bit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17534) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17535) # Typically, only one of the two possible branch directions could #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17536) # have the NAN bit set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17537) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17538) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17540) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17541) # equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17542) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17543) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17544) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17545) fscc_eq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17546) fbeq.w fscc_eq_yes # equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17547) fscc_eq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17548) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17549) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17550) fscc_eq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17551) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17552) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17554) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17555) # not equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17556) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17557) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17558) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17559) fscc_neq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17560) fbneq.w fscc_neq_yes # not equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17561) fscc_neq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17562) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17563) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17564) fscc_neq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17565) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17566) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17568) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17569) # greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17570) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17571) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17572) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17573) fscc_gt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17574) fbgt.w fscc_gt_yes # greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17575) fscc_gt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17576) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17577) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17578) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17579) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17580) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17581) fscc_gt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17582) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17583) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17585) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17586) # not greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17587) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17588) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17589) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17590) fscc_ngt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17591) fbngt.w fscc_ngt_yes # not greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17592) fscc_ngt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17593) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17594) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17595) fscc_ngt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17596) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17597) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17598) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17599) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17600) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17602) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17603) # greater than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17604) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17605) # Zv(NANvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17606) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17607) fscc_ge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17608) fbge.w fscc_ge_yes # greater than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17609) fscc_ge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17610) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17611) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17612) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17613) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17614) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17615) fscc_ge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17616) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17617) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17618) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17619) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17620) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17622) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17623) # not (greater than or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17624) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17625) # NANv(N^Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17626) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17627) fscc_nge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17628) fbnge.w fscc_nge_yes # not (greater than or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17629) fscc_nge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17630) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17631) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17632) fscc_nge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17633) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17634) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17635) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17636) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17637) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17639) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17640) # less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17641) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17642) # N^(NANvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17643) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17644) fscc_lt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17645) fblt.w fscc_lt_yes # less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17646) fscc_lt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17647) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17648) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17649) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17650) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17651) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17652) fscc_lt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17653) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17654) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17656) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17657) # not less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17658) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17659) # NANv(ZvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17660) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17661) fscc_nlt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17662) fbnlt.w fscc_nlt_yes # not less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17663) fscc_nlt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17664) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17665) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17666) fscc_nlt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17667) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17668) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17669) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17670) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17671) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17673) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17674) # less than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17675) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17676) # Zv(N^NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17677) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17678) fscc_le:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17679) fble.w fscc_le_yes # less than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17680) fscc_le_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17681) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17682) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17683) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17684) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17685) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17686) fscc_le_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17687) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17688) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17689) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17690) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17691) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17693) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17694) # not (less than or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17695) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17696) # NANv(NvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17697) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17698) fscc_nle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17699) fbnle.w fscc_nle_yes # not (less than or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17700) fscc_nle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17701) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17702) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17703) fscc_nle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17704) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17705) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17706) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17707) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17708) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17710) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17711) # greater or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17712) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17713) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17714) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17715) fscc_gl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17716) fbgl.w fscc_gl_yes # greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17717) fscc_gl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17718) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17719) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17720) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17721) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17722) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17723) fscc_gl_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17724) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17725) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17727) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17728) # not (greater or less than):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17729) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17730) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17731) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17732) fscc_ngl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17733) fbngl.w fscc_ngl_yes # not (greater or less than)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17734) fscc_ngl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17735) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17736) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17737) fscc_ngl_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17738) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17739) btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17740) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17741) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17742) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17744) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17745) # greater, less, or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17746) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17747) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17748) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17749) fscc_gle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17750) fbgle.w fscc_gle_yes # greater, less, or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17751) fscc_gle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17752) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17753) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17754) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17755) fscc_gle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17756) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17757) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17759) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17760) # not (greater, less, or equal):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17761) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17762) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17763) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17764) fscc_ngle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17765) fbngle.w fscc_ngle_yes # not (greater, less, or equal)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17766) fscc_ngle_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17767) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17768) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17769) fscc_ngle_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17770) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17771) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17772) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17774) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17775) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17776) # Miscellaneous tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17777) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17778) # For the IEEE aware tests, we only have to set the result based on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17779) # floating point condition codes. The BSUN exception will not be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17780) # set for any of these tests. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17781) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17782) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17784) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17785) # false:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17786) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17787) # False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17788) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17789) fscc_f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17790) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17791) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17793) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17794) # true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17795) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17796) # True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17797) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17798) fscc_t:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17799) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17800) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17802) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17803) # signalling false:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17804) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17805) # False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17806) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17807) fscc_sf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17808) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17809) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17810) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17811) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17812) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17814) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17815) # signalling true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17816) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17817) # True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17818) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17819) fscc_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17820) st %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17821) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17822) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17823) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17824) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17826) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17827) # signalling equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17828) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17829) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17830) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17831) fscc_seq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17832) fbseq.w fscc_seq_yes # signalling equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17833) fscc_seq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17834) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17835) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17836) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17837) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17838) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17839) fscc_seq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17840) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17841) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17842) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17843) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17844) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17846) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17847) # signalling not equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17848) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17849) # Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17850) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17851) fscc_sneq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17852) fbsneq.w fscc_sneq_yes # signalling equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17853) fscc_sneq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17854) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17855) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17856) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17857) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17858) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17859) fscc_sneq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17860) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17861) btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17862) beq.w fscc_done # no;go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17863) ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17864) bra.w fscc_chk_bsun # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17866) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17867) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17868) # IEEE Aware tests #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17869) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17870) # For the IEEE aware tests, we only have to set the result based on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17871) # floating point condition codes. The BSUN exception will not be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17872) # set for any of these tests. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17873) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17874) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17876) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17877) # ordered greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17878) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17879) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17880) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17881) fscc_ogt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17882) fbogt.w fscc_ogt_yes # ordered greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17883) fscc_ogt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17884) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17885) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17886) fscc_ogt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17887) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17888) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17890) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17891) # unordered or less or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17892) # _______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17893) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17894) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17895) fscc_ule:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17896) fbule.w fscc_ule_yes # unordered or less or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17897) fscc_ule_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17898) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17899) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17900) fscc_ule_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17901) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17902) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17904) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17905) # ordered greater than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17906) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17907) # Zv(NANvN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17908) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17909) fscc_oge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17910) fboge.w fscc_oge_yes # ordered greater than or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17911) fscc_oge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17912) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17913) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17914) fscc_oge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17915) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17916) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17918) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17919) # unordered or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17920) # _
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17921) # NANv(N^Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17922) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17923) fscc_ult:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17924) fbult.w fscc_ult_yes # unordered or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17925) fscc_ult_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17926) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17927) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17928) fscc_ult_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17929) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17930) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17932) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17933) # ordered less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17934) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17935) # N^(NANvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17936) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17937) fscc_olt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17938) fbolt.w fscc_olt_yes # ordered less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17939) fscc_olt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17940) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17941) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17942) fscc_olt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17943) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17944) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17946) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17947) # unordered or greater or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17948) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17949) # NANvZvN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17950) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17951) fscc_uge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17952) fbuge.w fscc_uge_yes # unordered or greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17953) fscc_uge_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17954) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17955) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17956) fscc_uge_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17957) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17958) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17960) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17961) # ordered less than or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17962) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17963) # Zv(N^NAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17964) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17965) fscc_ole:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17966) fbole.w fscc_ole_yes # ordered greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17967) fscc_ole_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17968) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17969) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17970) fscc_ole_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17971) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17972) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17974) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17975) # unordered or greater than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17976) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17977) # NANv(NvZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17978) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17979) fscc_ugt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17980) fbugt.w fscc_ugt_yes # unordered or greater than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17981) fscc_ugt_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17982) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17983) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17984) fscc_ugt_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17985) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17986) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17988) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17989) # ordered greater or less than:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17990) # _____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17991) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17992) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17993) fscc_ogl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17994) fbogl.w fscc_ogl_yes # ordered greater or less than?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17995) fscc_ogl_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17996) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17997) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17998) fscc_ogl_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17999) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18000) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18002) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18003) # unordered or equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18004) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18005) # NANvZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18006) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18007) fscc_ueq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18008) fbueq.w fscc_ueq_yes # unordered or equal?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18009) fscc_ueq_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18010) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18011) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18012) fscc_ueq_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18013) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18014) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18016) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18017) # ordered:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18018) # ___
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18019) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18020) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18021) fscc_or:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18022) fbor.w fscc_or_yes # ordered?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18023) fscc_or_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18024) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18025) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18026) fscc_or_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18027) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18028) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18030) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18031) # unordered:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18032) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18033) # NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18034) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18035) fscc_un:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18036) fbun.w fscc_un_yes # unordered?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18037) fscc_un_no:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18038) clr.b %d0 # set false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18039) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18040) fscc_un_yes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18041) st %d0 # set true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18042) bra.w fscc_done # go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18044) #######################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18046) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18047) # the bsun exception bit was set. now, check to see is BSUN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18048) # is enabled. if so, don't store result and correct stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18049) # for a bsun exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18050) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18051) fscc_chk_bsun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18052) btst &bsun_bit,FPCR_ENABLE(%a6) # was BSUN set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18053) bne.w fscc_bsun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18055) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18056) # the bsun exception bit was not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18057) # the result has been selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18058) # now, check to see if the result is to be stored in the data register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18059) # file or in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18060) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18061) fscc_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18062) mov.l %d0,%a0 # save result for a moment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18064) mov.b 1+EXC_OPWORD(%a6),%d1 # fetch lo opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18065) mov.l %d1,%d0 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18066) andi.b &0x38,%d1 # extract src mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18068) bne.b fscc_mem_op # it's a memory operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18070) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18071) andi.w &0x7,%d1 # pass index in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18072) mov.l %a0,%d0 # pass result in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18073) bsr.l store_dreg_b # save result in regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18074) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18076) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18077) # the stacked <ea> is correct with the exception of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18078) # -> Dn : <ea> is garbage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18079) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18080) # if the addressing mode is post-increment or pre-decrement,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18081) # then the address registers have not been updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18082) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18083) fscc_mem_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18084) cmpi.b %d1,&0x18 # is <ea> (An)+ ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18085) beq.b fscc_mem_inc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18086) cmpi.b %d1,&0x20 # is <ea> -(An) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18087) beq.b fscc_mem_dec # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18089) mov.l %a0,%d0 # pass result in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18090) mov.l EXC_EA(%a6),%a0 # fetch <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18091) bsr.l _dmem_write_byte # write result byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18093) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18094) bne.w fscc_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18096) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18098) # addressing mode is post-increment. write the result byte. if the write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18099) # fails then don't update the address register. if write passes then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18100) # call inc_areg() to update the address register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18101) fscc_mem_inc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18102) mov.l %a0,%d0 # pass result in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18103) mov.l EXC_EA(%a6),%a0 # fetch <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18104) bsr.l _dmem_write_byte # write result byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18106) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18107) bne.w fscc_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18109) mov.b 0x1+EXC_OPWORD(%a6),%d1 # fetch opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18110) andi.w &0x7,%d1 # pass index in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18111) movq.l &0x1,%d0 # pass amt to inc by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18112) bsr.l inc_areg # increment address register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18114) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18116) # addressing mode is pre-decrement. write the result byte. if the write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18117) # fails then don't update the address register. if the write passes then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18118) # call dec_areg() to update the address register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18119) fscc_mem_dec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18120) mov.l %a0,%d0 # pass result in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18121) mov.l EXC_EA(%a6),%a0 # fetch <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18122) bsr.l _dmem_write_byte # write result byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18124) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18125) bne.w fscc_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18127) mov.b 0x1+EXC_OPWORD(%a6),%d1 # fetch opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18128) andi.w &0x7,%d1 # pass index in d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18129) movq.l &0x1,%d0 # pass amt to dec by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18130) bsr.l dec_areg # decrement address register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18132) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18134) # the emulation routine set bsun and BSUN was enabled. have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18135) # fix stack and jump to the bsun handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18136) # let the caller of this routine shift the stack frame up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18137) # eliminate the effective address field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18138) fscc_bsun:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18139) mov.b &fbsun_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18140) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18142) # the byte write to memory has failed. pass the failing effective address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18143) # and a FSLW to funimp_dacc().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18144) fscc_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18145) mov.w &0x00a1,EXC_VOFF(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18146) bra.l facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18148) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18149) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18150) # fmovm_dynamic(): emulate "fmovm" dynamic instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18151) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18152) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18153) # fetch_dreg() - fetch data register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18154) # {i,d,}mem_read() - fetch data from memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18155) # _mem_write() - write data to memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18156) # iea_iacc() - instruction memory access error occurred #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18157) # iea_dacc() - data memory access error occurred #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18158) # restore() - restore An index regs if access error occurred #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18159) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18160) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18161) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18162) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18163) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18164) # If instr is "fmovm Dn,-(A7)" from supervisor mode, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18165) # d0 = size of dump #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18166) # d1 = Dn #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18167) # Else if instruction access error, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18168) # d0 = FSLW #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18169) # Else if data access error, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18170) # d0 = FSLW #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18171) # a0 = address of fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18172) # Else #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18173) # none. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18174) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18175) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18176) # The effective address must be calculated since this is entered #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18177) # from an "Unimplemented Effective Address" exception handler. So, we #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18178) # have our own fcalc_ea() routine here. If an access error is flagged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18179) # by a _{i,d,}mem_read() call, we must exit through the special #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18180) # handler. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18181) # The data register is determined and its value loaded to get the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18182) # string of FP registers affected. This value is used as an index into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18183) # a lookup table such that we can determine the number of bytes #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18184) # involved. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18185) # If the instruction is "fmovm.x <ea>,Dn", a _mem_read() is used #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18186) # to read in all FP values. Again, _mem_read() may fail and require a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18187) # special exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18188) # If the instruction is "fmovm.x DN,<ea>", a _mem_write() is used #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18189) # to write all FP values. _mem_write() may also fail. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18190) # If the instruction is "fmovm.x DN,-(a7)" from supervisor mode, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18191) # then we return the size of the dump and the string to the caller #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18192) # so that the move can occur outside of this routine. This special #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18193) # case is required so that moves to the system stack are handled #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18194) # correctly. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18195) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18196) # DYNAMIC: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18197) # fmovm.x dn, <ea> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18198) # fmovm.x <ea>, dn #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18199) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18200) # <WORD 1> <WORD2> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18201) # 1111 0010 00 |<ea>| 11@& 1000 0$$$ 0000 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18202) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18203) # & = (0): predecrement addressing mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18204) # (1): postincrement or control addressing mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18205) # @ = (0): move listed regs from memory to the FPU #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18206) # (1): move listed regs from the FPU to memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18207) # $$$ : index of data register holding reg select mask #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18208) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18209) # NOTES: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18210) # If the data register holds a zero, then the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18211) # instruction is a nop. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18212) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18213) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18215) global fmovm_dynamic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18216) fmovm_dynamic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18218) # extract the data register in which the bit string resides...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18219) mov.b 1+EXC_EXTWORD(%a6),%d1 # fetch extword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18220) andi.w &0x70,%d1 # extract reg bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18221) lsr.b &0x4,%d1 # shift into lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18223) # fetch the bit string into d0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18224) bsr.l fetch_dreg # fetch reg string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18226) andi.l &0x000000ff,%d0 # keep only lo byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18228) mov.l %d0,-(%sp) # save strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18229) mov.b (tbl_fmovm_size.w,%pc,%d0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18230) mov.l %d0,-(%sp) # save size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18231) bsr.l fmovm_calc_ea # calculate <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18232) mov.l (%sp)+,%d0 # restore size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18233) mov.l (%sp)+,%d1 # restore strg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18235) # if the bit string is a zero, then the operation is a no-op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18236) # but, make sure that we've calculated ea and advanced the opword pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18237) beq.w fmovm_data_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18239) # separate move ins from move outs...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18240) btst &0x5,EXC_EXTWORD(%a6) # is it a move in or out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18241) beq.w fmovm_data_in # it's a move out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18243) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18244) # MOVE OUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18245) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18246) fmovm_data_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18247) btst &0x4,EXC_EXTWORD(%a6) # control or predecrement?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18248) bne.w fmovm_out_ctrl # control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18250) ############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18251) fmovm_out_predec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18252) # for predecrement mode, the bit string is the opposite of both control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18253) # operations and postincrement mode. (bit7 = FP7 ... bit0 = FP0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18254) # here, we convert it to be just like the others...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18255) mov.b (tbl_fmovm_convert.w,%pc,%d1.w*1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18257) btst &0x5,EXC_SR(%a6) # user or supervisor mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18258) beq.b fmovm_out_ctrl # user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18260) fmovm_out_predec_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18261) cmpi.b SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18262) bne.b fmovm_out_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18264) # the operation was unfortunately an: fmovm.x dn,-(sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18265) # called from supervisor mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18266) # we're also passing "size" and "strg" back to the calling routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18267) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18269) ############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18270) fmovm_out_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18271) mov.l %a0,%a1 # move <ea> to a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18273) sub.l %d0,%sp # subtract size of dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18274) lea (%sp),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18276) tst.b %d1 # should FP0 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18277) bpl.b fmovm_out_ctrl_fp1 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18279) mov.l 0x0+EXC_FP0(%a6),(%a0)+ # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18280) mov.l 0x4+EXC_FP0(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18281) mov.l 0x8+EXC_FP0(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18283) fmovm_out_ctrl_fp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18284) lsl.b &0x1,%d1 # should FP1 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18285) bpl.b fmovm_out_ctrl_fp2 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18287) mov.l 0x0+EXC_FP1(%a6),(%a0)+ # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18288) mov.l 0x4+EXC_FP1(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18289) mov.l 0x8+EXC_FP1(%a6),(%a0)+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18291) fmovm_out_ctrl_fp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18292) lsl.b &0x1,%d1 # should FP2 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18293) bpl.b fmovm_out_ctrl_fp3 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18295) fmovm.x &0x20,(%a0) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18296) add.l &0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18298) fmovm_out_ctrl_fp3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18299) lsl.b &0x1,%d1 # should FP3 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18300) bpl.b fmovm_out_ctrl_fp4 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18302) fmovm.x &0x10,(%a0) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18303) add.l &0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18305) fmovm_out_ctrl_fp4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18306) lsl.b &0x1,%d1 # should FP4 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18307) bpl.b fmovm_out_ctrl_fp5 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18309) fmovm.x &0x08,(%a0) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18310) add.l &0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18312) fmovm_out_ctrl_fp5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18313) lsl.b &0x1,%d1 # should FP5 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18314) bpl.b fmovm_out_ctrl_fp6 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18316) fmovm.x &0x04,(%a0) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18317) add.l &0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18319) fmovm_out_ctrl_fp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18320) lsl.b &0x1,%d1 # should FP6 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18321) bpl.b fmovm_out_ctrl_fp7 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18323) fmovm.x &0x02,(%a0) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18324) add.l &0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18326) fmovm_out_ctrl_fp7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18327) lsl.b &0x1,%d1 # should FP7 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18328) bpl.b fmovm_out_ctrl_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18330) fmovm.x &0x01,(%a0) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18331) add.l &0xc,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18333) fmovm_out_ctrl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18334) mov.l %a1,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18336) lea (%sp),%a0 # pass: supervisor src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18337) mov.l %d0,-(%sp) # save size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18338) bsr.l _dmem_write # copy data to user mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18340) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18341) add.l %d0,%sp # clear fpreg data from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18343) tst.l %d1 # did dstore err?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18344) bne.w fmovm_out_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18346) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18348) ############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18349) # MOVE IN: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18350) ############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18351) fmovm_data_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18352) mov.l %a0,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18354) sub.l %d0,%sp # make room for fpregs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18355) lea (%sp),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18357) mov.l %d1,-(%sp) # save bit string for later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18358) mov.l %d0,-(%sp) # save # of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18360) bsr.l _dmem_read # copy data from user mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18362) mov.l (%sp)+,%d0 # retrieve # of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18364) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18365) bne.w fmovm_in_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18367) mov.l (%sp)+,%d1 # load bit string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18369) lea (%sp),%a0 # addr of stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18371) tst.b %d1 # should FP0 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18372) bpl.b fmovm_data_in_fp1 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18374) mov.l (%a0)+,0x0+EXC_FP0(%a6) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18375) mov.l (%a0)+,0x4+EXC_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18376) mov.l (%a0)+,0x8+EXC_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18378) fmovm_data_in_fp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18379) lsl.b &0x1,%d1 # should FP1 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18380) bpl.b fmovm_data_in_fp2 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18382) mov.l (%a0)+,0x0+EXC_FP1(%a6) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18383) mov.l (%a0)+,0x4+EXC_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18384) mov.l (%a0)+,0x8+EXC_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18386) fmovm_data_in_fp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18387) lsl.b &0x1,%d1 # should FP2 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18388) bpl.b fmovm_data_in_fp3 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18390) fmovm.x (%a0)+,&0x20 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18392) fmovm_data_in_fp3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18393) lsl.b &0x1,%d1 # should FP3 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18394) bpl.b fmovm_data_in_fp4 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18396) fmovm.x (%a0)+,&0x10 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18398) fmovm_data_in_fp4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18399) lsl.b &0x1,%d1 # should FP4 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18400) bpl.b fmovm_data_in_fp5 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18402) fmovm.x (%a0)+,&0x08 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18404) fmovm_data_in_fp5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18405) lsl.b &0x1,%d1 # should FP5 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18406) bpl.b fmovm_data_in_fp6 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18408) fmovm.x (%a0)+,&0x04 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18410) fmovm_data_in_fp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18411) lsl.b &0x1,%d1 # should FP6 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18412) bpl.b fmovm_data_in_fp7 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18414) fmovm.x (%a0)+,&0x02 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18416) fmovm_data_in_fp7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18417) lsl.b &0x1,%d1 # should FP7 be moved?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18418) bpl.b fmovm_data_in_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18420) fmovm.x (%a0)+,&0x01 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18422) fmovm_data_in_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18423) add.l %d0,%sp # remove fpregs from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18424) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18426) #####################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18428) fmovm_data_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18429) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18431) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18433) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18434) # table indexed by the operation's bit string that gives the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18435) # of bytes that will be moved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18436) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18437) # number of bytes = (# of 1's in bit string) * 12(bytes/fpreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18438) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18439) tbl_fmovm_size:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18440) byte 0x00,0x0c,0x0c,0x18,0x0c,0x18,0x18,0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18441) byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18442) byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18443) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18444) byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18445) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18446) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18447) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18448) byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18449) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18450) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18451) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18452) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18453) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18454) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18455) byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18456) byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18457) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18458) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18459) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18460) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18461) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18462) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18463) byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18464) byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18465) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18466) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18467) byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18468) byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18469) byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18470) byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18471) byte 0x3c,0x48,0x48,0x54,0x48,0x54,0x54,0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18473) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18474) # table to convert a pre-decrement bit string into a post-increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18475) # or control bit string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18476) # ex: 0x00 ==> 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18477) # 0x01 ==> 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18478) # 0x02 ==> 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18479) # .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18480) # .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18481) # 0xfd ==> 0xbf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18482) # 0xfe ==> 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18483) # 0xff ==> 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18484) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18485) tbl_fmovm_convert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18486) byte 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18487) byte 0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18488) byte 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18489) byte 0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18490) byte 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18491) byte 0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18492) byte 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18493) byte 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18494) byte 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18495) byte 0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18496) byte 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18497) byte 0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18498) byte 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18499) byte 0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18500) byte 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18501) byte 0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18502) byte 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18503) byte 0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18504) byte 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18505) byte 0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18506) byte 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18507) byte 0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18508) byte 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18509) byte 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18510) byte 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18511) byte 0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18512) byte 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18513) byte 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18514) byte 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18515) byte 0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18516) byte 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18517) byte 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18519) global fmovm_calc_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18520) ###############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18521) # _fmovm_calc_ea: calculate effective address #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18522) ###############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18523) fmovm_calc_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18524) mov.l %d0,%a0 # move # bytes to a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18526) # currently, MODE and REG are taken from the EXC_OPWORD. this could be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18527) # easily changed if they were inputs passed in registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18528) mov.w EXC_OPWORD(%a6),%d0 # fetch opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18529) mov.w %d0,%d1 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18531) andi.w &0x3f,%d0 # extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18532) andi.l &0x7,%d1 # extract reg field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18534) # jump to the corresponding function for each {MODE,REG} pair.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18535) mov.w (tbl_fea_mode.b,%pc,%d0.w*2),%d0 # fetch jmp distance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18536) jmp (tbl_fea_mode.b,%pc,%d0.w*1) # jmp to correct ea mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18538) swbeg &64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18539) tbl_fea_mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18540) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18541) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18542) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18543) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18544) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18545) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18546) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18547) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18549) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18550) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18551) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18552) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18553) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18554) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18555) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18556) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18558) short faddr_ind_a0 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18559) short faddr_ind_a1 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18560) short faddr_ind_a2 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18561) short faddr_ind_a3 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18562) short faddr_ind_a4 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18563) short faddr_ind_a5 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18564) short faddr_ind_a6 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18565) short faddr_ind_a7 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18567) short faddr_ind_p_a0 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18568) short faddr_ind_p_a1 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18569) short faddr_ind_p_a2 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18570) short faddr_ind_p_a3 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18571) short faddr_ind_p_a4 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18572) short faddr_ind_p_a5 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18573) short faddr_ind_p_a6 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18574) short faddr_ind_p_a7 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18576) short faddr_ind_m_a0 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18577) short faddr_ind_m_a1 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18578) short faddr_ind_m_a2 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18579) short faddr_ind_m_a3 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18580) short faddr_ind_m_a4 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18581) short faddr_ind_m_a5 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18582) short faddr_ind_m_a6 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18583) short faddr_ind_m_a7 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18585) short faddr_ind_disp_a0 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18586) short faddr_ind_disp_a1 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18587) short faddr_ind_disp_a2 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18588) short faddr_ind_disp_a3 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18589) short faddr_ind_disp_a4 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18590) short faddr_ind_disp_a5 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18591) short faddr_ind_disp_a6 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18592) short faddr_ind_disp_a7 - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18594) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18595) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18596) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18597) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18598) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18599) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18600) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18601) short faddr_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18603) short fabs_short - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18604) short fabs_long - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18605) short fpc_ind - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18606) short fpc_ind_ext - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18607) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18608) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18609) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18610) short tbl_fea_mode - tbl_fea_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18612) ###################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18613) # Address register indirect: (An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18614) ###################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18615) faddr_ind_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18616) mov.l EXC_DREGS+0x8(%a6),%a0 # Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18617) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18619) faddr_ind_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18620) mov.l EXC_DREGS+0xc(%a6),%a0 # Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18621) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18623) faddr_ind_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18624) mov.l %a2,%a0 # Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18625) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18627) faddr_ind_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18628) mov.l %a3,%a0 # Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18629) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18631) faddr_ind_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18632) mov.l %a4,%a0 # Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18633) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18635) faddr_ind_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18636) mov.l %a5,%a0 # Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18637) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18639) faddr_ind_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18640) mov.l (%a6),%a0 # Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18641) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18643) faddr_ind_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18644) mov.l EXC_A7(%a6),%a0 # Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18645) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18647) #####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18648) # Address register indirect w/ postincrement: (An)+ #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18649) #####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18650) faddr_ind_p_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18651) mov.l EXC_DREGS+0x8(%a6),%d0 # Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18652) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18653) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18654) mov.l %d1,EXC_DREGS+0x8(%a6) # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18655) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18656) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18658) faddr_ind_p_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18659) mov.l EXC_DREGS+0xc(%a6),%d0 # Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18660) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18661) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18662) mov.l %d1,EXC_DREGS+0xc(%a6) # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18663) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18664) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18666) faddr_ind_p_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18667) mov.l %a2,%d0 # Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18668) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18669) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18670) mov.l %d1,%a2 # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18671) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18672) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18674) faddr_ind_p_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18675) mov.l %a3,%d0 # Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18676) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18677) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18678) mov.l %d1,%a3 # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18679) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18680) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18682) faddr_ind_p_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18683) mov.l %a4,%d0 # Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18684) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18685) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18686) mov.l %d1,%a4 # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18687) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18688) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18690) faddr_ind_p_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18691) mov.l %a5,%d0 # Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18692) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18693) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18694) mov.l %d1,%a5 # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18695) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18696) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18698) faddr_ind_p_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18699) mov.l (%a6),%d0 # Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18700) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18701) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18702) mov.l %d1,(%a6) # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18703) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18704) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18706) faddr_ind_p_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18707) mov.b &mia7_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18709) mov.l EXC_A7(%a6),%d0 # Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18710) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18711) add.l %a0,%d1 # Increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18712) mov.l %d1,EXC_A7(%a6) # Save incr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18713) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18714) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18716) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18717) # Address register indirect w/ predecrement: -(An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18718) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18719) faddr_ind_m_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18720) mov.l EXC_DREGS+0x8(%a6),%d0 # Get current a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18721) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18722) mov.l %d0,EXC_DREGS+0x8(%a6) # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18723) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18724) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18726) faddr_ind_m_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18727) mov.l EXC_DREGS+0xc(%a6),%d0 # Get current a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18728) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18729) mov.l %d0,EXC_DREGS+0xc(%a6) # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18730) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18731) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18733) faddr_ind_m_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18734) mov.l %a2,%d0 # Get current a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18735) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18736) mov.l %d0,%a2 # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18737) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18738) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18740) faddr_ind_m_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18741) mov.l %a3,%d0 # Get current a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18742) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18743) mov.l %d0,%a3 # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18744) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18745) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18747) faddr_ind_m_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18748) mov.l %a4,%d0 # Get current a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18749) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18750) mov.l %d0,%a4 # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18751) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18752) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18754) faddr_ind_m_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18755) mov.l %a5,%d0 # Get current a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18756) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18757) mov.l %d0,%a5 # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18758) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18759) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18761) faddr_ind_m_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18762) mov.l (%a6),%d0 # Get current a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18763) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18764) mov.l %d0,(%a6) # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18765) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18766) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18768) faddr_ind_m_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18769) mov.b &mda7_flg,SPCOND_FLG(%a6) # set "special case" flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18771) mov.l EXC_A7(%a6),%d0 # Get current a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18772) sub.l %a0,%d0 # Decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18773) mov.l %d0,EXC_A7(%a6) # Save decr value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18774) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18775) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18777) ########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18778) # Address register indirect w/ displacement: (d16, An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18779) ########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18780) faddr_ind_disp_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18781) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18782) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18783) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18785) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18786) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18788) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18790) add.l EXC_DREGS+0x8(%a6),%a0 # a0 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18791) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18793) faddr_ind_disp_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18794) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18795) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18796) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18798) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18799) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18801) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18803) add.l EXC_DREGS+0xc(%a6),%a0 # a1 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18804) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18806) faddr_ind_disp_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18807) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18808) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18809) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18811) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18812) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18814) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18816) add.l %a2,%a0 # a2 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18817) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18819) faddr_ind_disp_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18820) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18821) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18822) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18824) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18825) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18827) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18829) add.l %a3,%a0 # a3 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18830) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18832) faddr_ind_disp_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18833) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18834) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18835) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18837) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18838) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18840) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18842) add.l %a4,%a0 # a4 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18843) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18845) faddr_ind_disp_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18846) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18847) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18848) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18850) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18851) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18853) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18855) add.l %a5,%a0 # a5 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18856) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18858) faddr_ind_disp_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18859) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18860) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18861) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18863) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18864) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18866) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18868) add.l (%a6),%a0 # a6 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18869) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18871) faddr_ind_disp_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18872) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18873) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18874) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18876) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18877) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18879) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18881) add.l EXC_A7(%a6),%a0 # a7 + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18882) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18884) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18885) # Address register indirect w/ index(8-bit displacement): (d8, An, Xn) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18886) # " " " w/ " (base displacement): (bd, An, Xn) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18887) # Memory indirect postindexed: ([bd, An], Xn, od) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18888) # Memory indirect preindexed: ([bd, An, Xn], od) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18889) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18890) faddr_ind_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18891) addq.l &0x8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18892) bsr.l fetch_dreg # fetch base areg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18893) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18895) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18896) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18897) bsr.l _imem_read_word # fetch extword in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18899) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18900) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18902) mov.l (%sp)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18904) btst &0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18905) bne.w fcalc_mem_ind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18907) mov.l %d0,L_SCR1(%a6) # hold opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18909) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18910) rol.w &0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18911) andi.w &0xf,%d1 # extract index regno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18913) # count on fetch_dreg() not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18914) bsr.l fetch_dreg # fetch index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18916) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18917) mov.l L_SCR1(%a6),%d2 # fetch opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18919) btst &0xb,%d2 # is it word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18920) bne.b faii8_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18921) ext.l %d0 # sign extend word index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18922) faii8_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18923) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18924) rol.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18925) andi.l &0x3,%d1 # extract scale value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18927) lsl.l %d1,%d0 # shift index by scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18929) extb.l %d2 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18930) add.l %d2,%d0 # index + disp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18931) add.l %d0,%a0 # An + (index + disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18933) mov.l (%sp)+,%d2 # restore old d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18934) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18936) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18937) # Absolute short: (XXX).W #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18938) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18939) fabs_short:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18940) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18941) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18942) bsr.l _imem_read_word # fetch short address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18944) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18945) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18947) mov.w %d0,%a0 # return <ea> in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18948) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18950) ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18951) # Absolute long: (XXX).L #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18952) ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18953) fabs_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18954) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18955) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18956) bsr.l _imem_read_long # fetch long address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18958) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18959) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18961) mov.l %d0,%a0 # return <ea> in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18962) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18964) #######################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18965) # Program counter indirect w/ displacement: (d16, PC) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18966) #######################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18967) fpc_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18968) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18969) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18970) bsr.l _imem_read_word # fetch word displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18972) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18973) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18975) mov.w %d0,%a0 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18977) add.l EXC_EXTWPTR(%a6),%a0 # pc + d16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18979) # _imem_read_word() increased the extwptr by 2. need to adjust here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18980) subq.l &0x2,%a0 # adjust <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18981) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18983) ##########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18984) # PC indirect w/ index(8-bit displacement): (d8, PC, An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18985) # " " w/ " (base displacement): (bd, PC, An) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18986) # PC memory indirect postindexed: ([bd, PC], Xn, od) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18987) # PC memory indirect preindexed: ([bd, PC, Xn], od) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18988) ##########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18989) fpc_ind_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18990) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18991) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18992) bsr.l _imem_read_word # fetch ext word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18994) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18995) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18997) mov.l EXC_EXTWPTR(%a6),%a0 # put base in a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18998) subq.l &0x2,%a0 # adjust base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19000) btst &0x8,%d0 # is disp only 8 bits?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19001) bne.w fcalc_mem_ind # calc memory indirect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19003) mov.l %d0,L_SCR1(%a6) # store opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19005) mov.l %d0,%d1 # make extword copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19006) rol.w &0x4,%d1 # rotate reg num into place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19007) andi.w &0xf,%d1 # extract register number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19009) # count on fetch_dreg() not to alter a0...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19010) bsr.l fetch_dreg # fetch index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19012) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19013) mov.l L_SCR1(%a6),%d2 # fetch opword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19015) btst &0xb,%d2 # is index word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19016) bne.b fpii8_long # long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19017) ext.l %d0 # sign extend word index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19018) fpii8_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19019) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19020) rol.w &0x7,%d1 # rotate scale value into place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19021) andi.l &0x3,%d1 # extract scale value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19023) lsl.l %d1,%d0 # shift index by scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19025) extb.l %d2 # sign extend displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19026) add.l %d2,%d0 # disp + index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19027) add.l %d0,%a0 # An + (index + disp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19029) mov.l (%sp)+,%d2 # restore temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19030) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19032) # d2 = index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19033) # d3 = base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19034) # d4 = od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19035) # d5 = extword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19036) fcalc_mem_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19037) btst &0x6,%d0 # is the index suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19038) beq.b fcalc_index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19040) movm.l &0x3c00,-(%sp) # save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19042) mov.l %d0,%d5 # put extword in d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19043) mov.l %a0,%d3 # put base in d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19045) clr.l %d2 # yes, so index = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19046) bra.b fbase_supp_ck
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19048) # index:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19049) fcalc_index:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19050) mov.l %d0,L_SCR1(%a6) # save d0 (opword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19051) bfextu %d0{&16:&4},%d1 # fetch dreg index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19052) bsr.l fetch_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19054) movm.l &0x3c00,-(%sp) # save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19055) mov.l %d0,%d2 # put index in d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19056) mov.l L_SCR1(%a6),%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19057) mov.l %a0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19059) btst &0xb,%d5 # is index word or long?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19060) bne.b fno_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19061) ext.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19063) fno_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19064) bfextu %d5{&21:&2},%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19065) lsl.l %d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19067) # base address (passed as parameter in d3):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19068) # we clear the value here if it should actually be suppressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19069) fbase_supp_ck:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19070) btst &0x7,%d5 # is the bd suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19071) beq.b fno_base_sup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19072) clr.l %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19074) # base displacement:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19075) fno_base_sup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19076) bfextu %d5{&26:&2},%d0 # get bd size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19077) # beq.l fmovm_error # if (size == 0) it's reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19079) cmpi.b %d0,&0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19080) blt.b fno_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19081) beq.b fget_word_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19083) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19084) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19085) bsr.l _imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19087) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19088) bne.l fcea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19090) bra.b fchk_ind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19092) fget_word_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19093) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19094) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19095) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19097) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19098) bne.l fcea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19100) ext.l %d0 # sign extend bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19102) fchk_ind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19103) add.l %d0,%d3 # base += bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19105) # outer displacement:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19106) fno_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19107) bfextu %d5{&30:&2},%d0 # is od suppressed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19108) beq.w faii_bd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19110) cmpi.b %d0,&0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19111) blt.b fnull_od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19112) beq.b fword_od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19114) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19115) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19116) bsr.l _imem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19118) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19119) bne.l fcea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19121) bra.b fadd_them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19123) fword_od:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19124) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19125) addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19126) bsr.l _imem_read_word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19128) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19129) bne.l fcea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19131) ext.l %d0 # sign extend od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19132) bra.b fadd_them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19134) fnull_od:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19135) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19137) fadd_them:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19138) mov.l %d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19140) btst &0x2,%d5 # pre or post indexing?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19141) beq.b fpre_indexed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19143) mov.l %d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19144) bsr.l _dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19146) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19147) bne.w fcea_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19149) add.l %d2,%d0 # <ea> += index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19150) add.l %d4,%d0 # <ea> += od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19151) bra.b fdone_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19153) fpre_indexed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19154) add.l %d2,%d3 # preindexing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19155) mov.l %d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19156) bsr.l _dmem_read_long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19158) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19159) bne.w fcea_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19161) add.l %d4,%d0 # ea += od
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19162) bra.b fdone_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19164) faii_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19165) add.l %d2,%d3 # ea = (base + bd) + index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19166) mov.l %d3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19167) fdone_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19168) mov.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19170) movm.l (%sp)+,&0x003c # restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19171) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19173) #########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19174) fcea_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19175) mov.l %d3,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19177) movm.l (%sp)+,&0x003c # restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19178) mov.w &0x0101,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19179) bra.l iea_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19181) fcea_iacc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19182) movm.l (%sp)+,&0x003c # restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19183) bra.l iea_iacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19185) fmovm_out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19186) bsr.l restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19187) mov.w &0x00e1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19188) bra.b fmovm_err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19190) fmovm_in_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19191) bsr.l restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19192) mov.w &0x0161,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19194) fmovm_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19195) mov.l L_SCR1(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19196) bra.l iea_dacc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19198) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19199) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19200) # fmovm_ctrl(): emulate fmovm.l of control registers instr #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19201) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19202) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19203) # _imem_read_long() - read longword from memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19204) # iea_iacc() - _imem_read_long() failed; error recovery #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19205) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19206) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19207) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19208) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19209) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19210) # If _imem_read_long() doesn't fail: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19211) # USER_FPCR(a6) = new FPCR value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19212) # USER_FPSR(a6) = new FPSR value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19213) # USER_FPIAR(a6) = new FPIAR value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19214) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19215) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19216) # Decode the instruction type by looking at the extension word #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19217) # in order to see how many control registers to fetch from memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19218) # Fetch them using _imem_read_long(). If this fetch fails, exit through #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19219) # the special access error exit handler iea_iacc(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19220) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19221) # Instruction word decoding: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19222) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19223) # fmovem.l #<data>, {FPIAR&|FPCR&|FPSR} #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19224) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19225) # WORD1 WORD2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19226) # 1111 0010 00 111100 100$ $$00 0000 0000 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19227) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19228) # $$$ (100): FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19229) # (010): FPSR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19230) # (001): FPIAR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19231) # (000): FPIAR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19232) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19233) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19235) global fmovm_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19236) fmovm_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19237) mov.b EXC_EXTWORD(%a6),%d0 # fetch reg select bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19238) cmpi.b %d0,&0x9c # fpcr & fpsr & fpiar ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19239) beq.w fctrl_in_7 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19240) cmpi.b %d0,&0x98 # fpcr & fpsr ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19241) beq.w fctrl_in_6 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19242) cmpi.b %d0,&0x94 # fpcr & fpiar ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19243) beq.b fctrl_in_5 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19245) # fmovem.l #<data>, fpsr/fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19246) fctrl_in_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19247) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19248) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19249) bsr.l _imem_read_long # fetch FPSR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19251) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19252) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19254) mov.l %d0,USER_FPSR(%a6) # store new FPSR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19255) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19256) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19257) bsr.l _imem_read_long # fetch FPIAR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19259) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19260) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19262) mov.l %d0,USER_FPIAR(%a6) # store new FPIAR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19263) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19265) # fmovem.l #<data>, fpcr/fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19266) fctrl_in_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19267) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19268) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19269) bsr.l _imem_read_long # fetch FPCR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19271) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19272) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19274) mov.l %d0,USER_FPCR(%a6) # store new FPCR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19275) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19276) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19277) bsr.l _imem_read_long # fetch FPIAR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19279) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19280) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19282) mov.l %d0,USER_FPIAR(%a6) # store new FPIAR to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19283) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19285) # fmovem.l #<data>, fpcr/fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19286) fctrl_in_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19287) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19288) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19289) bsr.l _imem_read_long # fetch FPCR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19291) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19292) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19294) mov.l %d0,USER_FPCR(%a6) # store new FPCR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19295) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19296) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19297) bsr.l _imem_read_long # fetch FPSR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19299) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19300) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19302) mov.l %d0,USER_FPSR(%a6) # store new FPSR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19303) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19305) # fmovem.l #<data>, fpcr/fpsr/fpiar
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19306) fctrl_in_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19307) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19308) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19309) bsr.l _imem_read_long # fetch FPCR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19311) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19312) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19314) mov.l %d0,USER_FPCR(%a6) # store new FPCR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19315) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19316) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19317) bsr.l _imem_read_long # fetch FPSR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19319) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19320) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19322) mov.l %d0,USER_FPSR(%a6) # store new FPSR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19323) mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19324) addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19325) bsr.l _imem_read_long # fetch FPIAR from mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19327) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19328) bne.l iea_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19330) mov.l %d0,USER_FPIAR(%a6) # store new FPIAR to mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19331) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19333) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19334) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19335) # _dcalc_ea(): calc correct <ea> from <ea> stacked on exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19336) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19337) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19338) # inc_areg() - increment an address register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19339) # dec_areg() - decrement an address register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19340) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19341) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19342) # d0 = number of bytes to adjust <ea> by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19343) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19344) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19345) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19346) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19347) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19348) # "Dummy" CALCulate Effective Address: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19349) # The stacked <ea> for FP unimplemented instructions and opclass #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19350) # two packed instructions is correct with the exception of... #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19351) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19352) # 1) -(An) : The register is not updated regardless of size. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19353) # Also, for extended precision and packed, the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19354) # stacked <ea> value is 8 bytes too big #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19355) # 2) (An)+ : The register is not updated. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19356) # 3) #<data> : The upper longword of the immediate operand is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19357) # stacked b,w,l and s sizes are completely stacked. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19358) # d,x, and p are not. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19359) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19360) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19362) global _dcalc_ea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19363) _dcalc_ea:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19364) mov.l %d0, %a0 # move # bytes to %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19366) mov.b 1+EXC_OPWORD(%a6), %d0 # fetch opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19367) mov.l %d0, %d1 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19369) andi.w &0x38, %d0 # extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19370) andi.l &0x7, %d1 # extract reg field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19372) cmpi.b %d0,&0x18 # is mode (An)+ ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19373) beq.b dcea_pi # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19375) cmpi.b %d0,&0x20 # is mode -(An) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19376) beq.b dcea_pd # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19378) or.w %d1,%d0 # concat mode,reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19379) cmpi.b %d0,&0x3c # is mode #<data>?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19381) beq.b dcea_imm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19383) mov.l EXC_EA(%a6),%a0 # return <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19384) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19386) # need to set immediate data flag here since we'll need to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19387) # an imem_read to fetch this later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19388) dcea_imm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19389) mov.b &immed_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19390) lea ([USER_FPIAR,%a6],0x4),%a0 # no; return <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19391) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19393) # here, the <ea> is stacked correctly. however, we must update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19394) # address register...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19395) dcea_pi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19396) mov.l %a0,%d0 # pass amt to inc by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19397) bsr.l inc_areg # inc addr register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19399) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19400) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19402) # the <ea> is stacked correctly for all but extended and packed which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19403) # the <ea>s are 8 bytes too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19404) # it would make no sense to have a pre-decrement to a7 in supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19405) # mode so we don't even worry about this tricky case here : )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19406) dcea_pd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19407) mov.l %a0,%d0 # pass amt to dec by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19408) bsr.l dec_areg # dec addr register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19410) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19412) cmpi.b %d0,&0xc # is opsize ext or packed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19413) beq.b dcea_pd2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19414) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19415) dcea_pd2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19416) sub.l &0x8,%a0 # correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19417) mov.l %a0,EXC_EA(%a6) # put correct <ea> on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19418) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19420) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19421) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19422) # _calc_ea_fout(): calculate correct stacked <ea> for extended #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19423) # and packed data opclass 3 operations. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19424) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19425) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19426) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19427) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19428) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19429) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19430) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19431) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19432) # a0 = return correct effective address #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19433) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19434) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19435) # For opclass 3 extended and packed data operations, the <ea> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19436) # stacked for the exception is incorrect for -(an) and (an)+ addressing #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19437) # modes. Also, while we're at it, the index register itself must get #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19438) # updated. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19439) # So, for -(an), we must subtract 8 off of the stacked <ea> value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19440) # and return that value as the correct <ea> and store that value in An. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19441) # For (an)+, the stacked <ea> is correct but we must adjust An by +12. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19442) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19443) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19445) # This calc_ea is currently used to retrieve the correct <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19446) # for fmove outs of type extended and packed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19447) global _calc_ea_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19448) _calc_ea_fout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19449) mov.b 1+EXC_OPWORD(%a6),%d0 # fetch opcode word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19450) mov.l %d0,%d1 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19452) andi.w &0x38,%d0 # extract mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19453) andi.l &0x7,%d1 # extract reg field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19455) cmpi.b %d0,&0x18 # is mode (An)+ ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19456) beq.b ceaf_pi # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19458) cmpi.b %d0,&0x20 # is mode -(An) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19459) beq.w ceaf_pd # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19461) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19462) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19464) # (An)+ : extended and packed fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19465) # : stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19466) # : "An" not updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19467) ceaf_pi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19468) mov.w (tbl_ceaf_pi.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19469) mov.l EXC_EA(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19470) jmp (tbl_ceaf_pi.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19472) swbeg &0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19473) tbl_ceaf_pi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19474) short ceaf_pi0 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19475) short ceaf_pi1 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19476) short ceaf_pi2 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19477) short ceaf_pi3 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19478) short ceaf_pi4 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19479) short ceaf_pi5 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19480) short ceaf_pi6 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19481) short ceaf_pi7 - tbl_ceaf_pi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19483) ceaf_pi0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19484) addi.l &0xc,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19485) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19486) ceaf_pi1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19487) addi.l &0xc,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19488) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19489) ceaf_pi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19490) add.l &0xc,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19491) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19492) ceaf_pi3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19493) add.l &0xc,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19494) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19495) ceaf_pi4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19496) add.l &0xc,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19497) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19498) ceaf_pi5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19499) add.l &0xc,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19500) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19501) ceaf_pi6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19502) addi.l &0xc,EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19503) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19504) ceaf_pi7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19505) mov.b &mia7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19506) addi.l &0xc,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19507) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19509) # -(An) : extended and packed fmove out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19510) # : stacked <ea> = actual <ea> + 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19511) # : "An" not updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19512) ceaf_pd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19513) mov.w (tbl_ceaf_pd.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19514) mov.l EXC_EA(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19515) sub.l &0x8,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19516) sub.l &0x8,EXC_EA(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19517) jmp (tbl_ceaf_pd.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19519) swbeg &0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19520) tbl_ceaf_pd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19521) short ceaf_pd0 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19522) short ceaf_pd1 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19523) short ceaf_pd2 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19524) short ceaf_pd3 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19525) short ceaf_pd4 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19526) short ceaf_pd5 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19527) short ceaf_pd6 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19528) short ceaf_pd7 - tbl_ceaf_pd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19530) ceaf_pd0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19531) mov.l %a0,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19532) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19533) ceaf_pd1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19534) mov.l %a0,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19535) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19536) ceaf_pd2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19537) mov.l %a0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19538) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19539) ceaf_pd3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19540) mov.l %a0,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19541) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19542) ceaf_pd4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19543) mov.l %a0,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19544) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19545) ceaf_pd5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19546) mov.l %a0,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19547) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19548) ceaf_pd6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19549) mov.l %a0,EXC_A6(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19550) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19551) ceaf_pd7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19552) mov.l %a0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19553) mov.b &mda7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19554) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19556) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19557) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19558) # _load_fop(): load operand for unimplemented FP exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19559) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19560) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19561) # set_tag_x() - determine ext prec optype tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19562) # set_tag_s() - determine sgl prec optype tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19563) # set_tag_d() - determine dbl prec optype tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19564) # unnorm_fix() - convert normalized number to denorm or zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19565) # norm() - normalize a denormalized number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19566) # get_packed() - fetch a packed operand from memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19567) # _dcalc_ea() - calculate <ea>, fixing An in process #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19568) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19569) # _imem_read_{word,long}() - read from instruction memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19570) # _dmem_read() - read from data memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19571) # _dmem_read_{byte,word,long}() - read from data memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19572) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19573) # facc_in_{b,w,l,d,x}() - mem read failed; special exit point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19574) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19575) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19576) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19577) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19578) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19579) # If memory access doesn't fail: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19580) # FP_SRC(a6) = source operand in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19581) # FP_DST(a6) = destination operand in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19582) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19583) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19584) # This is called from the Unimplemented FP exception handler in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19585) # order to load the source and maybe destination operand into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19586) # FP_SRC(a6) and FP_DST(a6). If the instruction was opclass zero, load #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19587) # the source and destination from the FP register file. Set the optype #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19588) # tags for both if dyadic, one for monadic. If a number is an UNNORM, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19589) # convert it to a DENORM or a ZERO. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19590) # If the instruction is opclass two (memory->reg), then fetch #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19591) # the destination from the register file and the source operand from #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19592) # memory. Tag and fix both as above w/ opclass zero instructions. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19593) # If the source operand is byte,word,long, or single, it may be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19594) # in the data register file. If it's actually out in memory, use one of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19595) # the mem_read() routines to fetch it. If the mem_read() access returns #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19596) # a failing value, exit through the special facc_in() routine which #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19597) # will create an access error exception frame from the current exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19598) # frame. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19599) # Immediate data and regular data accesses are separated because #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19600) # if an immediate data access fails, the resulting fault status #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19601) # longword stacked for the access error exception must have the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19602) # instruction bit set. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19603) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19604) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19606) global _load_fop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19607) _load_fop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19609) # 15 13 12 10 9 7 6 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19610) # / \ / \ / \ / \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19611) # ---------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19612) # | opclass | RX | RY | EXTENSION | (2nd word of general FP instruction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19613) # ---------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19614) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19616) # bfextu EXC_CMDREG(%a6){&0:&3}, %d0 # extract opclass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19617) # cmpi.b %d0, &0x2 # which class is it? ('000,'010,'011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19618) # beq.w op010 # handle <ea> -> fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19619) # bgt.w op011 # handle fpn -> <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19621) # we're not using op011 for now...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19622) btst &0x6,EXC_CMDREG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19623) bne.b op010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19625) ############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19626) # OPCLASS '000: reg -> reg #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19627) ############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19628) op000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19629) mov.b 1+EXC_CMDREG(%a6),%d0 # fetch extension word lo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19630) btst &0x5,%d0 # testing extension bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19631) beq.b op000_src # (bit 5 == 0) => monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19632) btst &0x4,%d0 # (bit 5 == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19633) beq.b op000_dst # (bit 4 == 0) => dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19634) and.w &0x007f,%d0 # extract extension bits {6:0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19635) cmpi.w %d0,&0x0038 # is it an fcmp (dyadic) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19636) bne.b op000_src # it's an fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19638) op000_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19639) bfextu EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19640) bsr.l load_fpn2 # fetch dst fpreg into FP_DST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19642) bsr.l set_tag_x # get dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19644) cmpi.b %d0, &UNNORM # is dst fpreg an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19645) beq.b op000_dst_unnorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19646) op000_dst_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19647) mov.b %d0, DTAG(%a6) # store the dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19649) op000_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19650) bfextu EXC_CMDREG(%a6){&3:&3}, %d0 # extract src field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19651) bsr.l load_fpn1 # fetch src fpreg into FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19653) bsr.l set_tag_x # get src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19655) cmpi.b %d0, &UNNORM # is src fpreg an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19656) beq.b op000_src_unnorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19657) op000_src_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19658) mov.b %d0, STAG(%a6) # store the src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19659) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19661) op000_dst_unnorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19662) bsr.l unnorm_fix # fix the dst UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19663) bra.b op000_dst_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19664) op000_src_unnorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19665) bsr.l unnorm_fix # fix the src UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19666) bra.b op000_src_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19668) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19669) # OPCLASS '010: <ea> -> reg #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19670) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19671) op010:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19672) mov.w EXC_CMDREG(%a6),%d0 # fetch extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19673) btst &0x5,%d0 # testing extension bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19674) beq.b op010_src # (bit 5 == 0) => monadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19675) btst &0x4,%d0 # (bit 5 == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19676) beq.b op010_dst # (bit 4 == 0) => dyadic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19677) and.w &0x007f,%d0 # extract extension bits {6:0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19678) cmpi.w %d0,&0x0038 # is it an fcmp (dyadic) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19679) bne.b op010_src # it's an fcmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19681) op010_dst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19682) bfextu EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19683) bsr.l load_fpn2 # fetch dst fpreg ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19685) bsr.l set_tag_x # get dst type tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19687) cmpi.b %d0, &UNNORM # is dst fpreg an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19688) beq.b op010_dst_unnorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19689) op010_dst_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19690) mov.b %d0, DTAG(%a6) # store the dst optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19692) op010_src:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19693) bfextu EXC_CMDREG(%a6){&3:&3}, %d0 # extract src type field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19695) bfextu EXC_OPWORD(%a6){&10:&3}, %d1 # extract <ea> mode field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19696) bne.w fetch_from_mem # src op is in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19698) op010_dreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19699) clr.b STAG(%a6) # either NORM or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19700) bfextu EXC_OPWORD(%a6){&13:&3}, %d1 # extract src reg field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19702) mov.w (tbl_op010_dreg.b,%pc,%d0.w*2), %d0 # jmp based on optype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19703) jmp (tbl_op010_dreg.b,%pc,%d0.w*1) # fetch src from dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19705) op010_dst_unnorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19706) bsr.l unnorm_fix # fix the dst UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19707) bra.b op010_dst_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19709) swbeg &0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19710) tbl_op010_dreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19711) short opd_long - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19712) short opd_sgl - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19713) short tbl_op010_dreg - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19714) short tbl_op010_dreg - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19715) short opd_word - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19716) short tbl_op010_dreg - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19717) short opd_byte - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19718) short tbl_op010_dreg - tbl_op010_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19720) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19721) # LONG: can be either NORM or ZERO...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19722) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19723) opd_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19724) bsr.l fetch_dreg # fetch long in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19725) fmov.l %d0, %fp0 # load a long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19726) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19727) fbeq.w opd_long_zero # long is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19728) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19729) opd_long_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19730) mov.b &ZERO, STAG(%a6) # set ZERO optype flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19731) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19733) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19734) # WORD: can be either NORM or ZERO...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19735) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19736) opd_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19737) bsr.l fetch_dreg # fetch word in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19738) fmov.w %d0, %fp0 # load a word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19739) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19740) fbeq.w opd_word_zero # WORD is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19741) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19742) opd_word_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19743) mov.b &ZERO, STAG(%a6) # set ZERO optype flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19744) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19746) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19747) # BYTE: can be either NORM or ZERO...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19748) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19749) opd_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19750) bsr.l fetch_dreg # fetch word in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19751) fmov.b %d0, %fp0 # load a byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19752) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19753) fbeq.w opd_byte_zero # byte is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19754) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19755) opd_byte_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19756) mov.b &ZERO, STAG(%a6) # set ZERO optype flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19757) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19759) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19760) # SGL: can be either NORM, DENORM, ZERO, INF, QNAN or SNAN but not UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19761) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19762) # separate SNANs and DENORMs so they can be loaded w/ special care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19763) # all others can simply be moved "in" using fmove.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19764) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19765) opd_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19766) bsr.l fetch_dreg # fetch sgl in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19767) mov.l %d0,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19769) lea L_SCR1(%a6), %a0 # pass: ptr to the sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19770) bsr.l set_tag_s # determine sgl type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19771) mov.b %d0, STAG(%a6) # save the src tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19773) cmpi.b %d0, &SNAN # is it an SNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19774) beq.w get_sgl_snan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19776) cmpi.b %d0, &DENORM # is it a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19777) beq.w get_sgl_denorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19779) fmov.s (%a0), %fp0 # no, so can load it regular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19780) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19781) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19783) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19785) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19786) # fetch_from_mem(): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19787) # - src is out in memory. must: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19788) # (1) calc ea - must read AFTER you know the src type since #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19789) # if the ea is -() or ()+, need to know # of bytes. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19790) # (2) read it in from either user or supervisor space #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19791) # (3) if (b || w || l) then simply read in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19792) # if (s || d || x) then check for SNAN,UNNORM,DENORM #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19793) # if (packed) then punt for now #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19794) # INPUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19795) # %d0 : src type field #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19796) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19797) fetch_from_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19798) clr.b STAG(%a6) # either NORM or ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19800) mov.w (tbl_fp_type.b,%pc,%d0.w*2), %d0 # index by src type field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19801) jmp (tbl_fp_type.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19803) swbeg &0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19804) tbl_fp_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19805) short load_long - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19806) short load_sgl - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19807) short load_ext - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19808) short load_packed - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19809) short load_word - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19810) short load_dbl - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19811) short load_byte - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19812) short tbl_fp_type - tbl_fp_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19814) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19815) # load a LONG into %fp0: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19816) # -number can't fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19817) # (1) calc ea #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19818) # (2) read 4 bytes into L_SCR1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19819) # (3) fmov.l into %fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19820) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19821) load_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19822) movq.l &0x4, %d0 # pass: 4 (bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19823) bsr.l _dcalc_ea # calc <ea>; <ea> in %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19825) cmpi.b SPCOND_FLG(%a6),&immed_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19826) beq.b load_long_immed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19828) bsr.l _dmem_read_long # fetch src operand from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19830) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19831) bne.l facc_in_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19833) load_long_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19834) fmov.l %d0, %fp0 # read into %fp0;convert to xprec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19835) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19837) fbeq.w load_long_zero # src op is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19838) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19839) load_long_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19840) mov.b &ZERO, STAG(%a6) # set optype tag to ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19841) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19843) load_long_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19844) bsr.l _imem_read_long # fetch src operand immed data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19846) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19847) bne.l funimp_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19848) bra.b load_long_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19850) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19851) # load a WORD into %fp0: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19852) # -number can't fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19853) # (1) calc ea #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19854) # (2) read 2 bytes into L_SCR1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19855) # (3) fmov.w into %fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19856) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19857) load_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19858) movq.l &0x2, %d0 # pass: 2 (bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19859) bsr.l _dcalc_ea # calc <ea>; <ea> in %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19861) cmpi.b SPCOND_FLG(%a6),&immed_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19862) beq.b load_word_immed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19864) bsr.l _dmem_read_word # fetch src operand from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19866) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19867) bne.l facc_in_w # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19869) load_word_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19870) fmov.w %d0, %fp0 # read into %fp0;convert to xprec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19871) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19873) fbeq.w load_word_zero # src op is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19874) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19875) load_word_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19876) mov.b &ZERO, STAG(%a6) # set optype tag to ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19877) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19879) load_word_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19880) bsr.l _imem_read_word # fetch src operand immed data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19882) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19883) bne.l funimp_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19884) bra.b load_word_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19886) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19887) # load a BYTE into %fp0: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19888) # -number can't fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19889) # (1) calc ea #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19890) # (2) read 1 byte into L_SCR1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19891) # (3) fmov.b into %fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19892) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19893) load_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19894) movq.l &0x1, %d0 # pass: 1 (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19895) bsr.l _dcalc_ea # calc <ea>; <ea> in %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19897) cmpi.b SPCOND_FLG(%a6),&immed_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19898) beq.b load_byte_immed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19900) bsr.l _dmem_read_byte # fetch src operand from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19902) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19903) bne.l facc_in_b # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19905) load_byte_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19906) fmov.b %d0, %fp0 # read into %fp0;convert to xprec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19907) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19909) fbeq.w load_byte_zero # src op is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19910) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19911) load_byte_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19912) mov.b &ZERO, STAG(%a6) # set optype tag to ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19913) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19915) load_byte_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19916) bsr.l _imem_read_word # fetch src operand immed data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19918) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19919) bne.l funimp_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19920) bra.b load_byte_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19922) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19923) # load a SGL into %fp0: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19924) # -number can't fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19925) # (1) calc ea #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19926) # (2) read 4 bytes into L_SCR1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19927) # (3) fmov.s into %fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19928) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19929) load_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19930) movq.l &0x4, %d0 # pass: 4 (bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19931) bsr.l _dcalc_ea # calc <ea>; <ea> in %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19933) cmpi.b SPCOND_FLG(%a6),&immed_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19934) beq.b load_sgl_immed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19936) bsr.l _dmem_read_long # fetch src operand from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19937) mov.l %d0, L_SCR1(%a6) # store src op on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19939) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19940) bne.l facc_in_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19942) load_sgl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19943) lea L_SCR1(%a6), %a0 # pass: ptr to sgl src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19944) bsr.l set_tag_s # determine src type tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19945) mov.b %d0, STAG(%a6) # save src optype tag on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19947) cmpi.b %d0, &DENORM # is it a sgl DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19948) beq.w get_sgl_denorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19950) cmpi.b %d0, &SNAN # is it a sgl SNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19951) beq.w get_sgl_snan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19953) fmov.s L_SCR1(%a6), %fp0 # read into %fp0;convert to xprec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19954) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19955) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19957) load_sgl_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19958) bsr.l _imem_read_long # fetch src operand immed data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19960) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19961) bne.l funimp_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19962) bra.b load_sgl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19964) # must convert sgl denorm format to an Xprec denorm fmt suitable for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19965) # normalization...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19966) # %a0 : points to sgl denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19967) get_sgl_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19968) clr.w FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19969) bfextu (%a0){&9:&23}, %d0 # fetch sgl hi(_mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19970) lsl.l &0x8, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19971) mov.l %d0, FP_SRC_HI(%a6) # set ext hi(_mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19972) clr.l FP_SRC_LO(%a6) # set ext lo(_mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19974) clr.w FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19975) btst &0x7, (%a0) # is sgn bit set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19976) beq.b sgl_dnrm_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19977) bset &0x7, FP_SRC_EX(%a6) # set sgn of xprec value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19979) sgl_dnrm_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19980) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19981) bsr.l norm # normalize number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19982) mov.w &0x3f81, %d1 # xprec exp = 0x3f81
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19983) sub.w %d0, %d1 # exp = 0x3f81 - shft amt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19984) or.w %d1, FP_SRC_EX(%a6) # {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19986) mov.b &NORM, STAG(%a6) # fix src type tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19987) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19989) # convert sgl to ext SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19990) # %a0 : points to sgl SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19991) get_sgl_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19992) mov.w &0x7fff, FP_SRC_EX(%a6) # set exp of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19993) bfextu (%a0){&9:&23}, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19994) lsl.l &0x8, %d0 # extract and insert hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19995) mov.l %d0, FP_SRC_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19996) clr.l FP_SRC_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19998) btst &0x7, (%a0) # see if sign of SNAN is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19999) beq.b no_sgl_snan_sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20000) bset &0x7, FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20001) no_sgl_snan_sgn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20002) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20004) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20005) # load a DBL into %fp0: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20006) # -number can't fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20007) # (1) calc ea #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20008) # (2) read 8 bytes into L_SCR(1,2)#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20009) # (3) fmov.d into %fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20010) #########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20011) load_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20012) movq.l &0x8, %d0 # pass: 8 (bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20013) bsr.l _dcalc_ea # calc <ea>; <ea> in %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20015) cmpi.b SPCOND_FLG(%a6),&immed_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20016) beq.b load_dbl_immed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20018) lea L_SCR1(%a6), %a1 # pass: ptr to input dbl tmp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20019) movq.l &0x8, %d0 # pass: # bytes to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20020) bsr.l _dmem_read # fetch src operand from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20022) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20023) bne.l facc_in_d # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20025) load_dbl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20026) lea L_SCR1(%a6), %a0 # pass: ptr to input dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20027) bsr.l set_tag_d # determine src type tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20028) mov.b %d0, STAG(%a6) # set src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20030) cmpi.b %d0, &DENORM # is it a dbl DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20031) beq.w get_dbl_denorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20033) cmpi.b %d0, &SNAN # is it a dbl SNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20034) beq.w get_dbl_snan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20036) fmov.d L_SCR1(%a6), %fp0 # read into %fp0;convert to xprec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20037) fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20038) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20040) load_dbl_immed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20041) lea L_SCR1(%a6), %a1 # pass: ptr to input dbl tmp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20042) movq.l &0x8, %d0 # pass: # bytes to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20043) bsr.l _imem_read # fetch src operand from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20045) tst.l %d1 # did ifetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20046) bne.l funimp_iacc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20047) bra.b load_dbl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20049) # must convert dbl denorm format to an Xprec denorm fmt suitable for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20050) # normalization...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20051) # %a0 : loc. of dbl denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20052) get_dbl_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20053) clr.w FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20054) bfextu (%a0){&12:&31}, %d0 # fetch hi(_mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20055) mov.l %d0, FP_SRC_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20056) bfextu 4(%a0){&11:&21}, %d0 # fetch lo(_mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20057) mov.l &0xb, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20058) lsl.l %d1, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20059) mov.l %d0, FP_SRC_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20061) btst &0x7, (%a0) # is sgn bit set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20062) beq.b dbl_dnrm_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20063) bset &0x7, FP_SRC_EX(%a6) # set sgn of xprec value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20065) dbl_dnrm_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20066) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20067) bsr.l norm # normalize number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20068) mov.w &0x3c01, %d1 # xprec exp = 0x3c01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20069) sub.w %d0, %d1 # exp = 0x3c01 - shft amt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20070) or.w %d1, FP_SRC_EX(%a6) # {sgn,exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20072) mov.b &NORM, STAG(%a6) # fix src type tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20073) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20075) # convert dbl to ext SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20076) # %a0 : points to dbl SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20077) get_dbl_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20078) mov.w &0x7fff, FP_SRC_EX(%a6) # set exp of SNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20080) bfextu (%a0){&12:&31}, %d0 # fetch hi(_mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20081) mov.l %d0, FP_SRC_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20082) bfextu 4(%a0){&11:&21}, %d0 # fetch lo(_mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20083) mov.l &0xb, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20084) lsl.l %d1, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20085) mov.l %d0, FP_SRC_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20087) btst &0x7, (%a0) # see if sign of SNAN is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20088) beq.b no_dbl_snan_sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20089) bset &0x7, FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20090) no_dbl_snan_sgn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20091) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20093) #################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20094) # load a Xprec into %fp0: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20095) # -number can't fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20096) # (1) calc ea #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20097) # (2) read 12 bytes into L_SCR(1,2) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20098) # (3) fmov.x into %fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20099) #################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20100) load_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20101) mov.l &0xc, %d0 # pass: 12 (bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20102) bsr.l _dcalc_ea # calc <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20104) lea FP_SRC(%a6), %a1 # pass: ptr to input ext tmp space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20105) mov.l &0xc, %d0 # pass: # of bytes to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20106) bsr.l _dmem_read # fetch src operand from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20108) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20109) bne.l facc_in_x # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20111) lea FP_SRC(%a6), %a0 # pass: ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20112) bsr.l set_tag_x # determine src type tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20114) cmpi.b %d0, &UNNORM # is the src op an UNNORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20115) beq.b load_ext_unnorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20117) mov.b %d0, STAG(%a6) # store the src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20118) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20120) load_ext_unnorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20121) bsr.l unnorm_fix # fix the src UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20122) mov.b %d0, STAG(%a6) # store the src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20123) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20125) #################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20126) # load a packed into %fp0: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20127) # -number can't fault #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20128) # (1) calc ea #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20129) # (2) read 12 bytes into L_SCR(1,2,3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20130) # (3) fmov.x into %fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20131) #################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20132) load_packed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20133) bsr.l get_packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20135) lea FP_SRC(%a6),%a0 # pass ptr to src op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20136) bsr.l set_tag_x # determine src type tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20137) cmpi.b %d0,&UNNORM # is the src op an UNNORM ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20138) beq.b load_packed_unnorm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20140) mov.b %d0,STAG(%a6) # store the src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20141) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20143) load_packed_unnorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20144) bsr.l unnorm_fix # fix the UNNORM ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20145) mov.b %d0,STAG(%a6) # store the src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20146) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20148) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20149) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20150) # fout(): move from fp register to memory or data register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20151) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20152) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20153) # _round() - needed to create EXOP for sgl/dbl precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20154) # norm() - needed to create EXOP for extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20155) # ovf_res() - create default overflow result for sgl/dbl precision#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20156) # unf_res() - create default underflow result for sgl/dbl prec. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20157) # dst_dbl() - create rounded dbl precision result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20158) # dst_sgl() - create rounded sgl precision result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20159) # fetch_dreg() - fetch dynamic k-factor reg for packed. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20160) # bindec() - convert FP binary number to packed number. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20161) # _mem_write() - write data to memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20162) # _mem_write2() - write data to memory unless supv mode -(a7) exc.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20163) # _dmem_write_{byte,word,long}() - write data to memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20164) # store_dreg_{b,w,l}() - store data to data register file. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20165) # facc_out_{b,w,l,d,x}() - data access error occurred. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20166) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20167) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20168) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20169) # d0 = round prec,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20170) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20171) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20172) # fp0 : intermediate underflow or overflow result if #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20173) # OVFL/UNFL occurred for a sgl or dbl operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20174) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20175) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20176) # This routine is accessed by many handlers that need to do an #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20177) # opclass three move of an operand out to memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20178) # Decode an fmove out (opclass 3) instruction to determine if #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20179) # 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 20180) # register or memory. The algorithm uses a standard "fmove" to create #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20181) # the rounded result. Also, since exceptions are disabled, this also #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20182) # create the correct OPERR default result if appropriate. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20183) # For sgl or dbl precision, overflow or underflow can occur. If #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20184) # either occurs and is enabled, the EXOP. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20185) # For extended precision, the stacked <ea> must be fixed along #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20186) # w/ the address index register as appropriate w/ _calc_ea_fout(). If #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20187) # the source is a denorm and if underflow is enabled, an EXOP must be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20188) # created. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20189) # For packed, the k-factor must be fetched from the instruction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20190) # word or a data register. The <ea> must be fixed as w/ extended #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20191) # precision. Then, bindec() is called to create the appropriate #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20192) # packed result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20193) # If at any time an access error is flagged by one of the move- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20194) # to-memory routines, then a special exit must be made so that the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20195) # access error can be handled properly. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20196) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20197) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20199) global fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20200) fout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20201) bfextu EXC_CMDREG(%a6){&3:&3},%d1 # extract dst fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20202) mov.w (tbl_fout.b,%pc,%d1.w*2),%a1 # use as index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20203) jmp (tbl_fout.b,%pc,%a1) # jump to routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20205) swbeg &0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20206) tbl_fout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20207) short fout_long - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20208) short fout_sgl - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20209) short fout_ext - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20210) short fout_pack - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20211) short fout_word - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20212) short fout_dbl - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20213) short fout_byte - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20214) short fout_pack - tbl_fout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20216) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20217) # fmove.b out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20218) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20220) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20221) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20222) fout_byte:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20223) tst.b STAG(%a6) # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20224) bne.b fout_byte_denorm # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20226) fmovm.x SRC(%a0),&0x80 # load value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20228) fout_byte_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20229) fmov.l %d0,%fpcr # insert rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20231) fmov.b %fp0,%d0 # exec move out w/ correct rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20233) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20234) fmov.l %fpsr,%d1 # fetch FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20235) or.w %d1,2+USER_FPSR(%a6) # save new exc,accrued bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20237) mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20238) andi.b &0x38,%d1 # is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20239) beq.b fout_byte_dn # must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20241) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20242) bsr.l _dmem_write_byte # write byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20244) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20245) bne.l facc_out_b # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20247) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20249) fout_byte_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20250) mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20251) andi.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20252) bsr.l store_dreg_b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20253) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20255) fout_byte_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20256) mov.l SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20257) andi.l &0x80000000,%d1 # keep DENORM sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20258) ori.l &0x00800000,%d1 # make smallest sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20259) fmov.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20260) bra.b fout_byte_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20262) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20263) # fmove.w out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20264) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20266) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20267) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20268) fout_word:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20269) tst.b STAG(%a6) # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20270) bne.b fout_word_denorm # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20272) fmovm.x SRC(%a0),&0x80 # load value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20274) fout_word_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20275) fmov.l %d0,%fpcr # insert rnd prec:mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20277) fmov.w %fp0,%d0 # exec move out w/ correct rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20279) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20280) fmov.l %fpsr,%d1 # fetch FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20281) or.w %d1,2+USER_FPSR(%a6) # save new exc,accrued bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20283) mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20284) andi.b &0x38,%d1 # is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20285) beq.b fout_word_dn # must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20287) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20288) bsr.l _dmem_write_word # write word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20290) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20291) bne.l facc_out_w # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20293) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20295) fout_word_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20296) mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20297) andi.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20298) bsr.l store_dreg_w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20299) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20301) fout_word_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20302) mov.l SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20303) andi.l &0x80000000,%d1 # keep DENORM sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20304) ori.l &0x00800000,%d1 # make smallest sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20305) fmov.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20306) bra.b fout_word_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20308) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20309) # fmove.l out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20310) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20312) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20313) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20314) fout_long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20315) tst.b STAG(%a6) # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20316) bne.b fout_long_denorm # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20318) fmovm.x SRC(%a0),&0x80 # load value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20320) fout_long_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20321) fmov.l %d0,%fpcr # insert rnd prec:mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20323) fmov.l %fp0,%d0 # exec move out w/ correct rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20325) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20326) fmov.l %fpsr,%d1 # fetch FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20327) or.w %d1,2+USER_FPSR(%a6) # save new exc,accrued bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20329) fout_long_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20330) mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20331) andi.b &0x38,%d1 # is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20332) beq.b fout_long_dn # must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20334) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20335) bsr.l _dmem_write_long # write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20337) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20338) bne.l facc_out_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20340) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20342) fout_long_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20343) mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20344) andi.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20345) bsr.l store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20346) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20348) fout_long_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20349) mov.l SRC_EX(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20350) andi.l &0x80000000,%d1 # keep DENORM sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20351) ori.l &0x00800000,%d1 # make smallest sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20352) fmov.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20353) bra.b fout_long_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20355) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20356) # fmove.x out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20357) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20359) # Only "Unimplemented Data Type" exceptions enter here. The operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20360) # is either a DENORM or a NORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20361) # The DENORM causes an Underflow exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20362) fout_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20364) # we copy the extended precision result to FP_SCR0 so that the reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20365) # 16-bit field gets zeroed. we do this since we promise not to disturb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20366) # what's at SRC(a0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20367) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20368) clr.w 2+FP_SCR0_EX(%a6) # clear reserved field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20369) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20370) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20372) fmovm.x SRC(%a0),&0x80 # return result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20374) bsr.l _calc_ea_fout # fix stacked <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20376) mov.l %a0,%a1 # pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20377) lea FP_SCR0(%a6),%a0 # pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20378) mov.l &0xc,%d0 # pass: opsize is 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20380) # we must not yet write the extended precision data to the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20381) # in the pre-decrement case from supervisor mode or else we'll corrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20382) # 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 20383) cmpi.b SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20384) beq.b fout_ext_a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20386) bsr.l _dmem_write # write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20388) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20389) bne.w fout_ext_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20391) tst.b STAG(%a6) # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20392) bne.b fout_ext_denorm # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20393) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20395) # the number is a DENORM. must set the underflow exception bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20396) fout_ext_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20397) bset &unfl_bit,FPSR_EXCEPT(%a6) # set underflow exc bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20399) mov.b FPCR_ENABLE(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20400) andi.b &0x0a,%d0 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20401) bne.b fout_ext_exc # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20402) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20404) # we don't want to do the write if the exception occurred in supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20405) # so _mem_write2() handles this for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20406) fout_ext_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20407) bsr.l _mem_write2 # write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20409) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20410) bne.w fout_ext_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20412) tst.b STAG(%a6) # is operand normalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20413) bne.b fout_ext_denorm # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20414) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20416) fout_ext_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20417) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20418) bsr.l norm # normalize the mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20419) neg.w %d0 # new exp = -(shft amt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20420) andi.w &0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20421) andi.w &0x8000,FP_SCR0_EX(%a6) # keep only old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20422) or.w %d0,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20423) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20424) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20426) fout_ext_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20427) mov.l EXC_A6(%a6),(%a6) # fix stacked a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20428) bra.l facc_out_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20430) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20431) # fmove.s out ###########################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20432) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20433) fout_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20434) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20435) ori.b &s_mode*0x10,%d0 # insert sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20436) mov.l %d0,L_SCR3(%a6) # save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20438) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20439) # operand is a normalized number. first, we check to see if the move out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20440) # would cause either an underflow or overflow. these cases are handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20441) # separately. otherwise, set the FPCR to the proper rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20442) # execute the move.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20443) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20444) mov.w SRC_EX(%a0),%d0 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20445) andi.w &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20447) cmpi.w %d0,&SGL_HI # will operand overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20448) bgt.w fout_sgl_ovfl # yes; go handle OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20449) beq.w fout_sgl_may_ovfl # maybe; go handle possible OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20450) cmpi.w %d0,&SGL_LO # will operand underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20451) blt.w fout_sgl_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20453) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20454) # NORMs(in range) can be stored out by a simple "fmov.s"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20455) # Unnormalized inputs can come through this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20456) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20457) fout_sgl_exg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20458) fmovm.x SRC(%a0),&0x80 # fetch fop from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20460) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20461) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20463) fmov.s %fp0,%d0 # store does convert and round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20465) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20466) fmov.l %fpsr,%d1 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20468) or.w %d1,2+USER_FPSR(%a6) # set possible inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20470) fout_sgl_exg_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20471) mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20472) andi.b &0x38,%d1 # is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20473) beq.b fout_sgl_exg_write_dn # must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20475) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20476) bsr.l _dmem_write_long # write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20478) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20479) bne.l facc_out_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20481) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20483) fout_sgl_exg_write_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20484) mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20485) andi.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20486) bsr.l store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20487) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20489) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20490) # here, we know that the operand would UNFL if moved out to single prec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20491) # so, denorm and round and then use generic store single routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20492) # write the value to memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20493) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20494) fout_sgl_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20495) bset &unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20497) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20498) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20499) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20500) mov.l %a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20502) clr.l %d0 # pass: S.F. = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20504) cmpi.b STAG(%a6),&DENORM # fetch src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20505) bne.b fout_sgl_unfl_cont # let DENORMs fall through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20507) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20508) bsr.l norm # normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20510) fout_sgl_unfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20511) lea FP_SCR0(%a6),%a0 # pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20512) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20513) bsr.l unf_res # calc default underflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20515) lea FP_SCR0(%a6),%a0 # pass: ptr to fop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20516) bsr.l dst_sgl # convert to single prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20518) mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20519) andi.b &0x38,%d1 # is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20520) beq.b fout_sgl_unfl_dn # must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20522) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20523) bsr.l _dmem_write_long # write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20525) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20526) bne.l facc_out_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20528) bra.b fout_sgl_unfl_chkexc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20530) fout_sgl_unfl_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20531) mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20532) andi.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20533) bsr.l store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20535) fout_sgl_unfl_chkexc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20536) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20537) andi.b &0x0a,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20538) bne.w fout_sd_exc_unfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20539) addq.l &0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20540) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20542) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20543) # it's definitely an overflow so call ovf_res to get the correct answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20544) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20545) fout_sgl_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20546) tst.b 3+SRC_HI(%a0) # is result inexact?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20547) bne.b fout_sgl_ovfl_inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20548) tst.l SRC_LO(%a0) # is result inexact?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20549) bne.b fout_sgl_ovfl_inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20550) ori.w &ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20551) bra.b fout_sgl_ovfl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20552) fout_sgl_ovfl_inex2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20553) ori.w &ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20555) fout_sgl_ovfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20556) mov.l %a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20558) # call ovf_res() w/ sgl prec and the correct rnd mode to create the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20559) # overflow result. DON'T save the returned ccodes from ovf_res() since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20560) # fmove out doesn't alter them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20561) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20562) smi %d1 # set if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20563) mov.l L_SCR3(%a6),%d0 # pass: sgl prec,rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20564) bsr.l ovf_res # calc OVFL result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20565) fmovm.x (%a0),&0x80 # load default overflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20566) fmov.s %fp0,%d0 # store to single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20568) mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20569) andi.b &0x38,%d1 # is mode == 0? (Dreg dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20570) beq.b fout_sgl_ovfl_dn # must save to integer regfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20572) mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20573) bsr.l _dmem_write_long # write long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20575) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20576) bne.l facc_out_l # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20578) bra.b fout_sgl_ovfl_chkexc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20580) fout_sgl_ovfl_dn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20581) mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20582) andi.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20583) bsr.l store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20585) fout_sgl_ovfl_chkexc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20586) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20587) andi.b &0x0a,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20588) bne.w fout_sd_exc_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20589) addq.l &0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20590) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20592) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20593) # move out MAY overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20594) # (1) force the exp to 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20595) # (2) do a move w/ appropriate rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20596) # (3) if exp still equals zero, then insert original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20597) # for the correct result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20598) # if exp now equals one, then it overflowed so call ovf_res.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20599) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20600) fout_sgl_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20601) mov.w SRC_EX(%a0),%d1 # fetch current sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20602) andi.w &0x8000,%d1 # keep it,clear exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20603) ori.w &0x3fff,%d1 # insert exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20604) mov.w %d1,FP_SCR0_EX(%a6) # insert scaled exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20605) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20606) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20608) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20610) fmov.x FP_SCR0(%a6),%fp0 # force fop to be rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20611) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20613) fabs.x %fp0 # need absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20614) fcmp.b %fp0,&0x2 # did exponent increase?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20615) fblt.w fout_sgl_exg # no; go finish NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20616) bra.w fout_sgl_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20618) ################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20620) fout_sd_exc_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20621) mov.l (%sp)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20623) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20624) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20625) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20627) cmpi.b STAG(%a6),&DENORM # was src a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20628) bne.b fout_sd_exc_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20630) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20631) bsr.l norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20632) neg.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20633) andi.w &0x7fff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20634) bfins %d0,FP_SCR0_EX(%a6){&1:&15}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20635) bra.b fout_sd_exc_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20637) fout_sd_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20638) fout_sd_exc_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20639) mov.l (%sp)+,%a0 # restore a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20641) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20642) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20643) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20645) fout_sd_exc_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20646) bclr &0x7,FP_SCR0_EX(%a6) # clear sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20647) sne.b 2+FP_SCR0_EX(%a6) # set internal sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20648) lea FP_SCR0(%a6),%a0 # pass: ptr to DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20650) mov.b 3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20651) lsr.b &0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20652) andi.w &0x0c,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20653) swap %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20654) mov.b 3+L_SCR3(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20655) lsr.b &0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20656) andi.w &0x03,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20657) clr.l %d0 # pass: zero g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20658) bsr.l _round # round the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20660) tst.b 2+FP_SCR0_EX(%a6) # is EXOP negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20661) beq.b fout_sd_exc_done # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20662) bset &0x7,FP_SCR0_EX(%a6) # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20664) fout_sd_exc_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20665) fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20666) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20668) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20669) # fmove.d out ###################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20670) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20671) fout_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20672) andi.b &0x30,%d0 # clear rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20673) ori.b &d_mode*0x10,%d0 # insert dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20674) mov.l %d0,L_SCR3(%a6) # save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20676) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20677) # operand is a normalized number. first, we check to see if the move out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20678) # would cause either an underflow or overflow. these cases are handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20679) # separately. otherwise, set the FPCR to the proper rounding mode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20680) # execute the move.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20681) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20682) mov.w SRC_EX(%a0),%d0 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20683) andi.w &0x7fff,%d0 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20685) cmpi.w %d0,&DBL_HI # will operand overflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20686) bgt.w fout_dbl_ovfl # yes; go handle OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20687) beq.w fout_dbl_may_ovfl # maybe; go handle possible OVFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20688) cmpi.w %d0,&DBL_LO # will operand underflow?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20689) blt.w fout_dbl_unfl # yes; go handle underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20691) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20692) # NORMs(in range) can be stored out by a simple "fmov.d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20693) # Unnormalized inputs can come through this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20694) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20695) fout_dbl_exg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20696) fmovm.x SRC(%a0),&0x80 # fetch fop from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20698) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20699) fmov.l &0x0,%fpsr # clear FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20701) fmov.d %fp0,L_SCR1(%a6) # store does convert and round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20703) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20704) fmov.l %fpsr,%d0 # save FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20706) or.w %d0,2+USER_FPSR(%a6) # set possible inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20708) mov.l EXC_EA(%a6),%a1 # pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20709) lea L_SCR1(%a6),%a0 # pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20710) movq.l &0x8,%d0 # pass: opsize is 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20711) bsr.l _dmem_write # store dbl fop to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20713) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20714) bne.l facc_out_d # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20716) rts # no; so we're finished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20718) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20719) # here, we know that the operand would UNFL if moved out to double prec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20720) # so, denorm and round and then use generic store double routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20721) # write the value to memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20722) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20723) fout_dbl_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20724) bset &unfl_bit,FPSR_EXCEPT(%a6) # set UNFL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20726) mov.w SRC_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20727) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20728) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20729) mov.l %a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20731) clr.l %d0 # pass: S.F. = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20733) cmpi.b STAG(%a6),&DENORM # fetch src optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20734) bne.b fout_dbl_unfl_cont # let DENORMs fall through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20736) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20737) bsr.l norm # normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20739) fout_dbl_unfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20740) lea FP_SCR0(%a6),%a0 # pass: ptr to operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20741) mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20742) bsr.l unf_res # calc default underflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20744) lea FP_SCR0(%a6),%a0 # pass: ptr to fop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20745) bsr.l dst_dbl # convert to single prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20746) mov.l %d0,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20747) mov.l %d1,L_SCR2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20749) mov.l EXC_EA(%a6),%a1 # pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20750) lea L_SCR1(%a6),%a0 # pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20751) movq.l &0x8,%d0 # pass: opsize is 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20752) bsr.l _dmem_write # store dbl fop to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20754) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20755) bne.l facc_out_d # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20757) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20758) andi.b &0x0a,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20759) bne.w fout_sd_exc_unfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20760) addq.l &0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20761) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20763) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20764) # it's definitely an overflow so call ovf_res to get the correct answer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20765) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20766) fout_dbl_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20767) mov.w 2+SRC_LO(%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20768) andi.w &0x7ff,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20769) bne.b fout_dbl_ovfl_inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20771) ori.w &ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20772) bra.b fout_dbl_ovfl_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20773) fout_dbl_ovfl_inex2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20774) ori.w &ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20776) fout_dbl_ovfl_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20777) mov.l %a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20779) # call ovf_res() w/ dbl prec and the correct rnd mode to create the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20780) # overflow result. DON'T save the returned ccodes from ovf_res() since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20781) # fmove out doesn't alter them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20782) tst.b SRC_EX(%a0) # is operand negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20783) smi %d1 # set if so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20784) mov.l L_SCR3(%a6),%d0 # pass: dbl prec,rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20785) bsr.l ovf_res # calc OVFL result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20786) fmovm.x (%a0),&0x80 # load default overflow result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20787) fmov.d %fp0,L_SCR1(%a6) # store to double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20789) mov.l EXC_EA(%a6),%a1 # pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20790) lea L_SCR1(%a6),%a0 # pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20791) movq.l &0x8,%d0 # pass: opsize is 8 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20792) bsr.l _dmem_write # store dbl fop to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20794) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20795) bne.l facc_out_d # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20797) mov.b FPCR_ENABLE(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20798) andi.b &0x0a,%d1 # is UNFL or INEX enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20799) bne.w fout_sd_exc_ovfl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20800) addq.l &0x4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20801) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20803) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20804) # move out MAY overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20805) # (1) force the exp to 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20806) # (2) do a move w/ appropriate rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20807) # (3) if exp still equals zero, then insert original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20808) # for the correct result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20809) # if exp now equals one, then it overflowed so call ovf_res.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20810) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20811) fout_dbl_may_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20812) mov.w SRC_EX(%a0),%d1 # fetch current sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20813) andi.w &0x8000,%d1 # keep it,clear exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20814) ori.w &0x3fff,%d1 # insert exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20815) mov.w %d1,FP_SCR0_EX(%a6) # insert scaled exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20816) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20817) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20819) fmov.l L_SCR3(%a6),%fpcr # set FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20821) fmov.x FP_SCR0(%a6),%fp0 # force fop to be rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20822) fmov.l &0x0,%fpcr # clear FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20824) fabs.x %fp0 # need absolute value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20825) fcmp.b %fp0,&0x2 # did exponent increase?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20826) fblt.w fout_dbl_exg # no; go finish NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20827) bra.w fout_dbl_ovfl # yes; go handle overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20829) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20830) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20831) # dst_dbl(): create double precision value from extended prec. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20832) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20833) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20834) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20835) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20836) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20837) # a0 = pointer to source operand in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20838) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20839) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20840) # d0 = hi(double precision result) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20841) # d1 = lo(double precision result) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20842) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20843) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20844) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20845) # Changes extended precision to double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20846) # Note: no attempt is made to round the extended value to double. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20847) # dbl_sign = ext_sign #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20848) # dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20849) # get rid of ext integer bit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20850) # dbl_mant = ext_mant{62:12} #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20851) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20852) # --------------- --------------- --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20853) # extended -> |s| exp | |1| ms mant | | ls mant | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20854) # --------------- --------------- --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20855) # 95 64 63 62 32 31 11 0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20856) # | | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20857) # | | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20858) # | | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20859) # v v #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20860) # --------------- --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20861) # double -> |s|exp| mant | | mant | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20862) # --------------- --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20863) # 63 51 32 31 0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20864) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20865) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20867) dst_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20868) clr.l %d0 # clear d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20869) mov.w FTEMP_EX(%a0),%d0 # get exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20870) subi.w &EXT_BIAS,%d0 # subtract extended precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20871) addi.w &DBL_BIAS,%d0 # add double precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20872) tst.b FTEMP_HI(%a0) # is number a denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20873) bmi.b dst_get_dupper # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20874) subq.w &0x1,%d0 # yes; denorm bias = DBL_BIAS - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20875) dst_get_dupper:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20876) swap %d0 # d0 now in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20877) lsl.l &0x4,%d0 # d0 in proper place for dbl prec exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20878) tst.b FTEMP_EX(%a0) # test sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20879) bpl.b dst_get_dman # if positive, go process mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20880) bset &0x1f,%d0 # if negative, set sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20881) dst_get_dman:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20882) mov.l FTEMP_HI(%a0),%d1 # get ms mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20883) bfextu %d1{&1:&20},%d1 # get upper 20 bits of ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20884) or.l %d1,%d0 # put these bits in ms word of double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20885) mov.l %d0,L_SCR1(%a6) # put the new exp back on the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20886) mov.l FTEMP_HI(%a0),%d1 # get ms mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20887) mov.l &21,%d0 # load shift count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20888) lsl.l %d0,%d1 # put lower 11 bits in upper bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20889) mov.l %d1,L_SCR2(%a6) # build lower lword in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20890) mov.l FTEMP_LO(%a0),%d1 # get ls mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20891) bfextu %d1{&0:&21},%d0 # get ls 21 bits of double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20892) mov.l L_SCR2(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20893) or.l %d0,%d1 # put them in double result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20894) mov.l L_SCR1(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20895) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20897) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20898) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20899) # dst_sgl(): create single precision value from extended prec #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20900) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20901) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20902) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20903) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20904) # a0 = pointer to source operand in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20905) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20906) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20907) # d0 = single precision result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20908) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20909) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20910) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20911) # Changes extended precision to single precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20912) # sgl_sign = ext_sign #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20913) # sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20914) # get rid of ext integer bit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20915) # sgl_mant = ext_mant{62:12} #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20916) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20917) # --------------- --------------- --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20918) # extended -> |s| exp | |1| ms mant | | ls mant | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20919) # --------------- --------------- --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20920) # 95 64 63 62 40 32 31 12 0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20921) # | | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20922) # | | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20923) # | | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20924) # v v #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20925) # --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20926) # single -> |s|exp| mant | #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20927) # --------------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20928) # 31 22 0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20929) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20930) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20932) dst_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20933) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20934) mov.w FTEMP_EX(%a0),%d0 # get exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20935) subi.w &EXT_BIAS,%d0 # subtract extended precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20936) addi.w &SGL_BIAS,%d0 # add single precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20937) tst.b FTEMP_HI(%a0) # is number a denorm?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20938) bmi.b dst_get_supper # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20939) subq.w &0x1,%d0 # yes; denorm bias = SGL_BIAS - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20940) dst_get_supper:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20941) swap %d0 # put exp in upper word of d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20942) lsl.l &0x7,%d0 # shift it into single exp bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20943) tst.b FTEMP_EX(%a0) # test sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20944) bpl.b dst_get_sman # if positive, continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20945) bset &0x1f,%d0 # if negative, put in sign first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20946) dst_get_sman:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20947) mov.l FTEMP_HI(%a0),%d1 # get ms mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20948) andi.l &0x7fffff00,%d1 # get upper 23 bits of ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20949) lsr.l &0x8,%d1 # and put them flush right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20950) or.l %d1,%d0 # put these bits in ms word of single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20951) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20953) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20954) fout_pack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20955) bsr.l _calc_ea_fout # fetch the <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20956) mov.l %a0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20958) mov.b STAG(%a6),%d0 # fetch input type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20959) bne.w fout_pack_not_norm # input is not NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20961) fout_pack_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20962) btst &0x4,EXC_CMDREG(%a6) # static or dynamic?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20963) beq.b fout_pack_s # static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20965) fout_pack_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20966) mov.b 1+EXC_CMDREG(%a6),%d1 # fetch dynamic reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20967) lsr.b &0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20968) andi.w &0x7,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20970) bsr.l fetch_dreg # fetch Dn w/ k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20972) bra.b fout_pack_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20973) fout_pack_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20974) mov.b 1+EXC_CMDREG(%a6),%d0 # fetch static field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20976) fout_pack_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20977) bfexts %d0{&25:&7},%d0 # extract k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20978) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20980) lea FP_SRC(%a6),%a0 # pass: ptr to input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20982) # bindec is currently scrambling FP_SRC for denorm inputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20983) # we'll have to change this, but for now, tough luck!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20984) bsr.l bindec # convert xprec to packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20986) # andi.l &0xcfff000f,FP_SCR0(%a6) # clear unused fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20987) andi.l &0xcffff00f,FP_SCR0(%a6) # clear unused fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20989) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20991) tst.b 3+FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20992) bne.b fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20993) tst.l FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20994) bne.b fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20995) tst.l FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20996) bne.b fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20998) # add the extra condition that only if the k-factor was zero, too, should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20999) # we zero the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21000) tst.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21001) bne.b fout_pack_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21002) # "mantissa" is all zero which means that the answer is zero. but, the '040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21003) # algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21004) # if the mantissa is zero, I will zero the exponent, too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21005) # the question now is whether the exponents sign bit is allowed to be non-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21006) # for a zero, also...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21007) andi.w &0xf000,FP_SCR0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21009) fout_pack_set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21011) lea FP_SCR0(%a6),%a0 # pass: src addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21013) fout_pack_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21014) mov.l (%sp)+,%a1 # pass: dst addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21015) mov.l &0xc,%d0 # pass: opsize is 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21017) cmpi.b SPCOND_FLG(%a6),&mda7_flg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21018) beq.b fout_pack_a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21020) bsr.l _dmem_write # write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21022) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21023) bne.w fout_ext_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21025) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21027) # we don't want to do the write if the exception occurred in supervisor mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21028) # so _mem_write2() handles this for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21029) fout_pack_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21030) bsr.l _mem_write2 # write ext prec number to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21032) tst.l %d1 # did dstore fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21033) bne.w fout_ext_err # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21035) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21037) fout_pack_not_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21038) cmpi.b %d0,&DENORM # is it a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21039) beq.w fout_pack_norm # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21040) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21041) clr.w 2+FP_SRC_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21042) cmpi.b %d0,&SNAN # is it an SNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21043) beq.b fout_pack_snan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21044) bra.b fout_pack_write # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21046) fout_pack_snan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21047) ori.w &snaniop2_mask,FPSR_EXCEPT(%a6) # set SNAN/AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21048) bset &0x6,FP_SRC_HI(%a6) # set snan bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21049) bra.b fout_pack_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21051) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21052) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21053) # fetch_dreg(): fetch register according to index in d1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21054) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21055) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21056) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21057) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21058) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21059) # d1 = index of register to fetch from #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21060) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21061) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21062) # d0 = value of register fetched #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21063) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21064) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21065) # According to the index value in d1 which can range from zero #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21066) # to fifteen, load the corresponding register file value (where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21067) # address register indexes start at 8). D0/D1/A0/A1/A6/A7 are on the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21068) # stack. The rest should still be in their original places. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21069) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21070) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21072) # this routine leaves d1 intact for subsequent store_dreg calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21073) global fetch_dreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21074) fetch_dreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21075) mov.w (tbl_fdreg.b,%pc,%d1.w*2),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21076) jmp (tbl_fdreg.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21078) tbl_fdreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21079) short fdreg0 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21080) short fdreg1 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21081) short fdreg2 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21082) short fdreg3 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21083) short fdreg4 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21084) short fdreg5 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21085) short fdreg6 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21086) short fdreg7 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21087) short fdreg8 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21088) short fdreg9 - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21089) short fdrega - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21090) short fdregb - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21091) short fdregc - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21092) short fdregd - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21093) short fdrege - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21094) short fdregf - tbl_fdreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21096) fdreg0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21097) mov.l EXC_DREGS+0x0(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21098) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21099) fdreg1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21100) mov.l EXC_DREGS+0x4(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21101) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21102) fdreg2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21103) mov.l %d2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21104) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21105) fdreg3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21106) mov.l %d3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21107) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21108) fdreg4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21109) mov.l %d4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21110) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21111) fdreg5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21112) mov.l %d5,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21113) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21114) fdreg6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21115) mov.l %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21116) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21117) fdreg7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21118) mov.l %d7,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21119) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21120) fdreg8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21121) mov.l EXC_DREGS+0x8(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21122) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21123) fdreg9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21124) mov.l EXC_DREGS+0xc(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21125) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21126) fdrega:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21127) mov.l %a2,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21128) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21129) fdregb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21130) mov.l %a3,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21131) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21132) fdregc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21133) mov.l %a4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21134) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21135) fdregd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21136) mov.l %a5,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21137) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21138) fdrege:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21139) mov.l (%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21140) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21141) fdregf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21142) mov.l EXC_A7(%a6),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21143) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21145) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21146) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21147) # store_dreg_l(): store longword to data register specified by d1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21148) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21149) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21150) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21151) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21152) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21153) # d0 = longowrd value to store #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21154) # d1 = index of register to fetch from #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21155) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21156) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21157) # (data register is updated) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21158) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21159) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21160) # According to the index value in d1, store the longword value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21161) # in d0 to the corresponding data register. D0/D1 are on the stack #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21162) # while the rest are in their initial places. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21163) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21164) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21166) global store_dreg_l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21167) store_dreg_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21168) mov.w (tbl_sdregl.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21169) jmp (tbl_sdregl.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21171) tbl_sdregl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21172) short sdregl0 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21173) short sdregl1 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21174) short sdregl2 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21175) short sdregl3 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21176) short sdregl4 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21177) short sdregl5 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21178) short sdregl6 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21179) short sdregl7 - tbl_sdregl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21181) sdregl0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21182) mov.l %d0,EXC_DREGS+0x0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21183) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21184) sdregl1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21185) mov.l %d0,EXC_DREGS+0x4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21186) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21187) sdregl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21188) mov.l %d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21189) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21190) sdregl3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21191) mov.l %d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21192) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21193) sdregl4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21194) mov.l %d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21195) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21196) sdregl5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21197) mov.l %d0,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21198) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21199) sdregl6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21200) mov.l %d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21201) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21202) sdregl7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21203) mov.l %d0,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21204) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21206) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21207) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21208) # store_dreg_w(): store word to data register specified by d1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21209) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21210) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21211) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21212) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21213) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21214) # d0 = word value to store #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21215) # d1 = index of register to fetch from #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21216) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21217) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21218) # (data register is updated) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21219) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21220) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21221) # According to the index value in d1, store the word value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21222) # in d0 to the corresponding data register. D0/D1 are on the stack #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21223) # while the rest are in their initial places. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21224) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21225) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21227) global store_dreg_w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21228) store_dreg_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21229) mov.w (tbl_sdregw.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21230) jmp (tbl_sdregw.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21232) tbl_sdregw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21233) short sdregw0 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21234) short sdregw1 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21235) short sdregw2 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21236) short sdregw3 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21237) short sdregw4 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21238) short sdregw5 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21239) short sdregw6 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21240) short sdregw7 - tbl_sdregw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21242) sdregw0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21243) mov.w %d0,2+EXC_DREGS+0x0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21244) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21245) sdregw1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21246) mov.w %d0,2+EXC_DREGS+0x4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21247) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21248) sdregw2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21249) mov.w %d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21250) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21251) sdregw3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21252) mov.w %d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21253) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21254) sdregw4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21255) mov.w %d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21256) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21257) sdregw5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21258) mov.w %d0,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21259) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21260) sdregw6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21261) mov.w %d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21262) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21263) sdregw7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21264) mov.w %d0,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21265) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21267) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21268) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21269) # store_dreg_b(): store byte to data register specified by d1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21270) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21271) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21272) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21273) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21274) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21275) # d0 = byte value to store #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21276) # d1 = index of register to fetch from #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21277) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21278) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21279) # (data register is updated) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21280) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21281) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21282) # According to the index value in d1, store the byte value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21283) # in d0 to the corresponding data register. D0/D1 are on the stack #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21284) # while the rest are in their initial places. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21285) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21286) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21288) global store_dreg_b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21289) store_dreg_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21290) mov.w (tbl_sdregb.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21291) jmp (tbl_sdregb.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21293) tbl_sdregb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21294) short sdregb0 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21295) short sdregb1 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21296) short sdregb2 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21297) short sdregb3 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21298) short sdregb4 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21299) short sdregb5 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21300) short sdregb6 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21301) short sdregb7 - tbl_sdregb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21303) sdregb0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21304) mov.b %d0,3+EXC_DREGS+0x0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21305) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21306) sdregb1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21307) mov.b %d0,3+EXC_DREGS+0x4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21308) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21309) sdregb2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21310) mov.b %d0,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21311) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21312) sdregb3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21313) mov.b %d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21314) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21315) sdregb4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21316) mov.b %d0,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21317) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21318) sdregb5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21319) mov.b %d0,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21320) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21321) sdregb6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21322) mov.b %d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21323) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21324) sdregb7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21325) mov.b %d0,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21326) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21328) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21329) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21330) # inc_areg(): increment an address register by the value in d0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21331) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21332) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21333) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21334) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21335) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21336) # d0 = amount to increment by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21337) # d1 = index of address register to increment #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21338) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21339) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21340) # (address register is updated) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21341) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21342) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21343) # Typically used for an instruction w/ a post-increment <ea>, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21344) # this routine adds the increment value in d0 to the address register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21345) # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21346) # in their original places. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21347) # For a7, if the increment amount is one, then we have to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21348) # increment by two. For any a7 update, set the mia7_flag so that if #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21349) # an access error exception occurs later in emulation, this address #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21350) # register update can be undone. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21351) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21352) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21354) global inc_areg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21355) inc_areg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21356) mov.w (tbl_iareg.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21357) jmp (tbl_iareg.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21359) tbl_iareg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21360) short iareg0 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21361) short iareg1 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21362) short iareg2 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21363) short iareg3 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21364) short iareg4 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21365) short iareg5 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21366) short iareg6 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21367) short iareg7 - tbl_iareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21369) iareg0: add.l %d0,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21370) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21371) iareg1: add.l %d0,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21372) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21373) iareg2: add.l %d0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21374) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21375) iareg3: add.l %d0,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21376) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21377) iareg4: add.l %d0,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21378) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21379) iareg5: add.l %d0,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21380) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21381) iareg6: add.l %d0,(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21382) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21383) iareg7: mov.b &mia7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21384) cmpi.b %d0,&0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21385) beq.b iareg7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21386) add.l %d0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21387) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21388) iareg7b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21389) addq.l &0x2,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21390) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21392) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21393) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21394) # dec_areg(): decrement an address register by the value in d0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21395) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21396) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21397) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21398) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21399) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21400) # d0 = amount to decrement by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21401) # d1 = index of address register to decrement #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21402) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21403) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21404) # (address register is updated) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21405) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21406) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21407) # Typically used for an instruction w/ a pre-decrement <ea>, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21408) # this routine adds the decrement value in d0 to the address register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21409) # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21410) # in their original places. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21411) # For a7, if the decrement amount is one, then we have to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21412) # decrement by two. For any a7 update, set the mda7_flag so that if #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21413) # an access error exception occurs later in emulation, this address #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21414) # register update can be undone. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21415) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21416) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21418) global dec_areg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21419) dec_areg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21420) mov.w (tbl_dareg.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21421) jmp (tbl_dareg.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21423) tbl_dareg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21424) short dareg0 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21425) short dareg1 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21426) short dareg2 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21427) short dareg3 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21428) short dareg4 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21429) short dareg5 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21430) short dareg6 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21431) short dareg7 - tbl_dareg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21433) dareg0: sub.l %d0,EXC_DREGS+0x8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21434) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21435) dareg1: sub.l %d0,EXC_DREGS+0xc(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21436) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21437) dareg2: sub.l %d0,%a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21438) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21439) dareg3: sub.l %d0,%a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21440) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21441) dareg4: sub.l %d0,%a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21442) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21443) dareg5: sub.l %d0,%a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21444) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21445) dareg6: sub.l %d0,(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21446) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21447) dareg7: mov.b &mda7_flg,SPCOND_FLG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21448) cmpi.b %d0,&0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21449) beq.b dareg7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21450) sub.l %d0,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21451) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21452) dareg7b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21453) subq.l &0x2,EXC_A7(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21454) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21456) ##############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21458) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21459) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21460) # load_fpn1(): load FP register value into FP_SRC(a6). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21461) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21462) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21463) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21464) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21465) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21466) # d0 = index of FP register to load #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21467) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21468) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21469) # FP_SRC(a6) = value loaded from FP register file #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21470) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21471) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21472) # Using the index in d0, load FP_SRC(a6) with a number from the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21473) # FP register file. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21474) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21475) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21477) global load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21478) load_fpn1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21479) mov.w (tbl_load_fpn1.b,%pc,%d0.w*2), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21480) jmp (tbl_load_fpn1.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21482) tbl_load_fpn1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21483) short load_fpn1_0 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21484) short load_fpn1_1 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21485) short load_fpn1_2 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21486) short load_fpn1_3 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21487) short load_fpn1_4 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21488) short load_fpn1_5 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21489) short load_fpn1_6 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21490) short load_fpn1_7 - tbl_load_fpn1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21492) load_fpn1_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21493) mov.l 0+EXC_FP0(%a6), 0+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21494) mov.l 4+EXC_FP0(%a6), 4+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21495) mov.l 8+EXC_FP0(%a6), 8+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21496) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21497) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21498) load_fpn1_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21499) mov.l 0+EXC_FP1(%a6), 0+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21500) mov.l 4+EXC_FP1(%a6), 4+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21501) mov.l 8+EXC_FP1(%a6), 8+FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21502) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21503) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21504) load_fpn1_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21505) fmovm.x &0x20, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21506) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21507) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21508) load_fpn1_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21509) fmovm.x &0x10, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21510) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21511) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21512) load_fpn1_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21513) fmovm.x &0x08, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21514) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21515) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21516) load_fpn1_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21517) fmovm.x &0x04, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21518) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21519) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21520) load_fpn1_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21521) fmovm.x &0x02, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21522) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21523) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21524) load_fpn1_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21525) fmovm.x &0x01, FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21526) lea FP_SRC(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21527) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21529) #############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21531) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21532) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21533) # load_fpn2(): load FP register value into FP_DST(a6). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21534) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21535) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21536) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21537) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21538) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21539) # d0 = index of FP register to load #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21540) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21541) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21542) # FP_DST(a6) = value loaded from FP register file #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21543) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21544) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21545) # Using the index in d0, load FP_DST(a6) with a number from the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21546) # FP register file. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21547) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21548) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21550) global load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21551) load_fpn2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21552) mov.w (tbl_load_fpn2.b,%pc,%d0.w*2), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21553) jmp (tbl_load_fpn2.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21555) tbl_load_fpn2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21556) short load_fpn2_0 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21557) short load_fpn2_1 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21558) short load_fpn2_2 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21559) short load_fpn2_3 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21560) short load_fpn2_4 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21561) short load_fpn2_5 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21562) short load_fpn2_6 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21563) short load_fpn2_7 - tbl_load_fpn2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21565) load_fpn2_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21566) mov.l 0+EXC_FP0(%a6), 0+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21567) mov.l 4+EXC_FP0(%a6), 4+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21568) mov.l 8+EXC_FP0(%a6), 8+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21569) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21570) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21571) load_fpn2_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21572) mov.l 0+EXC_FP1(%a6), 0+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21573) mov.l 4+EXC_FP1(%a6), 4+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21574) mov.l 8+EXC_FP1(%a6), 8+FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21575) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21576) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21577) load_fpn2_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21578) fmovm.x &0x20, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21579) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21580) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21581) load_fpn2_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21582) fmovm.x &0x10, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21583) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21584) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21585) load_fpn2_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21586) fmovm.x &0x08, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21587) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21588) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21589) load_fpn2_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21590) fmovm.x &0x04, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21591) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21592) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21593) load_fpn2_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21594) fmovm.x &0x02, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21595) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21596) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21597) load_fpn2_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21598) fmovm.x &0x01, FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21599) lea FP_DST(%a6), %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21600) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21602) #############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21604) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21605) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21606) # store_fpreg(): store an fp value to the fpreg designated d0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21607) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21608) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21609) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21610) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21611) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21612) # fp0 = extended precision value to store #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21613) # d0 = index of floating-point register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21614) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21615) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21616) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21617) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21618) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21619) # Store the value in fp0 to the FP register designated by the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21620) # 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 21621) # careful that we don't take an exception here. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21622) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21623) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21625) global store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21626) store_fpreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21627) mov.w (tbl_store_fpreg.b,%pc,%d0.w*2), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21628) jmp (tbl_store_fpreg.b,%pc,%d0.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21630) tbl_store_fpreg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21631) short store_fpreg_0 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21632) short store_fpreg_1 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21633) short store_fpreg_2 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21634) short store_fpreg_3 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21635) short store_fpreg_4 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21636) short store_fpreg_5 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21637) short store_fpreg_6 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21638) short store_fpreg_7 - tbl_store_fpreg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21640) store_fpreg_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21641) fmovm.x &0x80, EXC_FP0(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21642) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21643) store_fpreg_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21644) fmovm.x &0x80, EXC_FP1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21645) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21646) store_fpreg_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21647) fmovm.x &0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21648) fmovm.x (%sp)+, &0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21649) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21650) store_fpreg_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21651) fmovm.x &0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21652) fmovm.x (%sp)+, &0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21653) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21654) store_fpreg_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21655) fmovm.x &0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21656) fmovm.x (%sp)+, &0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21657) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21658) store_fpreg_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21659) fmovm.x &0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21660) fmovm.x (%sp)+, &0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21661) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21662) store_fpreg_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21663) fmovm.x &0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21664) fmovm.x (%sp)+, &0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21665) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21666) store_fpreg_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21667) fmovm.x &0x01, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21668) fmovm.x (%sp)+, &0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21669) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21671) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21672) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21673) # _denorm(): denormalize an intermediate result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21674) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21675) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21676) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21677) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21678) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21679) # a0 = points to the operand to be denormalized #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21680) # (in the internal extended format) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21681) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21682) # d0 = rounding precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21683) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21684) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21685) # a0 = pointer to the denormalized result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21686) # (in the internal extended format) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21687) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21688) # d0 = guard,round,sticky #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21689) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21690) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21691) # According to the exponent underflow threshold for the given #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21692) # precision, shift the mantissa bits to the right in order raise the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21693) # exponent of the operand to the threshold value. While shifting the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21694) # mantissa bits right, maintain the value of the guard, round, and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21695) # sticky bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21696) # other notes: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21697) # (1) _denorm() is called by the underflow routines #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21698) # (2) _denorm() does NOT affect the status register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21699) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21700) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21702) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21703) # table of exponent threshold values for each precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21704) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21705) tbl_thresh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21706) short 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21707) short sgl_thresh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21708) short dbl_thresh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21710) global _denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21711) _denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21712) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21713) # Load the exponent threshold for the precision selected and check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21714) # to see if (threshold - exponent) is > 65 in which case we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21715) # simply calculate the sticky bit and zero the mantissa. otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21716) # we have to call the denormalization routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21717) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21718) lsr.b &0x2, %d0 # shift prec to lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21719) mov.w (tbl_thresh.b,%pc,%d0.w*2), %d1 # load prec threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21720) mov.w %d1, %d0 # copy d1 into d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21721) sub.w FTEMP_EX(%a0), %d0 # diff = threshold - exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21722) cmpi.w %d0, &66 # is diff > 65? (mant + g,r bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21723) bpl.b denorm_set_stky # yes; just calc sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21725) clr.l %d0 # clear g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21726) btst &inex2_bit, FPSR_EXCEPT(%a6) # yes; was INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21727) beq.b denorm_call # no; don't change anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21728) bset &29, %d0 # yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21730) denorm_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21731) bsr.l dnrm_lp # denormalize the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21732) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21734) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21735) # all bit would have been shifted off during the denorm so simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21736) # calculate if the sticky should be set and clear the entire mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21737) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21738) denorm_set_stky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21739) mov.l &0x20000000, %d0 # set sticky bit in return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21740) mov.w %d1, FTEMP_EX(%a0) # load exp with threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21741) clr.l FTEMP_HI(%a0) # set d1 = 0 (ms mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21742) clr.l FTEMP_LO(%a0) # set d2 = 0 (ms mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21743) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21745) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21746) # dnrm_lp(): normalize exponent/mantissa to specified threshold #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21747) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21748) # INPUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21749) # %a0 : points to the operand to be denormalized #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21750) # %d0{31:29} : initial guard,round,sticky #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21751) # %d1{15:0} : denormalization threshold #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21752) # OUTPUT: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21753) # %a0 : points to the denormalized operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21754) # %d0{31:29} : final guard,round,sticky #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21755) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21757) # *** Local Equates *** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21758) set GRS, L_SCR2 # g,r,s temp storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21759) set FTEMP_LO2, L_SCR1 # FTEMP_LO copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21761) global dnrm_lp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21762) dnrm_lp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21764) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21765) # 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 21766) # in memory so as to make the bitfield extraction for denormalization easier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21767) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21768) mov.l FTEMP_LO(%a0), FTEMP_LO2(%a6) # make FTEMP_LO copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21769) mov.l %d0, GRS(%a6) # place g,r,s after it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21771) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21772) # check to see how much less than the underflow threshold the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21773) # exponent is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21774) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21775) mov.l %d1, %d0 # copy the denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21776) sub.w FTEMP_EX(%a0), %d1 # d1 = threshold - uns exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21777) ble.b dnrm_no_lp # d1 <= 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21778) cmpi.w %d1, &0x20 # is ( 0 <= d1 < 32) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21779) blt.b case_1 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21780) cmpi.w %d1, &0x40 # is (32 <= d1 < 64) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21781) blt.b case_2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21782) bra.w case_3 # (d1 >= 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21784) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21785) # No normalization necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21786) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21787) dnrm_no_lp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21788) mov.l GRS(%a6), %d0 # restore original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21789) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21791) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21792) # case (0<d1<32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21793) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21794) # %d0 = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21795) # %d1 = "n" = amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21796) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21797) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21798) # | FTEMP_HI | FTEMP_LO |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21799) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21800) # <-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21801) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21802) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21803) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21804) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21805) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21806) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21807) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21808) # \ \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21809) # <-(n)-><-(32 - n)-><------(32)-------><------(32)------->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21810) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21811) # |0.....0| NEW_HI | NEW_FTEMP_LO |grs |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21812) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21813) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21814) case_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21815) mov.l %d2, -(%sp) # create temp storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21817) mov.w %d0, FTEMP_EX(%a0) # exponent = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21818) mov.l &32, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21819) sub.w %d1, %d0 # %d0 = 32 - %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21821) cmpi.w %d1, &29 # is shft amt >= 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21822) blt.b case1_extract # no; no fix needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21823) mov.b GRS(%a6), %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21824) or.b %d2, 3+FTEMP_LO2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21826) case1_extract:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21827) bfextu FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_HI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21828) bfextu FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21829) bfextu FTEMP_LO2(%a6){%d0:&32}, %d0 # %d0 = new G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21831) mov.l %d2, FTEMP_HI(%a0) # store new FTEMP_HI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21832) mov.l %d1, FTEMP_LO(%a0) # store new FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21834) bftst %d0{&2:&30} # were bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21835) beq.b case1_sticky_clear # no; go finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21836) bset &rnd_stky_bit, %d0 # yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21838) case1_sticky_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21839) and.l &0xe0000000, %d0 # clear all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21840) mov.l (%sp)+, %d2 # restore temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21841) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21843) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21844) # case (32<=d1<64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21845) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21846) # %d0 = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21847) # %d1 = "n" = amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21848) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21849) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21850) # | FTEMP_HI | FTEMP_LO |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21851) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21852) # <-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21853) # \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21854) # \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21855) # \ \ -------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21856) # \ -------------------- \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21857) # ------------------- \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21858) # \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21859) # \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21860) # \ \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21861) # <-------(32)------><-(n)-><-(32 - n)-><------(32)------->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21862) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21863) # |0...............0|0....0| NEW_LO |grs |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21864) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21865) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21866) case_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21867) mov.l %d2, -(%sp) # create temp storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21869) mov.w %d0, FTEMP_EX(%a0) # exponent = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21870) subi.w &0x20, %d1 # %d1 now between 0 and 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21871) mov.l &0x20, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21872) sub.w %d1, %d0 # %d0 = 32 - %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21874) # 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 21875) # the number of bits to check for the sticky detect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21876) # it only plays a role in shift amounts of 61-63.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21877) mov.b GRS(%a6), %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21878) or.b %d2, 3+FTEMP_LO2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21880) bfextu FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21881) bfextu FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21883) bftst %d1{&2:&30} # were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21884) bne.b case2_set_sticky # yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21885) bftst FTEMP_LO2(%a6){%d0:&31} # were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21886) bne.b case2_set_sticky # yes; set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21888) mov.l %d1, %d0 # move new G,R,S to %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21889) bra.b case2_end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21891) case2_set_sticky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21892) mov.l %d1, %d0 # move new G,R,S to %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21893) bset &rnd_stky_bit, %d0 # set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21895) case2_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21896) clr.l FTEMP_HI(%a0) # store FTEMP_HI = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21897) mov.l %d2, FTEMP_LO(%a0) # store FTEMP_LO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21898) and.l &0xe0000000, %d0 # clear all but G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21900) mov.l (%sp)+,%d2 # restore temp register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21901) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21903) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21904) # case (d1>=64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21905) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21906) # %d0 = denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21907) # %d1 = amt to shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21908) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21909) case_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21910) mov.w %d0, FTEMP_EX(%a0) # insert denorm threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21912) cmpi.w %d1, &65 # is shift amt > 65?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21913) blt.b case3_64 # no; it's == 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21914) beq.b case3_65 # no; it's == 65
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21916) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21917) # case (d1>65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21918) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21919) # Shift value is > 65 and out of range. All bits are shifted off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21920) # Return a zero mantissa with the sticky bit set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21921) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21922) clr.l FTEMP_HI(%a0) # clear hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21923) clr.l FTEMP_LO(%a0) # clear lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21924) mov.l &0x20000000, %d0 # set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21925) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21927) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21928) # case (d1 == 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21929) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21930) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21931) # | FTEMP_HI | FTEMP_LO |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21932) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21933) # <-------(32)------>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21934) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21935) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21936) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21937) # \ ------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21938) # ------------------------------- \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21939) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21940) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21941) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21942) # <-------(32)------>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21943) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21944) # |0...............0|0................0|grs |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21945) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21946) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21947) case3_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21948) mov.l FTEMP_HI(%a0), %d0 # fetch hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21949) mov.l %d0, %d1 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21950) and.l &0xc0000000, %d0 # extract G,R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21951) and.l &0x3fffffff, %d1 # extract other bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21953) bra.b case3_complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21955) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21956) # case (d1 == 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21957) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21958) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21959) # | FTEMP_HI | FTEMP_LO |grs000.........000|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21960) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21961) # <-------(32)------>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21962) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21963) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21964) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21965) # \ ------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21966) # -------------------------------- \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21967) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21968) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21969) # \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21970) # <-------(31)----->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21971) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21972) # |0...............0|0................0|0rs |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21973) # ---------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21974) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21975) case3_65:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21976) mov.l FTEMP_HI(%a0), %d0 # fetch hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21977) and.l &0x80000000, %d0 # extract R bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21978) lsr.l &0x1, %d0 # shift high bit into R bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21979) and.l &0x7fffffff, %d1 # extract other bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21981) case3_complete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21982) # last operation done was an "and" of the bits shifted off so the condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21983) # codes are already set so branch accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21984) bne.b case3_set_sticky # yes; go set new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21985) tst.l FTEMP_LO(%a0) # were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21986) bne.b case3_set_sticky # yes; go set new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21987) tst.b GRS(%a6) # were any bits shifted off?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21988) bne.b case3_set_sticky # yes; go set new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21990) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21991) # no bits were shifted off so don't set the sticky bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21992) # the guard and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21993) # the entire mantissa is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21994) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21995) clr.l FTEMP_HI(%a0) # clear hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21996) clr.l FTEMP_LO(%a0) # clear lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21997) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21999) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22000) # some bits were shifted off so set the sticky bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22001) # the entire mantissa is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22002) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22003) case3_set_sticky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22004) bset &rnd_stky_bit,%d0 # set new sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22005) clr.l FTEMP_HI(%a0) # clear hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22006) clr.l FTEMP_LO(%a0) # clear lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22007) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22009) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22010) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22011) # _round(): round result according to precision/mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22012) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22013) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22014) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22015) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22016) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22017) # a0 = ptr to input operand in internal extended format #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22018) # d1(hi) = contains rounding precision: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22019) # ext = $0000xxxx #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22020) # sgl = $0004xxxx #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22021) # dbl = $0008xxxx #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22022) # d1(lo) = contains rounding mode: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22023) # RN = $xxxx0000 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22024) # RZ = $xxxx0001 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22025) # RM = $xxxx0002 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22026) # RP = $xxxx0003 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22027) # d0{31:29} = contains the g,r,s bits (extended) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22028) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22029) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22030) # a0 = pointer to rounded result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22031) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22032) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22033) # On return the value pointed to by a0 is correctly rounded, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22034) # a0 is preserved and the g-r-s bits in d0 are cleared. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22035) # The result is not typed - the tag field is invalid. The #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22036) # result is still in the internal extended format. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22037) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22038) # The INEX bit of USER_FPSR will be set if the rounded result was #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22039) # inexact (i.e. if any of the g-r-s bits were set). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22040) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22041) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22043) global _round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22044) _round:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22045) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22046) # ext_grs() looks at the rounding precision and sets the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22047) # G,R,S bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22048) # If (G,R,S == 0) then result is exact and round is done, else set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22049) # the inex flag in status reg and continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22050) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22051) bsr.l ext_grs # extract G,R,S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22053) tst.l %d0 # are G,R,S zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22054) beq.w truncate # yes; round is complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22056) or.w &inx2a_mask, 2+USER_FPSR(%a6) # set inex2/ainex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22058) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22059) # Use rounding mode as an index into a jump table for these modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22060) # All of the following assumes grs != 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22061) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22062) mov.w (tbl_mode.b,%pc,%d1.w*2), %a1 # load jump offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22063) jmp (tbl_mode.b,%pc,%a1) # jmp to rnd mode handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22065) tbl_mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22066) short rnd_near - tbl_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22067) short truncate - tbl_mode # RZ always truncates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22068) short rnd_mnus - tbl_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22069) short rnd_plus - tbl_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22071) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22072) # ROUND PLUS INFINITY #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22073) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22074) # If sign of fp number = 0 (positive), then add 1 to l. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22075) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22076) rnd_plus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22077) tst.b FTEMP_SGN(%a0) # check for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22078) bmi.w truncate # if positive then truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22080) mov.l &0xffffffff, %d0 # force g,r,s to be all f's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22081) swap %d1 # set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22083) cmpi.b %d1, &s_mode # is prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22084) beq.w add_sgl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22085) bgt.w add_dbl # no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22086) bra.w add_ext # no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22088) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22089) # ROUND MINUS INFINITY #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22090) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22091) # If sign of fp number = 1 (negative), then add 1 to l. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22092) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22093) rnd_mnus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22094) tst.b FTEMP_SGN(%a0) # check for sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22095) bpl.w truncate # if negative then truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22097) mov.l &0xffffffff, %d0 # force g,r,s to be all f's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22098) swap %d1 # set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22100) cmpi.b %d1, &s_mode # is prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22101) beq.w add_sgl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22102) bgt.w add_dbl # no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22103) bra.w add_ext # no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22105) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22106) # ROUND NEAREST #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22107) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22108) # 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 22109) # Note that this will round to even in case of a tie. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22110) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22111) rnd_near:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22112) asl.l &0x1, %d0 # shift g-bit to c-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22113) bcc.w truncate # if (g=1) then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22115) swap %d1 # set up d1 for round prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22117) cmpi.b %d1, &s_mode # is prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22118) beq.w add_sgl # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22119) bgt.w add_dbl # no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22120) bra.w add_ext # no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22122) # *** LOCAL EQUATES ***
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22123) set ad_1_sgl, 0x00000100 # constant to add 1 to l-bit in sgl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22124) set ad_1_dbl, 0x00000800 # constant to add 1 to l-bit in dbl prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22126) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22127) # ADD SINGLE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22128) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22129) add_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22130) add.l &ad_1_sgl, FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22131) bcc.b scc_clr # no mantissa overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22132) roxr.w FTEMP_HI(%a0) # shift v-bit back in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22133) roxr.w FTEMP_HI+2(%a0) # shift v-bit back in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22134) add.w &0x1, FTEMP_EX(%a0) # and incr exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22135) scc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22136) tst.l %d0 # test for rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22137) bne.b sgl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22138) and.w &0xfe00, FTEMP_HI+2(%a0) # clear the l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22139) sgl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22140) and.l &0xffffff00, FTEMP_HI(%a0) # truncate bits beyond sgl limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22141) clr.l FTEMP_LO(%a0) # clear d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22142) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22144) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22145) # ADD EXTENDED #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22146) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22147) add_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22148) addq.l &1,FTEMP_LO(%a0) # add 1 to l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22149) bcc.b xcc_clr # test for carry out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22150) addq.l &1,FTEMP_HI(%a0) # propagate carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22151) bcc.b xcc_clr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22152) roxr.w FTEMP_HI(%a0) # mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22153) roxr.w FTEMP_HI+2(%a0) # mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22154) roxr.w FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22155) roxr.w FTEMP_LO+2(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22156) add.w &0x1,FTEMP_EX(%a0) # and inc exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22157) xcc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22158) tst.l %d0 # test rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22159) bne.b add_ext_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22160) and.b &0xfe,FTEMP_LO+3(%a0) # clear the l bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22161) add_ext_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22162) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22164) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22165) # ADD DOUBLE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22166) #########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22167) add_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22168) add.l &ad_1_dbl, FTEMP_LO(%a0) # add 1 to lsb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22169) bcc.b dcc_clr # no carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22170) addq.l &0x1, FTEMP_HI(%a0) # propagate carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22171) bcc.b dcc_clr # no carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22173) roxr.w FTEMP_HI(%a0) # mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22174) roxr.w FTEMP_HI+2(%a0) # mant is 0 so restore v-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22175) roxr.w FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22176) roxr.w FTEMP_LO+2(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22177) addq.w &0x1, FTEMP_EX(%a0) # incr exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22178) dcc_clr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22179) tst.l %d0 # test for rs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22180) bne.b dbl_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22181) and.w &0xf000, FTEMP_LO+2(%a0) # clear the l-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22183) dbl_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22184) and.l &0xfffff800,FTEMP_LO(%a0) # truncate bits beyond dbl limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22185) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22187) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22188) # Truncate all other bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22189) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22190) truncate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22191) swap %d1 # select rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22193) cmpi.b %d1, &s_mode # is prec sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22194) beq.w sgl_done # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22195) bgt.b dbl_done # no; it's dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22196) rts # no; it's ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22199) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22200) # ext_grs(): extract guard, round and sticky bits according to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22201) # rounding precision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22202) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22203) # INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22204) # d0 = extended precision g,r,s (in d0{31:29})
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22205) # d1 = {PREC,ROUND}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22206) # OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22207) # d0{31:29} = guard, round, sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22208) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22209) # The ext_grs extract the guard/round/sticky bits according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22210) # selected rounding precision. It is called by the round subroutine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22211) # only. All registers except d0 are kept intact. d0 becomes an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22212) # updated guard,round,sticky in d0{31:29}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22213) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22214) # Notes: the ext_grs uses the round PREC, and therefore has to swap d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22215) # prior to usage, and needs to restore d1 to original. this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22216) # routine is tightly tied to the round routine and not meant to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22217) # uphold standard subroutine calling practices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22218) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22220) ext_grs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22221) swap %d1 # have d1.w point to round precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22222) tst.b %d1 # is rnd prec = extended?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22223) bne.b ext_grs_not_ext # no; go handle sgl or dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22225) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22226) # %d0 actually already hold g,r,s since _round() had it before calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22227) # this function. so, as long as we don't disturb it, we are "returning" it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22228) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22229) ext_grs_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22230) swap %d1 # yes; return to correct positions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22231) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22233) ext_grs_not_ext:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22234) movm.l &0x3000, -(%sp) # make some temp registers {d2/d3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22236) cmpi.b %d1, &s_mode # is rnd prec = sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22237) bne.b ext_grs_dbl # no; go handle dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22239) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22240) # sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22241) # 96 64 40 32 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22242) # -----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22243) # | EXP |XXXXXXX| |xx | |grs|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22244) # -----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22245) # <--(24)--->nn\ /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22246) # ee ---------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22247) # ww |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22248) # v
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22249) # gr new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22250) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22251) ext_grs_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22252) bfextu FTEMP_HI(%a0){&24:&2}, %d3 # sgl prec. g-r are 2 bits right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22253) mov.l &30, %d2 # of the sgl prec. limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22254) lsl.l %d2, %d3 # shift g-r bits to MSB of d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22255) mov.l FTEMP_HI(%a0), %d2 # get word 2 for s-bit test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22256) and.l &0x0000003f, %d2 # s bit is the or of all other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22257) bne.b ext_grs_st_stky # bits to the right of g-r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22258) tst.l FTEMP_LO(%a0) # test lower mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22259) bne.b ext_grs_st_stky # if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22260) tst.l %d0 # test original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22261) bne.b ext_grs_st_stky # if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22262) bra.b ext_grs_end_sd # if words 3 and 4 are clr, exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22264) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22265) # dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22266) # 96 64 32 11 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22267) # -----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22268) # | EXP |XXXXXXX| | |xx |grs|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22269) # -----------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22270) # nn\ /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22271) # ee -------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22272) # ww |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22273) # v
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22274) # gr new sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22275) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22276) ext_grs_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22277) bfextu FTEMP_LO(%a0){&21:&2}, %d3 # dbl-prec. g-r are 2 bits right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22278) mov.l &30, %d2 # of the dbl prec. limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22279) lsl.l %d2, %d3 # shift g-r bits to the MSB of d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22280) mov.l FTEMP_LO(%a0), %d2 # get lower mantissa for s-bit test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22281) and.l &0x000001ff, %d2 # s bit is the or-ing of all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22282) bne.b ext_grs_st_stky # other bits to the right of g-r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22283) tst.l %d0 # test word original g,r,s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22284) bne.b ext_grs_st_stky # if any are set, set sticky
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22285) bra.b ext_grs_end_sd # if clear, exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22287) ext_grs_st_stky:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22288) bset &rnd_stky_bit, %d3 # set sticky bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22289) ext_grs_end_sd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22290) mov.l %d3, %d0 # return grs to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22292) movm.l (%sp)+, &0xc # restore scratch registers {d2/d3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22294) swap %d1 # restore d1 to original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22295) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22297) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22298) # norm(): normalize the mantissa of an extended precision input. the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22299) # input operand should not be normalized already. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22300) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22301) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22302) # norm() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22303) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22304) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22305) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22306) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22307) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22308) # a0 = pointer fp extended precision operand to normalize #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22309) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22310) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22311) # d0 = number of bit positions the mantissa was shifted #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22312) # a0 = the input operand's mantissa is normalized; the exponent #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22313) # is unchanged. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22314) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22315) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22316) global norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22317) norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22318) mov.l %d2, -(%sp) # create some temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22319) mov.l %d3, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22321) mov.l FTEMP_HI(%a0), %d0 # load hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22322) mov.l FTEMP_LO(%a0), %d1 # load lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22324) bfffo %d0{&0:&32}, %d2 # how many places to shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22325) beq.b norm_lo # hi(man) is all zeroes!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22327) norm_hi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22328) lsl.l %d2, %d0 # left shift hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22329) bfextu %d1{&0:%d2}, %d3 # extract lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22331) or.l %d3, %d0 # create hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22332) lsl.l %d2, %d1 # create lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22334) mov.l %d0, FTEMP_HI(%a0) # store new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22335) mov.l %d1, FTEMP_LO(%a0) # store new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22337) mov.l %d2, %d0 # return shift amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22339) mov.l (%sp)+, %d3 # restore temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22340) mov.l (%sp)+, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22342) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22344) norm_lo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22345) bfffo %d1{&0:&32}, %d2 # how many places to shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22346) lsl.l %d2, %d1 # shift lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22347) add.l &32, %d2 # add 32 to shft amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22349) mov.l %d1, FTEMP_HI(%a0) # store hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22350) clr.l FTEMP_LO(%a0) # lo(man) is now zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22352) mov.l %d2, %d0 # return shift amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22354) mov.l (%sp)+, %d3 # restore temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22355) mov.l (%sp)+, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22357) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22359) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22360) # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22361) # - returns corresponding optype tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22362) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22363) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22364) # unnorm_fix() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22365) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22366) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22367) # norm() - normalize the mantissa #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22368) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22369) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22370) # a0 = pointer to unnormalized extended precision number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22371) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22372) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22373) # d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22374) # a0 = input operand has been converted to a norm, denorm, or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22375) # zero; both the exponent and mantissa are changed. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22376) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22377) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22379) global unnorm_fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22380) unnorm_fix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22381) bfffo FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22382) bne.b unnorm_shift # hi(man) is not all zeroes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22384) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22385) # hi(man) is all zeroes so see if any bits in lo(man) are set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22386) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22387) unnorm_chk_lo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22388) bfffo FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22389) beq.w unnorm_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22391) add.w &32, %d0 # no; fix shift distance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22393) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22394) # d0 = # shifts needed for complete normalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22395) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22396) unnorm_shift:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22397) clr.l %d1 # clear top word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22398) mov.w FTEMP_EX(%a0), %d1 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22399) and.w &0x7fff, %d1 # strip off sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22401) cmp.w %d0, %d1 # will denorm push exp < 0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22402) bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22404) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22405) # exponent would not go < 0. Therefore, number stays normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22406) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22407) sub.w %d0, %d1 # shift exponent value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22408) mov.w FTEMP_EX(%a0), %d0 # load old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22409) and.w &0x8000, %d0 # save old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22410) or.w %d0, %d1 # {sgn,new exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22411) mov.w %d1, FTEMP_EX(%a0) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22413) bsr.l norm # normalize UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22415) mov.b &NORM, %d0 # return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22416) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22418) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22419) # exponent would go < 0, so only denormalize until exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22420) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22421) unnorm_nrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22422) cmp.b %d1, &32 # is exp <= 32?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22423) bgt.b unnorm_nrm_zero_lrg # no; go handle large exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22425) bfextu FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22426) mov.l %d0, FTEMP_HI(%a0) # save new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22428) mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22429) lsl.l %d1, %d0 # extract new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22430) mov.l %d0, FTEMP_LO(%a0) # save new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22432) and.w &0x8000, FTEMP_EX(%a0) # set exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22434) mov.b &DENORM, %d0 # return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22435) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22437) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22438) # only mantissa bits set are in lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22439) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22440) unnorm_nrm_zero_lrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22441) sub.w &32, %d1 # adjust shft amt by 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22443) mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22444) lsl.l %d1, %d0 # left shift lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22446) mov.l %d0, FTEMP_HI(%a0) # store new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22447) clr.l FTEMP_LO(%a0) # lo(man) = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22449) and.w &0x8000, FTEMP_EX(%a0) # set exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22451) mov.b &DENORM, %d0 # return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22452) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22454) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22455) # whole mantissa is zero so this UNNORM is actually a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22456) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22457) unnorm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22458) and.w &0x8000, FTEMP_EX(%a0) # force exponent to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22460) mov.b &ZERO, %d0 # fix optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22461) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22463) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22464) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22465) # set_tag_x(): return the optype of the input ext fp number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22466) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22467) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22468) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22469) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22470) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22471) # a0 = pointer to extended precision operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22472) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22473) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22474) # d0 = value of type tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22475) # one of: NORM, INF, QNAN, SNAN, DENORM, UNNORM, ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22476) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22477) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22478) # Simply test the exponent, j-bit, and mantissa values to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22479) # determine the type of operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22480) # If it's an unnormalized zero, alter the operand and force it #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22481) # to be a normal zero. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22482) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22483) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22485) global set_tag_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22486) set_tag_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22487) mov.w FTEMP_EX(%a0), %d0 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22488) andi.w &0x7fff, %d0 # strip off sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22489) cmpi.w %d0, &0x7fff # is (EXP == MAX)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22490) beq.b inf_or_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22491) not_inf_or_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22492) btst &0x7,FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22493) beq.b not_norm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22494) is_norm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22495) mov.b &NORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22496) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22497) not_norm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22498) tst.w %d0 # is exponent = 0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22499) bne.b is_unnorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22500) not_unnorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22501) tst.l FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22502) bne.b is_denorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22503) tst.l FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22504) bne.b is_denorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22505) is_zero_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22506) mov.b &ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22507) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22508) is_denorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22509) mov.b &DENORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22510) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22511) # must distinguish now "Unnormalized zeroes" which we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22512) # must convert to zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22513) is_unnorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22514) tst.l FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22515) bne.b is_unnorm_reg_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22516) tst.l FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22517) bne.b is_unnorm_reg_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22518) # it's an "unnormalized zero". let's convert it to an actual zero...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22519) andi.w &0x8000,FTEMP_EX(%a0) # clear exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22520) mov.b &ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22521) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22522) is_unnorm_reg_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22523) mov.b &UNNORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22524) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22525) inf_or_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22526) tst.l FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22527) bne.b is_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22528) mov.l FTEMP_HI(%a0), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22529) and.l &0x7fffffff, %d0 # msb is a don't care!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22530) bne.b is_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22531) is_inf_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22532) mov.b &INF, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22533) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22534) is_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22535) btst &0x6, FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22536) beq.b is_snan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22537) mov.b &QNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22538) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22539) is_snan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22540) mov.b &SNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22541) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22543) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22544) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22545) # set_tag_d(): return the optype of the input dbl fp number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22546) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22547) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22548) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22549) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22550) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22551) # a0 = points to double precision operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22552) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22553) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22554) # d0 = value of type tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22555) # one of: NORM, INF, QNAN, SNAN, DENORM, ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22556) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22557) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22558) # Simply test the exponent, j-bit, and mantissa values to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22559) # determine the type of operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22560) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22561) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22563) global set_tag_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22564) set_tag_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22565) mov.l FTEMP(%a0), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22566) mov.l %d0, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22568) andi.l &0x7ff00000, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22569) beq.b zero_or_denorm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22571) cmpi.l %d0, &0x7ff00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22572) beq.b inf_or_nan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22574) is_norm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22575) mov.b &NORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22576) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22577) zero_or_denorm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22578) and.l &0x000fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22579) bne is_denorm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22580) tst.l 4+FTEMP(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22581) bne is_denorm_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22582) is_zero_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22583) mov.b &ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22584) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22585) is_denorm_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22586) mov.b &DENORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22587) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22588) inf_or_nan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22589) and.l &0x000fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22590) bne is_nan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22591) tst.l 4+FTEMP(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22592) bne is_nan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22593) is_inf_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22594) mov.b &INF, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22595) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22596) is_nan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22597) btst &19, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22598) bne is_qnan_d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22599) is_snan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22600) mov.b &SNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22601) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22602) is_qnan_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22603) mov.b &QNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22604) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22606) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22607) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22608) # set_tag_s(): return the optype of the input sgl fp number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22609) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22610) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22611) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22612) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22613) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22614) # a0 = pointer to single precision operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22615) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22616) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22617) # d0 = value of type tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22618) # one of: NORM, INF, QNAN, SNAN, DENORM, ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22619) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22620) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22621) # Simply test the exponent, j-bit, and mantissa values to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22622) # determine the type of operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22623) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22624) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22626) global set_tag_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22627) set_tag_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22628) mov.l FTEMP(%a0), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22629) mov.l %d0, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22631) andi.l &0x7f800000, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22632) beq.b zero_or_denorm_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22634) cmpi.l %d0, &0x7f800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22635) beq.b inf_or_nan_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22637) is_norm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22638) mov.b &NORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22639) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22640) zero_or_denorm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22641) and.l &0x007fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22642) bne is_denorm_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22643) is_zero_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22644) mov.b &ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22645) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22646) is_denorm_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22647) mov.b &DENORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22648) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22649) inf_or_nan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22650) and.l &0x007fffff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22651) bne is_nan_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22652) is_inf_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22653) mov.b &INF, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22654) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22655) is_nan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22656) btst &22, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22657) bne is_qnan_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22658) is_snan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22659) mov.b &SNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22660) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22661) is_qnan_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22662) mov.b &QNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22663) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22665) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22666) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22667) # unf_res(): routine to produce default underflow result of a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22668) # scaled extended precision number; this is used by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22669) # fadd/fdiv/fmul/etc. emulation routines. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22670) # unf_res4(): same as above but for fsglmul/fsgldiv which use #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22671) # single round prec and extended prec mode. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22672) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22673) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22674) # _denorm() - denormalize according to scale factor #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22675) # _round() - round denormalized number according to rnd prec #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22676) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22677) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22678) # a0 = pointer to extended precison operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22679) # d0 = scale factor #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22680) # d1 = rounding precision/mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22681) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22682) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22683) # a0 = pointer to default underflow result in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22684) # d0.b = result FPSR_cc which caller may or may not want to save #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22685) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22686) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22687) # Convert the input operand to "internal format" which means the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22688) # exponent is extended to 16 bits and the sign is stored in the unused #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22689) # portion of the extended precison operand. Denormalize the number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22690) # according to the scale factor passed in d0. Then, round the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22691) # denormalized result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22692) # Set the FPSR_exc bits as appropriate but return the cc bits in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22693) # 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 22694) # fmove out). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22695) # unf_res4() for fsglmul/fsgldiv forces the denorm to extended #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22696) # precision and the rounding mode to single. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22697) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22698) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22699) global unf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22700) unf_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22701) mov.l %d1, -(%sp) # save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22703) btst &0x7, FTEMP_EX(%a0) # make "internal" format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22704) sne FTEMP_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22706) mov.w FTEMP_EX(%a0), %d1 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22707) and.w &0x7fff, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22708) sub.w %d0, %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22709) mov.w %d1, FTEMP_EX(%a0) # insert 16 bit exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22711) mov.l %a0, -(%sp) # save operand ptr during calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22713) mov.l 0x4(%sp),%d0 # pass rnd prec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22714) andi.w &0x00c0,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22715) lsr.w &0x4,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22716) bsr.l _denorm # denorm result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22718) mov.l (%sp),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22719) mov.w 0x6(%sp),%d1 # load prec:mode into %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22720) andi.w &0xc0,%d1 # extract rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22721) lsr.w &0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22722) swap %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22723) mov.w 0x6(%sp),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22724) andi.w &0x30,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22725) lsr.w &0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22726) bsr.l _round # round the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22728) mov.l (%sp)+, %a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22730) # result is now rounded properly. convert back to normal format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22731) bclr &0x7, FTEMP_EX(%a0) # clear sgn first; may have residue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22732) tst.b FTEMP_SGN(%a0) # is "internal result" sign set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22733) beq.b unf_res_chkifzero # no; result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22734) bset &0x7, FTEMP_EX(%a0) # set result sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22735) clr.b FTEMP_SGN(%a0) # clear temp sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22737) # the number may have become zero after rounding. set ccodes accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22738) unf_res_chkifzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22739) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22740) tst.l FTEMP_HI(%a0) # is value now a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22741) bne.b unf_res_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22742) tst.l FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22743) bne.b unf_res_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22744) # bset &z_bit, FPSR_CC(%a6) # yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22745) bset &z_bit, %d0 # yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22747) unf_res_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22749) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22750) # can inex1 also be set along with unfl and inex2???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22751) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22752) # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22753) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22754) btst &inex2_bit, FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22755) beq.b unf_res_end # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22756) bset &aunfl_bit, FPSR_AEXCEPT(%a6) # yes; set aunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22758) unf_res_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22759) add.l &0x4, %sp # clear stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22760) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22762) # unf_res() for fsglmul() and fsgldiv().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22763) global unf_res4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22764) unf_res4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22765) mov.l %d1,-(%sp) # save rnd prec,mode on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22767) btst &0x7,FTEMP_EX(%a0) # make "internal" format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22768) sne FTEMP_SGN(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22770) mov.w FTEMP_EX(%a0),%d1 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22771) and.w &0x7fff,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22772) sub.w %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22773) mov.w %d1,FTEMP_EX(%a0) # insert 16 bit exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22775) mov.l %a0,-(%sp) # save operand ptr during calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22777) clr.l %d0 # force rnd prec = ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22778) bsr.l _denorm # denorm result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22780) mov.l (%sp),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22781) mov.w &s_mode,%d1 # force rnd prec = sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22782) swap %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22783) mov.w 0x6(%sp),%d1 # load rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22784) andi.w &0x30,%d1 # extract rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22785) lsr.w &0x4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22786) bsr.l _round # round the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22788) mov.l (%sp)+,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22790) # result is now rounded properly. convert back to normal format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22791) bclr &0x7,FTEMP_EX(%a0) # clear sgn first; may have residue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22792) tst.b FTEMP_SGN(%a0) # is "internal result" sign set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22793) beq.b unf_res4_chkifzero # no; result is positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22794) bset &0x7,FTEMP_EX(%a0) # set result sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22795) clr.b FTEMP_SGN(%a0) # clear temp sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22797) # the number may have become zero after rounding. set ccodes accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22798) unf_res4_chkifzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22799) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22800) tst.l FTEMP_HI(%a0) # is value now a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22801) bne.b unf_res4_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22802) tst.l FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22803) bne.b unf_res4_cont # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22804) # bset &z_bit,FPSR_CC(%a6) # yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22805) bset &z_bit,%d0 # yes; set zero ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22807) unf_res4_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22809) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22810) # can inex1 also be set along with unfl and inex2???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22811) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22812) # we know that underflow has occurred. aunfl should be set if INEX2 is also set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22813) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22814) btst &inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22815) beq.b unf_res4_end # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22816) bset &aunfl_bit,FPSR_AEXCEPT(%a6) # yes; set aunfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22818) unf_res4_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22819) add.l &0x4,%sp # clear stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22820) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22822) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22823) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22824) # ovf_res(): routine to produce the default overflow result of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22825) # an overflowing number. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22826) # ovf_res2(): same as above but the rnd mode/prec are passed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22827) # differently. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22828) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22829) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22830) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22831) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22832) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22833) # d1.b = '-1' => (-); '0' => (+) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22834) # ovf_res(): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22835) # d0 = rnd mode/prec #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22836) # ovf_res2(): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22837) # hi(d0) = rnd prec #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22838) # lo(d0) = rnd mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22839) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22840) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22841) # a0 = points to extended precision result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22842) # d0.b = condition code bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22843) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22844) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22845) # The default overflow result can be determined by the sign of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22846) # the result and the rounding mode/prec in effect. These bits are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22847) # concatenated together to create an index into the default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22848) # table. A pointer to the correct result is returned in a0. The #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22849) # resulting condition codes are returned in d0 in case the caller #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22850) # doesn't want FPSR_cc altered (as is the case for fmove out). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22851) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22852) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22854) global ovf_res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22855) ovf_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22856) andi.w &0x10,%d1 # keep result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22857) lsr.b &0x4,%d0 # shift prec/mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22858) or.b %d0,%d1 # concat the two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22859) mov.w %d1,%d0 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22860) lsl.b &0x1,%d1 # multiply d1 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22861) bra.b ovf_res_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22863) global ovf_res2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22864) ovf_res2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22865) and.w &0x10, %d1 # keep result sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22866) or.b %d0, %d1 # insert rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22867) swap %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22868) or.b %d0, %d1 # insert rnd prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22869) mov.w %d1, %d0 # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22870) lsl.b &0x1, %d1 # shift left by 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22872) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22873) # use the rounding mode, precision, and result sign as in index into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22874) # two tables below to fetch the default result and the result ccodes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22875) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22876) ovf_res_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22877) mov.b (tbl_ovfl_cc.b,%pc,%d0.w*1), %d0 # fetch result ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22878) lea (tbl_ovfl_result.b,%pc,%d1.w*8), %a0 # return result ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22880) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22882) tbl_ovfl_cc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22883) byte 0x2, 0x0, 0x0, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22884) byte 0x2, 0x0, 0x0, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22885) byte 0x2, 0x0, 0x0, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22886) byte 0x0, 0x0, 0x0, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22887) byte 0x2+0x8, 0x8, 0x2+0x8, 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22888) byte 0x2+0x8, 0x8, 0x2+0x8, 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22889) byte 0x2+0x8, 0x8, 0x2+0x8, 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22891) tbl_ovfl_result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22892) long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22893) long 0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22894) long 0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22895) long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22897) long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22898) long 0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22899) long 0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22900) long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22902) long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22903) long 0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22904) long 0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22905) long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22907) long 0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22908) long 0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22909) long 0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22910) long 0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22912) long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22913) long 0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22914) long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22915) long 0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22917) long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22918) long 0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22919) long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22920) long 0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22922) long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22923) long 0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22924) long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22925) long 0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22927) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22928) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22929) # get_packed(): fetch a packed operand from memory and then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22930) # convert it to a floating-point binary number. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22931) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22932) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22933) # _dcalc_ea() - calculate the correct <ea> #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22934) # _mem_read() - fetch the packed operand from memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22935) # facc_in_x() - the fetch failed so jump to special exit code #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22936) # decbin() - convert packed to binary extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22937) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22938) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22939) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22940) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22941) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22942) # If no failure on _mem_read(): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22943) # FP_SRC(a6) = packed operand now as a binary FP number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22944) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22945) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22946) # Get the correct <ea> which is the value on the exception stack #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22947) # frame w/ maybe a correction factor if the <ea> is -(an) or (an)+. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22948) # Then, fetch the operand from memory. If the fetch fails, exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22949) # through facc_in_x(). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22950) # If the packed operand is a ZERO,NAN, or INF, convert it to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22951) # its binary representation here. Else, call decbin() which will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22952) # convert the packed value to an extended precision binary value. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22953) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22954) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22956) # the stacked <ea> for packed is correct except for -(An).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22957) # the base reg must be updated for both -(An) and (An)+.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22958) global get_packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22959) get_packed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22960) mov.l &0xc,%d0 # packed is 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22961) bsr.l _dcalc_ea # fetch <ea>; correct An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22963) lea FP_SRC(%a6),%a1 # pass: ptr to super dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22964) mov.l &0xc,%d0 # pass: 12 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22965) bsr.l _dmem_read # read packed operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22967) tst.l %d1 # did dfetch fail?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22968) bne.l facc_in_x # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22970) # 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 22971) bfextu FP_SRC(%a6){&1:&15},%d0 # get exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22972) cmpi.w %d0,&0x7fff # INF or NAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22973) bne.b gp_try_zero # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22974) rts # operand is an INF or NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22976) # The packed operand is a zero if the mantissa is all zero, else it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22977) # a normal packed op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22978) gp_try_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22979) mov.b 3+FP_SRC(%a6),%d0 # get byte 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22980) andi.b &0x0f,%d0 # clear all but last nybble
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22981) bne.b gp_not_spec # not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22982) tst.l FP_SRC_HI(%a6) # is lw 2 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22983) bne.b gp_not_spec # not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22984) tst.l FP_SRC_LO(%a6) # is lw 3 zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22985) bne.b gp_not_spec # not a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22986) rts # operand is a ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22987) gp_not_spec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22988) lea FP_SRC(%a6),%a0 # pass: ptr to packed op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22989) bsr.l decbin # convert to extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22990) fmovm.x &0x80,FP_SRC(%a6) # make this the srcop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22991) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22993) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22994) # decbin(): Converts normalized packed bcd value pointed to by register #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22995) # a0 to extended-precision value in fp0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22996) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22997) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22998) # a0 = pointer to normalized packed bcd value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22999) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23000) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23001) # fp0 = exact fp representation of the packed bcd value. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23002) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23003) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23004) # Expected is a normal bcd (i.e. non-exceptional; all inf, zero, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23005) # and NaN operands are dispatched without entering this routine) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23006) # value in 68881/882 format at location (a0). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23007) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23008) # A1. Convert the bcd exponent to binary by successive adds and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23009) # muls. Set the sign according to SE. Subtract 16 to compensate #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23010) # for the mantissa which is to be interpreted as 17 integer #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23011) # digits, rather than 1 integer and 16 fraction digits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23012) # Note: this operation can never overflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23013) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23014) # A2. Convert the bcd mantissa to binary by successive #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23015) # adds and muls in FP0. Set the sign according to SM. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23016) # The mantissa digits will be converted with the decimal point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23017) # assumed following the least-significant digit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23018) # Note: this operation can never overflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23019) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23020) # A3. Count the number of leading/trailing zeros in the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23021) # bcd string. If SE is positive, count the leading zeros; #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23022) # if negative, count the trailing zeros. Set the adjusted #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23023) # exponent equal to the exponent from A1 and the zero count #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23024) # added if SM = 1 and subtracted if SM = 0. Scale the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23025) # mantissa the equivalent of forcing in the bcd value: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23026) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23027) # SM = 0 a non-zero digit in the integer position #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23028) # SM = 1 a non-zero digit in Mant0, lsd of the fraction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23029) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23030) # this will insure that any value, regardless of its #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23031) # representation (ex. 0.1E2, 1E1, 10E0, 100E-1), is converted #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23032) # consistently. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23033) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23034) # A4. Calculate the factor 10^exp in FP1 using a table of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23035) # 10^(2^n) values. To reduce the error in forming factors #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23036) # greater than 10^27, a directed rounding scheme is used with #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23037) # tables rounded to RN, RM, and RP, according to the table #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23038) # in the comments of the pwrten section. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23039) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23040) # A5. Form the final binary number by scaling the mantissa by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23041) # the exponent factor. This is done by multiplying the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23042) # mantissa in FP0 by the factor in FP1 if the adjusted #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23043) # exponent sign is positive, and dividing FP0 by FP1 if #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23044) # it is negative. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23045) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23046) # Clean up and return. Check if the final mul or div was inexact. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23047) # If so, set INEX1 in USER_FPSR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23048) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23049) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23051) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23052) # PTENRN, PTENRM, and PTENRP are arrays of powers of 10 rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23053) # to nearest, minus, and plus, respectively. The tables include
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23054) # 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 23055) # is required until the power is greater than 27, however, all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23056) # tables include the first 5 for ease of indexing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23057) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23058) RTABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23059) byte 0,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23060) byte 2,3,2,3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23061) byte 2,3,3,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23062) byte 3,2,2,3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23064) set FNIBS,7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23065) set FSTRT,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23067) set ESTRT,4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23068) set EDIGITS,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23070) global decbin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23071) decbin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23072) mov.l 0x0(%a0),FP_SCR0_EX(%a6) # make a copy of input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23073) mov.l 0x4(%a0),FP_SCR0_HI(%a6) # so we don't alter it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23074) mov.l 0x8(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23076) lea FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23078) movm.l &0x3c00,-(%sp) # save d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23079) fmovm.x &0x1,-(%sp) # save fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23080) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23081) # Calculate exponent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23082) # 1. Copy bcd value in memory for use as a working copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23083) # 2. Calculate absolute value of exponent in d1 by mul and add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23084) # 3. Correct for exponent sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23085) # 4. Subtract 16 to compensate for interpreting the mant as all integer digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23086) # (i.e., all digits assumed left of the decimal point.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23087) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23088) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23089) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23090) # calc_e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23091) # (*) d0: temp digit storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23092) # (*) d1: accumulator for binary exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23093) # (*) d2: digit count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23094) # (*) d3: offset pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23095) # ( ) d4: first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23096) # ( ) a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23097) # ( ) a6: pointer to original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23098) # (*) FP_SCR1: working copy of original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23099) # (*) L_SCR1: copy of original exponent word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23100) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23101) calc_e:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23102) mov.l &EDIGITS,%d2 # # of nibbles (digits) in fraction part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23103) mov.l &ESTRT,%d3 # counter to pick up digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23104) mov.l (%a0),%d4 # get first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23105) clr.l %d1 # zero d1 for accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23106) e_gd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23107) mulu.l &0xa,%d1 # mul partial product by one digit place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23108) bfextu %d4{%d3:&4},%d0 # get the digit and zero extend into d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23109) add.l %d0,%d1 # d1 = d1 + d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23110) addq.b &4,%d3 # advance d3 to the next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23111) dbf.w %d2,e_gd # if we have used all 3 digits, exit loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23112) btst &30,%d4 # get SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23113) beq.b e_pos # don't negate if pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23114) neg.l %d1 # negate before subtracting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23115) e_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23116) sub.l &16,%d1 # sub to compensate for shift of mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23117) bge.b e_save # if still pos, do not neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23118) neg.l %d1 # now negative, make pos and set SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23119) or.l &0x40000000,%d4 # set SE in d4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23120) or.l &0x40000000,(%a0) # and in working bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23121) e_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23122) mov.l %d1,-(%sp) # save exp on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23123) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23124) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23125) # Calculate mantissa:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23126) # 1. Calculate absolute value of mantissa in fp0 by mul and add.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23127) # 2. Correct for mantissa sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23128) # (i.e., all digits assumed left of the decimal point.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23129) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23130) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23131) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23132) # calc_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23133) # (*) d0: temp digit storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23134) # (*) d1: lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23135) # (*) d2: digit count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23136) # (*) d3: offset pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23137) # ( ) d4: words 2 and 3 of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23138) # ( ) a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23139) # ( ) a6: pointer to original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23140) # (*) fp0: mantissa accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23141) # ( ) FP_SCR1: working copy of original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23142) # ( ) L_SCR1: copy of original exponent word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23143) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23144) calc_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23145) mov.l &1,%d1 # word counter, init to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23146) fmov.s &0x00000000,%fp0 # accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23147) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23148) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23149) # Since the packed number has a long word between the first & second parts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23150) # get the integer digit then skip down & get the rest of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23151) # mantissa. We will unroll the loop once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23152) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23153) bfextu (%a0){&28:&4},%d0 # integer part is ls digit in long word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23154) fadd.b %d0,%fp0 # add digit to sum in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23155) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23156) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23157) # Get the rest of the mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23158) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23159) loadlw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23160) mov.l (%a0,%d1.L*4),%d4 # load mantissa lonqword into d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23161) mov.l &FSTRT,%d3 # counter to pick up digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23162) mov.l &FNIBS,%d2 # reset number of digits per a0 ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23163) md2b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23164) fmul.s &0x41200000,%fp0 # fp0 = fp0 * 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23165) bfextu %d4{%d3:&4},%d0 # get the digit and zero extend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23166) fadd.b %d0,%fp0 # fp0 = fp0 + digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23167) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23168) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23169) # If all the digits (8) in that long word have been converted (d2=0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23170) # 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 23171) # to initialize the digit offset, and set d2 to 7 for the digit count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23172) # else continue with this long word.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23173) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23174) addq.b &4,%d3 # advance d3 to the next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23175) dbf.w %d2,md2b # check for last digit in this lw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23176) nextlw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23177) addq.l &1,%d1 # inc lw pointer in mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23178) cmp.l %d1,&2 # test for last lw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23179) ble.b loadlw # if not, get last one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23180) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23181) # Check the sign of the mant and make the value in fp0 the same sign.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23182) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23183) m_sign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23184) btst &31,(%a0) # test sign of the mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23185) beq.b ap_st_z # if clear, go to append/strip zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23186) fneg.x %fp0 # if set, negate fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23187) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23188) # Append/strip zeros:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23189) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23190) # For adjusted exponents which have an absolute value greater than 27*,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23191) # this routine calculates the amount needed to normalize the mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23192) # for the adjusted exponent. That number is subtracted from the exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23193) # if the exp was positive, and added if it was negative. The purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23194) # of this is to reduce the value of the exponent and the possibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23195) # of error in calculation of pwrten.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23196) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23197) # 1. Branch on the sign of the adjusted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23198) # 2p.(positive exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23199) # 2. Check M16 and the digits in lwords 2 and 3 in descending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23200) # 3. Add one for each zero encountered until a non-zero digit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23201) # 4. Subtract the count from the exp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23202) # 5. Check if the exp has crossed zero in #3 above; make the exp abs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23203) # and set SE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23204) # 6. Multiply the mantissa by 10**count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23205) # 2n.(negative exp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23206) # 2. Check the digits in lwords 3 and 2 in descending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23207) # 3. Add one for each zero encountered until a non-zero digit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23208) # 4. Add the count to the exp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23209) # 5. Check if the exp has crossed zero in #3 above; clear SE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23210) # 6. Divide the mantissa by 10**count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23211) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23212) # *Why 27? If the adjusted exponent is within -28 < expA < 28, than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23213) # any adjustment due to append/strip zeros will drive the resultane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23214) # exponent towards zero. Since all pwrten constants with a power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23215) # of 27 or less are exact, there is no need to use this routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23216) # attempt to lessen the resultant exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23217) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23218) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23219) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23220) # ap_st_z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23221) # (*) d0: temp digit storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23222) # (*) d1: zero count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23223) # (*) d2: digit count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23224) # (*) d3: offset pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23225) # ( ) d4: first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23226) # (*) d5: lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23227) # ( ) a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23228) # ( ) FP_SCR1: working copy of original bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23229) # ( ) L_SCR1: copy of original exponent word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23230) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23231) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23232) # First check the absolute value of the exponent to see if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23233) # routine is necessary. If so, then check the sign of the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23234) # and do append (+) or strip (-) zeros accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23235) # This section handles a positive adjusted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23236) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23237) ap_st_z:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23238) mov.l (%sp),%d1 # load expA for range test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23239) cmp.l %d1,&27 # test is with 27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23240) ble.w pwrten # if abs(expA) <28, skip ap/st zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23241) btst &30,(%a0) # check sign of exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23242) bne.b ap_st_n # if neg, go to neg side
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23243) clr.l %d1 # zero count reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23244) mov.l (%a0),%d4 # load lword 1 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23245) bfextu %d4{&28:&4},%d0 # get M16 in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23246) bne.b ap_p_fx # if M16 is non-zero, go fix exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23247) addq.l &1,%d1 # inc zero count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23248) mov.l &1,%d5 # init lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23249) mov.l (%a0,%d5.L*4),%d4 # get lword 2 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23250) bne.b ap_p_cl # if lw 2 is zero, skip it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23251) addq.l &8,%d1 # and inc count by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23252) addq.l &1,%d5 # inc lword counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23253) mov.l (%a0,%d5.L*4),%d4 # get lword 3 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23254) ap_p_cl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23255) clr.l %d3 # init offset reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23256) mov.l &7,%d2 # init digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23257) ap_p_gd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23258) bfextu %d4{%d3:&4},%d0 # get digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23259) bne.b ap_p_fx # if non-zero, go to fix exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23260) addq.l &4,%d3 # point to next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23261) addq.l &1,%d1 # inc digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23262) dbf.w %d2,ap_p_gd # get next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23263) ap_p_fx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23264) mov.l %d1,%d0 # copy counter to d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23265) mov.l (%sp),%d1 # get adjusted exp from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23266) sub.l %d0,%d1 # subtract count from exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23267) bge.b ap_p_fm # if still pos, go to pwrten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23268) neg.l %d1 # now its neg; get abs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23269) mov.l (%a0),%d4 # load lword 1 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23270) or.l &0x40000000,%d4 # and set SE in d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23271) or.l &0x40000000,(%a0) # and in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23272) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23273) # Calculate the mantissa multiplier to compensate for the striping of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23274) # zeros from the mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23275) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23276) ap_p_fm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23277) lea.l PTENRN(%pc),%a1 # get address of power-of-ten table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23278) clr.l %d3 # init table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23279) fmov.s &0x3f800000,%fp1 # init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23280) mov.l &3,%d2 # init d2 to count bits in counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23281) ap_p_el:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23282) asr.l &1,%d0 # shift lsb into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23283) bcc.b ap_p_en # if 1, mul fp1 by pwrten factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23284) fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23285) ap_p_en:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23286) add.l &12,%d3 # inc d3 to next rtable entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23287) tst.l %d0 # check if d0 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23288) bne.b ap_p_el # if not, get next bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23289) fmul.x %fp1,%fp0 # mul mantissa by 10**(no_bits_shifted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23290) bra.b pwrten # go calc pwrten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23291) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23292) # This section handles a negative adjusted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23293) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23294) ap_st_n:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23295) clr.l %d1 # clr counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23296) mov.l &2,%d5 # set up d5 to point to lword 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23297) mov.l (%a0,%d5.L*4),%d4 # get lword 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23298) bne.b ap_n_cl # if not zero, check digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23299) sub.l &1,%d5 # dec d5 to point to lword 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23300) addq.l &8,%d1 # inc counter by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23301) mov.l (%a0,%d5.L*4),%d4 # get lword 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23302) ap_n_cl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23303) mov.l &28,%d3 # point to last digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23304) mov.l &7,%d2 # init digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23305) ap_n_gd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23306) bfextu %d4{%d3:&4},%d0 # get digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23307) bne.b ap_n_fx # if non-zero, go to exp fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23308) subq.l &4,%d3 # point to previous digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23309) addq.l &1,%d1 # inc digit counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23310) dbf.w %d2,ap_n_gd # get next digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23311) ap_n_fx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23312) mov.l %d1,%d0 # copy counter to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23313) mov.l (%sp),%d1 # get adjusted exp from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23314) sub.l %d0,%d1 # subtract count from exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23315) bgt.b ap_n_fm # if still pos, go fix mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23316) neg.l %d1 # take abs of exp and clr SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23317) mov.l (%a0),%d4 # load lword 1 to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23318) and.l &0xbfffffff,%d4 # and clr SE in d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23319) and.l &0xbfffffff,(%a0) # and in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23320) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23321) # Calculate the mantissa multiplier to compensate for the appending of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23322) # zeros to the mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23323) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23324) ap_n_fm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23325) lea.l PTENRN(%pc),%a1 # get address of power-of-ten table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23326) clr.l %d3 # init table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23327) fmov.s &0x3f800000,%fp1 # init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23328) mov.l &3,%d2 # init d2 to count bits in counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23329) ap_n_el:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23330) asr.l &1,%d0 # shift lsb into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23331) bcc.b ap_n_en # if 1, mul fp1 by pwrten factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23332) fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23333) ap_n_en:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23334) add.l &12,%d3 # inc d3 to next rtable entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23335) tst.l %d0 # check if d0 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23336) bne.b ap_n_el # if not, get next bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23337) fdiv.x %fp1,%fp0 # div mantissa by 10**(no_bits_shifted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23338) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23339) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23340) # Calculate power-of-ten factor from adjusted and shifted exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23341) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23342) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23343) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23344) # pwrten:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23345) # (*) d0: temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23346) # ( ) d1: exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23347) # (*) d2: {FPCR[6:5],SM,SE} as index in RTABLE; temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23348) # (*) d3: FPCR work copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23349) # ( ) d4: first word of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23350) # (*) a1: RTABLE pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23351) # calc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23352) # (*) d0: temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23353) # ( ) d1: exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23354) # (*) d3: PWRTxx table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23355) # ( ) a0: pointer to working copy of bcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23356) # (*) a1: PWRTxx pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23357) # (*) fp1: power-of-ten accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23358) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23359) # Pwrten calculates the exponent factor in the selected rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23360) # according to the following table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23361) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23362) # Sign of Mant Sign of Exp Rounding Mode PWRTEN Rounding Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23363) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23364) # ANY ANY RN RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23365) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23366) # + + RP RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23367) # - + RP RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23368) # + - RP RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23369) # - - RP RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23370) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23371) # + + RM RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23372) # - + RM RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23373) # + - RM RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23374) # - - RM RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23375) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23376) # + + RZ RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23377) # - + RZ RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23378) # + - RZ RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23379) # - - RZ RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23380) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23381) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23382) pwrten:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23383) mov.l USER_FPCR(%a6),%d3 # get user's FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23384) bfextu %d3{&26:&2},%d2 # isolate rounding mode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23385) mov.l (%a0),%d4 # reload 1st bcd word to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23386) asl.l &2,%d2 # format d2 to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23387) bfextu %d4{&0:&2},%d0 # {FPCR[6],FPCR[5],SM,SE}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23388) add.l %d0,%d2 # in d2 as index into RTABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23389) lea.l RTABLE(%pc),%a1 # load rtable base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23390) mov.b (%a1,%d2),%d0 # load new rounding bits from table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23391) clr.l %d3 # clear d3 to force no exc and extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23392) bfins %d0,%d3{&26:&2} # stuff new rounding bits in FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23393) fmov.l %d3,%fpcr # write new FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23394) asr.l &1,%d0 # write correct PTENxx table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23395) bcc.b not_rp # to a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23396) lea.l PTENRP(%pc),%a1 # it is RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23397) bra.b calc_p # go to init section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23398) not_rp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23399) asr.l &1,%d0 # keep checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23400) bcc.b not_rm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23401) lea.l PTENRM(%pc),%a1 # it is RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23402) bra.b calc_p # go to init section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23403) not_rm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23404) lea.l PTENRN(%pc),%a1 # it is RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23405) calc_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23406) mov.l %d1,%d0 # copy exp to d0;use d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23407) bpl.b no_neg # if exp is negative,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23408) neg.l %d0 # invert it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23409) or.l &0x40000000,(%a0) # and set SE bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23410) no_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23411) clr.l %d3 # table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23412) fmov.s &0x3f800000,%fp1 # init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23413) e_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23414) asr.l &1,%d0 # shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23415) bcc.b e_next # if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23416) fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23417) e_next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23418) add.l &12,%d3 # inc d3 to next rtable entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23419) tst.l %d0 # check if d0 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23420) bne.b e_loop # not zero, continue shifting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23421) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23422) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23423) # Check the sign of the adjusted exp and make the value in fp0 the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23424) # same sign. If the exp was pos then multiply fp1*fp0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23425) # else divide fp0/fp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23426) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23427) # Register Usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23428) # norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23429) # ( ) a0: pointer to working bcd value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23430) # (*) fp0: mantissa accumulator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23431) # ( ) fp1: scaling factor - 10**(abs(exp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23432) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23433) pnorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23434) btst &30,(%a0) # test the sign of the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23435) beq.b mul # if clear, go to multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23436) div:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23437) fdiv.x %fp1,%fp0 # exp is negative, so divide mant by exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23438) bra.b end_dec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23439) mul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23440) fmul.x %fp1,%fp0 # exp is positive, so multiply by exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23441) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23442) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23443) # Clean up and return with result in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23444) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23445) # If the final mul/div in decbin incurred an inex exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23446) # it will be inex2, but will be reported as inex1 by get_op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23447) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23448) end_dec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23449) fmov.l %fpsr,%d0 # get status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23450) bclr &inex2_bit+8,%d0 # test for inex2 and clear it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23451) beq.b no_exc # skip this if no exc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23452) ori.w &inx1a_mask,2+USER_FPSR(%a6) # set INEX1/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23453) no_exc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23454) add.l &0x4,%sp # clear 1 lw param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23455) fmovm.x (%sp)+,&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23456) movm.l (%sp)+,&0x3c # restore d2-d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23457) fmov.l &0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23458) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23459) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23461) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23462) # bindec(): Converts an input in extended precision format to bcd format#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23463) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23464) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23465) # a0 = pointer to the input extended precision value in memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23466) # the input may be either normalized, unnormalized, or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23467) # denormalized. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23468) # d0 = contains the k-factor sign-extended to 32-bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23469) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23470) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23471) # FP_SCR0(a6) = bcd format result on the stack. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23472) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23473) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23474) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23475) # A1. Set RM and size ext; Set SIGMA = sign of input. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23476) # The k-factor is saved for use in d7. Clear the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23477) # BINDEC_FLG for separating normalized/denormalized #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23478) # input. If input is unnormalized or denormalized, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23479) # normalize it. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23480) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23481) # A2. Set X = abs(input). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23482) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23483) # A3. Compute ILOG. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23484) # ILOG is the log base 10 of the input value. It is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23485) # approximated by adding e + 0.f when the original #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23486) # value is viewed as 2^^e * 1.f in extended precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23487) # This value is stored in d6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23488) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23489) # A4. Clr INEX bit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23490) # The operation in A3 above may have set INEX2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23491) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23492) # A5. Set ICTR = 0; #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23493) # ICTR is a flag used in A13. It must be set before the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23494) # loop entry A6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23495) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23496) # A6. Calculate LEN. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23497) # LEN is the number of digits to be displayed. The #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23498) # k-factor can dictate either the total number of digits, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23499) # if it is a positive number, or the number of digits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23500) # after the decimal point which are to be included as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23501) # significant. See the 68882 manual for examples. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23502) # If LEN is computed to be greater than 17, set OPERR in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23503) # USER_FPSR. LEN is stored in d4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23504) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23505) # A7. Calculate SCALE. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23506) # SCALE is equal to 10^ISCALE, where ISCALE is the number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23507) # of decimal places needed to insure LEN integer digits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23508) # in the output before conversion to bcd. LAMBDA is the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23509) # sign of ISCALE, used in A9. Fp1 contains #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23510) # 10^^(abs(ISCALE)) using a rounding mode which is a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23511) # function of the original rounding mode and the signs #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23512) # of ISCALE and X. A table is given in the code. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23513) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23514) # A8. Clr INEX; Force RZ. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23515) # The operation in A3 above may have set INEX2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23516) # RZ mode is forced for the scaling operation to insure #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23517) # only one rounding error. The grs bits are collected in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23518) # the INEX flag for use in A10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23519) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23520) # A9. Scale X -> Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23521) # The mantissa is scaled to the desired number of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23522) # significant digits. The excess digits are collected #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23523) # in INEX2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23524) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23525) # A10. Or in INEX. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23526) # If INEX is set, round error occurred. This is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23527) # compensated for by 'or-ing' in the INEX2 flag to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23528) # the lsb of Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23529) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23530) # A11. Restore original FPCR; set size ext. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23531) # Perform FINT operation in the user's rounding mode. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23532) # Keep the size to extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23533) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23534) # A12. Calculate YINT = FINT(Y) according to user's rounding #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23535) # mode. The FPSP routine sintd0 is used. The output #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23536) # is in fp0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23537) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23538) # A13. Check for LEN digits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23539) # If the int operation results in more than LEN digits, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23540) # or less than LEN -1 digits, adjust ILOG and repeat from #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23541) # A6. This test occurs only on the first pass. If the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23542) # result is exactly 10^LEN, decrement ILOG and divide #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23543) # the mantissa by 10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23544) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23545) # A14. Convert the mantissa to bcd. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23546) # The binstr routine is used to convert the LEN digit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23547) # mantissa to bcd in memory. The input to binstr is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23548) # to be a fraction; i.e. (mantissa)/10^LEN and adjusted #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23549) # such that the decimal point is to the left of bit 63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23550) # The bcd digits are stored in the correct position in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23551) # the final string area in memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23552) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23553) # A15. Convert the exponent to bcd. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23554) # As in A14 above, the exp is converted to bcd and the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23555) # digits are stored in the final string. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23556) # Test the length of the final exponent string. If the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23557) # length is 4, set operr. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23558) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23559) # A16. Write sign bits to final string. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23560) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23561) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23563) set BINDEC_FLG, EXC_TEMP # DENORM flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23565) # Constants in extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23566) PLOG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23567) long 0x3FFD0000,0x9A209A84,0xFBCFF798,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23568) PLOG2UP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23569) long 0x3FFD0000,0x9A209A84,0xFBCFF799,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23571) # Constants in single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23572) FONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23573) long 0x3F800000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23574) FTWO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23575) long 0x40000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23576) FTEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23577) long 0x41200000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23578) F4933:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23579) long 0x459A2800,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23581) RBDTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23582) byte 0,0,0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23583) byte 3,3,2,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23584) byte 3,2,2,3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23585) byte 2,3,3,2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23587) # Implementation Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23588) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23589) # The registers are used as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23590) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23591) # d0: scratch; LEN input to binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23592) # d1: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23593) # d2: upper 32-bits of mantissa for binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23594) # d3: scratch;lower 32-bits of mantissa for binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23595) # d4: LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23596) # d5: LAMBDA/ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23597) # d6: ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23598) # d7: k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23599) # a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23600) # a1: scratch pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23601) # a2: pointer to FP_X; abs(original value) in ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23602) # fp0: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23603) # fp1: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23604) # fp2: scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23605) # F_SCR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23606) # F_SCR2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23607) # L_SCR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23608) # L_SCR2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23610) global bindec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23611) bindec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23612) movm.l &0x3f20,-(%sp) # {%d2-%d7/%a2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23613) fmovm.x &0x7,-(%sp) # {%fp0-%fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23615) # A1. Set RM and size ext. Set SIGMA = sign input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23616) # The k-factor is saved for use in d7. Clear BINDEC_FLG for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23617) # separating normalized/denormalized input. If the input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23618) # is a denormalized number, set the BINDEC_FLG memory word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23619) # to signal denorm. If the input is unnormalized, normalize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23620) # the input and test for denormalized result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23621) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23622) fmov.l &rm_mode*0x10,%fpcr # set RM and ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23623) mov.l (%a0),L_SCR2(%a6) # save exponent for sign check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23624) mov.l %d0,%d7 # move k-factor to d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23626) clr.b BINDEC_FLG(%a6) # clr norm/denorm flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23627) cmpi.b STAG(%a6),&DENORM # is input a DENORM?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23628) bne.w A2_str # no; input is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23630) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23631) # Normalize the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23632) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23633) un_de_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23634) mov.w (%a0),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23635) and.w &0x7fff,%d0 # strip sign of normalized exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23636) mov.l 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23637) mov.l 8(%a0),%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23638) norm_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23639) sub.w &1,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23640) lsl.l &1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23641) roxl.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23642) tst.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23643) bge.b norm_loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23644) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23645) # Test if the normalized input is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23646) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23647) tst.w %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23648) bgt.b pos_exp # if greater than zero, it is a norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23649) st BINDEC_FLG(%a6) # set flag for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23650) pos_exp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23651) and.w &0x7fff,%d0 # strip sign of normalized exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23652) mov.w %d0,(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23653) mov.l %d1,4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23654) mov.l %d2,8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23656) # A2. Set X = abs(input).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23657) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23658) A2_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23659) mov.l (%a0),FP_SCR1(%a6) # move input to work space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23660) mov.l 4(%a0),FP_SCR1+4(%a6) # move input to work space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23661) mov.l 8(%a0),FP_SCR1+8(%a6) # move input to work space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23662) and.l &0x7fffffff,FP_SCR1(%a6) # create abs(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23664) # A3. Compute ILOG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23665) # ILOG is the log base 10 of the input value. It is approx-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23666) # imated by adding e + 0.f when the original value is viewed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23667) # as 2^^e * 1.f in extended precision. This value is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23668) # in d6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23669) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23670) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23671) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23672) # d0: k-factor/exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23673) # d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23674) # d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23675) # d4: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23676) # d5: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23677) # d6: x/ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23678) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23679) # a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23680) # a1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23681) # a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23682) # fp0: x/float(ILOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23683) # fp1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23684) # fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23685) # F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23686) # F_SCR2:Abs(X)/Abs(X) with $3fff exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23687) # L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23688) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23690) tst.b BINDEC_FLG(%a6) # check for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23691) beq.b A3_cont # if clr, continue with norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23692) mov.l &-4933,%d6 # force ILOG = -4933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23693) bra.b A4_str
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23694) A3_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23695) mov.w FP_SCR1(%a6),%d0 # move exp to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23696) mov.w &0x3fff,FP_SCR1(%a6) # replace exponent with 0x3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23697) fmov.x FP_SCR1(%a6),%fp0 # now fp0 has 1.f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23698) sub.w &0x3fff,%d0 # strip off bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23699) fadd.w %d0,%fp0 # add in exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23700) fsub.s FONE(%pc),%fp0 # subtract off 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23701) fbge.w pos_res # if pos, branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23702) fmul.x PLOG2UP1(%pc),%fp0 # if neg, mul by LOG2UP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23703) fmov.l %fp0,%d6 # put ILOG in d6 as a lword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23704) bra.b A4_str # go move out ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23705) pos_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23706) fmul.x PLOG2(%pc),%fp0 # if pos, mul by LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23707) fmov.l %fp0,%d6 # put ILOG in d6 as a lword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23710) # A4. Clr INEX bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23711) # The operation in A3 above may have set INEX2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23713) A4_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23714) fmov.l &0,%fpsr # zero all of fpsr - nothing needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23717) # A5. Set ICTR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23718) # ICTR is a flag used in A13. It must be set before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23719) # loop entry A6. The lower word of d5 is used for ICTR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23721) clr.w %d5 # clear ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23723) # A6. Calculate LEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23724) # LEN is the number of digits to be displayed. The k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23725) # can dictate either the total number of digits, if it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23726) # a positive number, or the number of digits after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23727) # original decimal point which are to be included as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23728) # significant. See the 68882 manual for examples.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23729) # If LEN is computed to be greater than 17, set OPERR in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23730) # USER_FPSR. LEN is stored in d4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23731) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23732) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23733) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23734) # d0: exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23735) # d2: x/x/scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23736) # d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23737) # d4: exc picture/LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23738) # d5: ICTR/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23739) # d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23740) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23741) # a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23742) # a1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23743) # a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23744) # fp0: float(ILOG)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23745) # fp1: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23746) # fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23747) # F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23748) # F_SCR2:Abs(X) with $3fff exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23749) # L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23750) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23752) A6_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23753) tst.l %d7 # branch on sign of k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23754) ble.b k_neg # if k <= 0, LEN = ILOG + 1 - k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23755) mov.l %d7,%d4 # if k > 0, LEN = k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23756) bra.b len_ck # skip to LEN check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23757) k_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23758) mov.l %d6,%d4 # first load ILOG to d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23759) sub.l %d7,%d4 # subtract off k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23760) addq.l &1,%d4 # add in the 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23761) len_ck:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23762) tst.l %d4 # LEN check: branch on sign of LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23763) ble.b LEN_ng # if neg, set LEN = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23764) cmp.l %d4,&17 # test if LEN > 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23765) ble.b A7_str # if not, forget it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23766) mov.l &17,%d4 # set max LEN = 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23767) tst.l %d7 # if negative, never set OPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23768) ble.b A7_str # if positive, continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23769) or.l &opaop_mask,USER_FPSR(%a6) # set OPERR & AIOP in USER_FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23770) bra.b A7_str # finished here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23771) LEN_ng:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23772) mov.l &1,%d4 # min LEN is 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23775) # A7. Calculate SCALE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23776) # SCALE is equal to 10^ISCALE, where ISCALE is the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23777) # of decimal places needed to insure LEN integer digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23778) # in the output before conversion to bcd. LAMBDA is the sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23779) # of ISCALE, used in A9. Fp1 contains 10^^(abs(ISCALE)) using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23780) # the rounding mode as given in the following table (see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23781) # Coonen, p. 7.23 as ref.; however, the SCALE variable is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23782) # of opposite sign in bindec.sa from Coonen).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23783) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23784) # Initial USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23785) # FPCR[6:5] LAMBDA SIGN(X) FPCR[6:5]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23786) # ----------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23787) # RN 00 0 0 00/0 RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23788) # RN 00 0 1 00/0 RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23789) # RN 00 1 0 00/0 RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23790) # RN 00 1 1 00/0 RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23791) # RZ 01 0 0 11/3 RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23792) # RZ 01 0 1 11/3 RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23793) # RZ 01 1 0 10/2 RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23794) # RZ 01 1 1 10/2 RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23795) # RM 10 0 0 11/3 RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23796) # RM 10 0 1 10/2 RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23797) # RM 10 1 0 10/2 RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23798) # RM 10 1 1 11/3 RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23799) # RP 11 0 0 10/2 RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23800) # RP 11 0 1 11/3 RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23801) # RP 11 1 0 11/3 RP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23802) # RP 11 1 1 10/2 RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23803) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23804) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23805) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23806) # d0: exponent/scratch - final is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23807) # d2: x/0 or 24 for A9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23808) # d3: x/scratch - offset ptr into PTENRM array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23809) # d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23810) # d5: 0/ICTR:LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23811) # d6: ILOG/ILOG or k if ((k<=0)&(ILOG<k))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23812) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23813) # a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23814) # a1: x/ptr to PTENRM array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23815) # a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23816) # fp0: float(ILOG)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23817) # fp1: x/10^ISCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23818) # fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23819) # F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23820) # F_SCR2:Abs(X) with $3fff exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23821) # L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23822) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23824) A7_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23825) tst.l %d7 # test sign of k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23826) bgt.b k_pos # if pos and > 0, skip this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23827) cmp.l %d7,%d6 # test k - ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23828) blt.b k_pos # if ILOG >= k, skip this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23829) mov.l %d7,%d6 # if ((k<0) & (ILOG < k)) ILOG = k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23830) k_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23831) mov.l %d6,%d0 # calc ILOG + 1 - LEN in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23832) addq.l &1,%d0 # add the 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23833) sub.l %d4,%d0 # sub off LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23834) swap %d5 # use upper word of d5 for LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23835) clr.w %d5 # set it zero initially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23836) clr.w %d2 # set up d2 for very small case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23837) tst.l %d0 # test sign of ISCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23838) bge.b iscale # if pos, skip next inst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23839) addq.w &1,%d5 # if neg, set LAMBDA true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23840) cmp.l %d0,&0xffffecd4 # test iscale <= -4908
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23841) bgt.b no_inf # if false, skip rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23842) add.l &24,%d0 # add in 24 to iscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23843) mov.l &24,%d2 # put 24 in d2 for A9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23844) no_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23845) neg.l %d0 # and take abs of ISCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23846) iscale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23847) fmov.s FONE(%pc),%fp1 # init fp1 to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23848) bfextu USER_FPCR(%a6){&26:&2},%d1 # get initial rmode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23849) lsl.w &1,%d1 # put them in bits 2:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23850) add.w %d5,%d1 # add in LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23851) lsl.w &1,%d1 # put them in bits 3:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23852) tst.l L_SCR2(%a6) # test sign of original x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23853) bge.b x_pos # if pos, don't set bit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23854) addq.l &1,%d1 # if neg, set bit 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23855) x_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23856) lea.l RBDTBL(%pc),%a2 # load rbdtbl base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23857) mov.b (%a2,%d1),%d3 # load d3 with new rmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23858) lsl.l &4,%d3 # put bits in proper position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23859) fmov.l %d3,%fpcr # load bits into fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23860) lsr.l &4,%d3 # put bits in proper position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23861) tst.b %d3 # decode new rmode for pten table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23862) bne.b not_rn # if zero, it is RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23863) lea.l PTENRN(%pc),%a1 # load a1 with RN table base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23864) bra.b rmode # exit decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23865) not_rn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23866) lsr.b &1,%d3 # get lsb in carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23867) bcc.b not_rp2 # if carry clear, it is RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23868) lea.l PTENRP(%pc),%a1 # load a1 with RP table base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23869) bra.b rmode # exit decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23870) not_rp2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23871) lea.l PTENRM(%pc),%a1 # load a1 with RM table base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23872) rmode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23873) clr.l %d3 # clr table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23874) e_loop2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23875) lsr.l &1,%d0 # shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23876) bcc.b e_next2 # if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23877) fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23878) e_next2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23879) add.l &12,%d3 # inc d3 to next pwrten table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23880) tst.l %d0 # test if ISCALE is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23881) bne.b e_loop2 # if not, loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23883) # A8. Clr INEX; Force RZ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23884) # The operation in A3 above may have set INEX2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23885) # RZ mode is forced for the scaling operation to insure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23886) # only one rounding error. The grs bits are collected in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23887) # the INEX flag for use in A10.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23888) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23889) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23890) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23892) fmov.l &0,%fpsr # clr INEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23893) fmov.l &rz_mode*0x10,%fpcr # set RZ rounding mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23895) # A9. Scale X -> Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23896) # The mantissa is scaled to the desired number of significant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23897) # digits. The excess digits are collected in INEX2. If mul,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23898) # Check d2 for excess 10 exponential value. If not zero,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23899) # the iscale value would have caused the pwrten calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23900) # to overflow. Only a negative iscale can cause this, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23901) # multiply by 10^(d2), which is now only allowed to be 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23902) # with a multiply by 10^8 and 10^16, which is exact since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23903) # 10^24 is exact. If the input was denormalized, we must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23904) # create a busy stack frame with the mul command and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23905) # two operands, and allow the fpu to complete the multiply.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23906) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23907) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23908) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23909) # d0: FPCR with RZ mode/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23910) # d2: 0 or 24/unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23911) # d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23912) # d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23913) # d5: ICTR:LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23914) # d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23915) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23916) # a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23917) # a1: ptr to PTENRM array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23918) # a2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23919) # fp0: float(ILOG)/X adjusted for SCALE (Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23920) # fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23921) # fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23922) # F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23923) # F_SCR2:Abs(X) with $3fff exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23924) # L_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23925) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23927) A9_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23928) fmov.x (%a0),%fp0 # load X from memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23929) fabs.x %fp0 # use abs(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23930) tst.w %d5 # LAMBDA is in lower word of d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23931) bne.b sc_mul # if neg (LAMBDA = 1), scale by mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23932) fdiv.x %fp1,%fp0 # calculate X / SCALE -> Y to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23933) bra.w A10_st # branch to A10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23935) sc_mul:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23936) tst.b BINDEC_FLG(%a6) # check for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23937) beq.w A9_norm # if norm, continue with mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23939) # for DENORM, we must calculate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23940) # fp0 = input_op * 10^ISCALE * 10^24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23941) # since the input operand is a DENORM, we can't multiply it directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23942) # so, we do the multiplication of the exponents and mantissas separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23943) # in this way, we avoid underflow on intermediate stages of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23944) # multiplication and guarantee a result without exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23945) fmovm.x &0x2,-(%sp) # save 10^ISCALE to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23947) mov.w (%sp),%d3 # grab exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23948) andi.w &0x7fff,%d3 # clear sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23949) ori.w &0x8000,(%a0) # make DENORM exp negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23950) add.w (%a0),%d3 # add DENORM exp to 10^ISCALE exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23951) subi.w &0x3fff,%d3 # subtract BIAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23952) add.w 36(%a1),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23953) subi.w &0x3fff,%d3 # subtract BIAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23954) add.w 48(%a1),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23955) subi.w &0x3fff,%d3 # subtract BIAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23957) bmi.w sc_mul_err # is result is DENORM, punt!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23959) andi.w &0x8000,(%sp) # keep sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23960) or.w %d3,(%sp) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23961) andi.w &0x7fff,(%a0) # clear sign bit on DENORM again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23962) mov.l 0x8(%a0),-(%sp) # put input op mantissa on stk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23963) mov.l 0x4(%a0),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23964) mov.l &0x3fff0000,-(%sp) # force exp to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23965) fmovm.x (%sp)+,&0x80 # load normalized DENORM into fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23966) fmul.x (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23968) # fmul.x 36(%a1),%fp0 # multiply fp0 by 10^8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23969) # fmul.x 48(%a1),%fp0 # multiply fp0 by 10^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23970) mov.l 36+8(%a1),-(%sp) # get 10^8 mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23971) mov.l 36+4(%a1),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23972) mov.l &0x3fff0000,-(%sp) # force exp to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23973) mov.l 48+8(%a1),-(%sp) # get 10^16 mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23974) mov.l 48+4(%a1),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23975) mov.l &0x3fff0000,-(%sp)# force exp to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23976) fmul.x (%sp)+,%fp0 # multiply fp0 by 10^8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23977) fmul.x (%sp)+,%fp0 # multiply fp0 by 10^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23978) bra.b A10_st
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23980) sc_mul_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23981) bra.b sc_mul_err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23983) A9_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23984) tst.w %d2 # test for small exp case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23985) beq.b A9_con # if zero, continue as normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23986) fmul.x 36(%a1),%fp0 # multiply fp0 by 10^8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23987) fmul.x 48(%a1),%fp0 # multiply fp0 by 10^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23988) A9_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23989) fmul.x %fp1,%fp0 # calculate X * SCALE -> Y to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23991) # A10. Or in INEX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23992) # If INEX is set, round error occurred. This is compensated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23993) # for by 'or-ing' in the INEX2 flag to the lsb of Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23994) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23995) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23996) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23997) # d0: FPCR with RZ mode/FPSR with INEX2 isolated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23998) # d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23999) # d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24000) # d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24001) # d5: ICTR:LAMBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24002) # d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24003) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24004) # a0: ptr for original operand/final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24005) # a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24006) # a2: x/ptr to FP_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24007) # fp0: Y/Y with lsb adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24008) # fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24009) # fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24011) A10_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24012) fmov.l %fpsr,%d0 # get FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24013) fmov.x %fp0,FP_SCR1(%a6) # move Y to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24014) lea.l FP_SCR1(%a6),%a2 # load a2 with ptr to FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24015) btst &9,%d0 # check if INEX2 set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24016) beq.b A11_st # if clear, skip rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24017) or.l &1,8(%a2) # or in 1 to lsb of mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24018) fmov.x FP_SCR1(%a6),%fp0 # write adjusted Y back to fpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24021) # A11. Restore original FPCR; set size ext.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24022) # Perform FINT operation in the user's rounding mode. Keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24023) # the size to extended. The sintdo entry point in the sint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24024) # routine expects the FPCR value to be in USER_FPCR for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24025) # mode and precision. The original FPCR is saved in L_SCR1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24027) A11_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24028) mov.l USER_FPCR(%a6),L_SCR1(%a6) # save it for later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24029) and.l &0x00000030,USER_FPCR(%a6) # set size to ext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24030) # ;block exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24033) # A12. Calculate YINT = FINT(Y) according to user's rounding mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24034) # The FPSP routine sintd0 is used. The output is in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24035) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24036) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24037) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24038) # d0: FPSR with AINEX cleared/FPCR with size set to ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24039) # d2: x/x/scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24040) # d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24041) # d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24042) # d5: ICTR:LAMBDA/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24043) # d6: ILOG/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24044) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24045) # a0: ptr for original operand/src ptr for sintdo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24046) # a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24047) # a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24048) # a6: temp pointer to FP_SCR1(a6) - orig value saved and restored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24049) # fp0: Y/YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24050) # fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24051) # fp2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24052) # F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24053) # F_SCR2:Y adjusted for inex/Y with original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24054) # L_SCR1:x/original USER_FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24055) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24057) A12_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24058) movm.l &0xc0c0,-(%sp) # save regs used by sintd0 {%d0-%d1/%a0-%a1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24059) mov.l L_SCR1(%a6),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24060) mov.l L_SCR2(%a6),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24062) lea.l FP_SCR1(%a6),%a0 # a0 is ptr to FP_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24063) fmov.x %fp0,(%a0) # move Y to memory at FP_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24064) tst.l L_SCR2(%a6) # test sign of original operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24065) bge.b do_fint12 # if pos, use Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24066) or.l &0x80000000,(%a0) # if neg, use -Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24067) do_fint12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24068) mov.l USER_FPSR(%a6),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24069) # bsr sintdo # sint routine returns int in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24071) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24072) fmov.l &0x0,%fpsr # clear the AEXC bits!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24073) ## mov.l USER_FPCR(%a6),%d0 # ext prec/keep rnd mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24074) ## andi.l &0x00000030,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24075) ## fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24076) fint.x FP_SCR1(%a6),%fp0 # do fint()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24077) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24078) or.w %d0,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24079) ## fmov.l &0x0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24080) ## fmov.l %fpsr,%d0 # don't keep ccodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24081) ## or.w %d0,FPSR_EXCEPT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24083) mov.b (%sp),USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24084) add.l &4,%sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24086) mov.l (%sp)+,L_SCR2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24087) mov.l (%sp)+,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24088) movm.l (%sp)+,&0x303 # restore regs used by sint {%d0-%d1/%a0-%a1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24090) mov.l L_SCR2(%a6),FP_SCR1(%a6) # restore original exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24091) mov.l L_SCR1(%a6),USER_FPCR(%a6) # restore user's FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24093) # A13. Check for LEN digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24094) # If the int operation results in more than LEN digits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24095) # or less than LEN -1 digits, adjust ILOG and repeat from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24096) # A6. This test occurs only on the first pass. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24097) # result is exactly 10^LEN, decrement ILOG and divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24098) # the mantissa by 10. The calculation of 10^LEN cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24099) # be inexact, since all powers of ten up to 10^27 are exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24100) # in extended precision, so the use of a previous power-of-ten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24101) # table will introduce no error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24102) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24103) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24104) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24105) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24106) # d0: FPCR with size set to ext/scratch final = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24107) # d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24108) # d3: x/scratch final = x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24109) # d4: LEN/LEN adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24110) # d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24111) # d6: ILOG/ILOG adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24112) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24113) # a0: pointer into memory for packed bcd string formation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24114) # a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24115) # a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24116) # fp0: int portion of Y/abs(YINT) adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24117) # fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24118) # fp2: x/10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24119) # F_SCR1:x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24120) # F_SCR2:Y with original exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24121) # L_SCR1:original USER_FPCR/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24122) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24124) A13_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24125) swap %d5 # put ICTR in lower word of d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24126) tst.w %d5 # check if ICTR = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24127) bne not_zr # if non-zero, go to second test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24128) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24129) # Compute 10^(LEN-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24130) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24131) fmov.s FONE(%pc),%fp2 # init fp2 to 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24132) mov.l %d4,%d0 # put LEN in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24133) subq.l &1,%d0 # d0 = LEN -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24134) clr.l %d3 # clr table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24135) l_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24136) lsr.l &1,%d0 # shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24137) bcc.b l_next # if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24138) fmul.x (%a1,%d3),%fp2 # mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24139) l_next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24140) add.l &12,%d3 # inc d3 to next pwrten table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24141) tst.l %d0 # test if LEN is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24142) bne.b l_loop # if not, loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24143) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24144) # 10^LEN-1 is computed for this test and A14. If the input was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24145) # denormalized, check only the case in which YINT > 10^LEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24146) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24147) tst.b BINDEC_FLG(%a6) # check if input was norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24148) beq.b A13_con # if norm, continue with checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24149) fabs.x %fp0 # take abs of YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24150) bra test_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24151) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24152) # Compare abs(YINT) to 10^(LEN-1) and 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24153) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24154) A13_con:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24155) fabs.x %fp0 # take abs of YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24156) fcmp.x %fp0,%fp2 # compare abs(YINT) with 10^(LEN-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24157) fbge.w test_2 # if greater, do next test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24158) subq.l &1,%d6 # subtract 1 from ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24159) mov.w &1,%d5 # set ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24160) fmov.l &rm_mode*0x10,%fpcr # set rmode to RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24161) fmul.s FTEN(%pc),%fp2 # compute 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24162) bra.w A6_str # return to A6 and recompute YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24163) test_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24164) fmul.s FTEN(%pc),%fp2 # compute 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24165) fcmp.x %fp0,%fp2 # compare abs(YINT) with 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24166) fblt.w A14_st # if less, all is ok, go to A14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24167) fbgt.w fix_ex # if greater, fix and redo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24168) fdiv.s FTEN(%pc),%fp0 # if equal, divide by 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24169) addq.l &1,%d6 # and inc ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24170) bra.b A14_st # and continue elsewhere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24171) fix_ex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24172) addq.l &1,%d6 # increment ILOG by 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24173) mov.w &1,%d5 # set ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24174) fmov.l &rm_mode*0x10,%fpcr # set rmode to RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24175) bra.w A6_str # return to A6 and recompute YINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24176) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24177) # Since ICTR <> 0, we have already been through one adjustment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24178) # and shouldn't have another; this is to check if abs(YINT) = 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24179) # 10^LEN is again computed using whatever table is in a1 since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24180) # value calculated cannot be inexact.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24181) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24182) not_zr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24183) fmov.s FONE(%pc),%fp2 # init fp2 to 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24184) mov.l %d4,%d0 # put LEN in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24185) clr.l %d3 # clr table index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24186) z_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24187) lsr.l &1,%d0 # shift next bit into carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24188) bcc.b z_next # if zero, skip the mul
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24189) fmul.x (%a1,%d3),%fp2 # mul by 10**(d3_bit_no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24190) z_next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24191) add.l &12,%d3 # inc d3 to next pwrten table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24192) tst.l %d0 # test if LEN is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24193) bne.b z_loop # if not, loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24194) fabs.x %fp0 # get abs(YINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24195) fcmp.x %fp0,%fp2 # check if abs(YINT) = 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24196) fbneq.w A14_st # if not, skip this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24197) fdiv.s FTEN(%pc),%fp0 # divide abs(YINT) by 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24198) addq.l &1,%d6 # and inc ILOG by 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24199) addq.l &1,%d4 # and inc LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24200) fmul.s FTEN(%pc),%fp2 # if LEN++, the get 10^^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24202) # A14. Convert the mantissa to bcd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24203) # The binstr routine is used to convert the LEN digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24204) # mantissa to bcd in memory. The input to binstr is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24205) # to be a fraction; i.e. (mantissa)/10^LEN and adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24206) # such that the decimal point is to the left of bit 63.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24207) # The bcd digits are stored in the correct position in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24208) # the final string area in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24209) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24210) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24211) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24212) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24213) # d0: x/LEN call to binstr - final is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24214) # d1: x/0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24215) # d2: x/ms 32-bits of mant of abs(YINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24216) # d3: x/ls 32-bits of mant of abs(YINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24217) # d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24218) # d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24219) # d6: ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24220) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24221) # a0: pointer into memory for packed bcd string formation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24222) # /ptr to first mantissa byte in result string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24223) # a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24224) # a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24225) # fp0: int portion of Y/abs(YINT) adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24226) # fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24227) # fp2: 10^LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24228) # F_SCR1:x/Work area for final result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24229) # F_SCR2:Y with original exponent/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24230) # L_SCR1:original USER_FPCR/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24231) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24233) A14_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24234) fmov.l &rz_mode*0x10,%fpcr # force rz for conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24235) fdiv.x %fp2,%fp0 # divide abs(YINT) by 10^LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24236) lea.l FP_SCR0(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24237) fmov.x %fp0,(%a0) # move abs(YINT)/10^LEN to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24238) mov.l 4(%a0),%d2 # move 2nd word of FP_RES to d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24239) mov.l 8(%a0),%d3 # move 3rd word of FP_RES to d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24240) clr.l 4(%a0) # zero word 2 of FP_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24241) clr.l 8(%a0) # zero word 3 of FP_RES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24242) mov.l (%a0),%d0 # move exponent to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24243) swap %d0 # put exponent in lower word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24244) beq.b no_sft # if zero, don't shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24245) sub.l &0x3ffd,%d0 # sub bias less 2 to make fract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24246) tst.l %d0 # check if > 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24247) bgt.b no_sft # if so, don't shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24248) neg.l %d0 # make exp positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24249) m_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24250) lsr.l &1,%d2 # shift d2:d3 right, add 0s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24251) roxr.l &1,%d3 # the number of places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24252) dbf.w %d0,m_loop # given in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24253) no_sft:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24254) tst.l %d2 # check for mantissa of zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24255) bne.b no_zr # if not, go on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24256) tst.l %d3 # continue zero check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24257) beq.b zer_m # if zero, go directly to binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24258) no_zr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24259) clr.l %d1 # put zero in d1 for addx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24260) add.l &0x00000080,%d3 # inc at bit 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24261) addx.l %d1,%d2 # continue inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24262) and.l &0xffffff80,%d3 # strip off lsb not used by 882
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24263) zer_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24264) mov.l %d4,%d0 # put LEN in d0 for binstr call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24265) addq.l &3,%a0 # a0 points to M16 byte in result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24266) bsr binstr # call binstr to convert mant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24269) # A15. Convert the exponent to bcd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24270) # As in A14 above, the exp is converted to bcd and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24271) # digits are stored in the final string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24272) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24273) # Digits are stored in L_SCR1(a6) on return from BINDEC as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24274) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24275) # 32 16 15 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24276) # -----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24277) # | 0 | e3 | e2 | e1 | e4 | X | X | X |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24278) # -----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24279) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24280) # And are moved into their proper places in FP_SCR0. If digit e4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24281) # is non-zero, OPERR is signaled. In all cases, all 4 digits are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24282) # written as specified in the 881/882 manual for packed decimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24283) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24284) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24285) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24286) # d0: x/LEN call to binstr - final is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24287) # d1: x/scratch (0);shift count for final exponent packing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24288) # d2: x/ms 32-bits of exp fraction/scratch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24289) # d3: x/ls 32-bits of exp fraction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24290) # d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24291) # d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24292) # d6: ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24293) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24294) # a0: ptr to result string/ptr to L_SCR1(a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24295) # a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24296) # a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24297) # fp0: abs(YINT) adjusted/float(ILOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24298) # fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24299) # fp2: 10^LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24300) # F_SCR1:Work area for final result/BCD result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24301) # F_SCR2:Y with original exponent/ILOG/10^4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24302) # L_SCR1:original USER_FPCR/Exponent digits on return from binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24303) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24305) A15_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24306) tst.b BINDEC_FLG(%a6) # check for denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24307) beq.b not_denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24308) ftest.x %fp0 # test for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24309) fbeq.w den_zero # if zero, use k-factor or 4933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24310) fmov.l %d6,%fp0 # float ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24311) fabs.x %fp0 # get abs of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24312) bra.b convrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24313) den_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24314) tst.l %d7 # check sign of the k-factor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24315) blt.b use_ilog # if negative, use ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24316) fmov.s F4933(%pc),%fp0 # force exponent to 4933
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24317) bra.b convrt # do it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24318) use_ilog:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24319) fmov.l %d6,%fp0 # float ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24320) fabs.x %fp0 # get abs of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24321) bra.b convrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24322) not_denorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24323) ftest.x %fp0 # test for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24324) fbneq.w not_zero # if zero, force exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24325) fmov.s FONE(%pc),%fp0 # force exponent to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24326) bra.b convrt # do it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24327) not_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24328) fmov.l %d6,%fp0 # float ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24329) fabs.x %fp0 # get abs of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24330) convrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24331) fdiv.x 24(%a1),%fp0 # compute ILOG/10^4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24332) fmov.x %fp0,FP_SCR1(%a6) # store fp0 in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24333) mov.l 4(%a2),%d2 # move word 2 to d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24334) mov.l 8(%a2),%d3 # move word 3 to d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24335) mov.w (%a2),%d0 # move exp to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24336) beq.b x_loop_fin # if zero, skip the shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24337) sub.w &0x3ffd,%d0 # subtract off bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24338) neg.w %d0 # make exp positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24339) x_loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24340) lsr.l &1,%d2 # shift d2:d3 right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24341) roxr.l &1,%d3 # the number of places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24342) dbf.w %d0,x_loop # given in d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24343) x_loop_fin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24344) clr.l %d1 # put zero in d1 for addx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24345) add.l &0x00000080,%d3 # inc at bit 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24346) addx.l %d1,%d2 # continue inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24347) and.l &0xffffff80,%d3 # strip off lsb not used by 882
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24348) mov.l &4,%d0 # put 4 in d0 for binstr call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24349) lea.l L_SCR1(%a6),%a0 # a0 is ptr to L_SCR1 for exp digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24350) bsr binstr # call binstr to convert exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24351) mov.l L_SCR1(%a6),%d0 # load L_SCR1 lword to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24352) mov.l &12,%d1 # use d1 for shift count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24353) lsr.l %d1,%d0 # shift d0 right by 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24354) bfins %d0,FP_SCR0(%a6){&4:&12} # put e3:e2:e1 in FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24355) lsr.l %d1,%d0 # shift d0 right by 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24356) bfins %d0,FP_SCR0(%a6){&16:&4} # put e4 in FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24357) tst.b %d0 # check if e4 is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24358) beq.b A16_st # if zero, skip rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24359) or.l &opaop_mask,USER_FPSR(%a6) # set OPERR & AIOP in USER_FPSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24362) # A16. Write sign bits to final string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24363) # Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24364) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24365) # Register usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24366) # Input/Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24367) # d0: x/scratch - final is x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24368) # d2: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24369) # d3: x/x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24370) # d4: LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24371) # d5: ICTR:LAMBDA/LAMBDA:ICTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24372) # d6: ILOG/ILOG adjusted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24373) # d7: k-factor/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24374) # a0: ptr to L_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24375) # a1: ptr to PTENxx array/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24376) # a2: ptr to FP_SCR1(a6)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24377) # fp0: float(ILOG)/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24378) # fp1: 10^ISCALE/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24379) # fp2: 10^LEN/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24380) # F_SCR1:BCD result with correct signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24381) # F_SCR2:ILOG/10^4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24382) # L_SCR1:Exponent digits on return from binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24383) # L_SCR2:first word of X packed/Unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24385) A16_st:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24386) clr.l %d0 # clr d0 for collection of signs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24387) and.b &0x0f,FP_SCR0(%a6) # clear first nibble of FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24388) tst.l L_SCR2(%a6) # check sign of original mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24389) bge.b mant_p # if pos, don't set SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24390) mov.l &2,%d0 # move 2 in to d0 for SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24391) mant_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24392) tst.l %d6 # check sign of ILOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24393) bge.b wr_sgn # if pos, don't set SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24394) addq.l &1,%d0 # set bit 0 in d0 for SE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24395) wr_sgn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24396) bfins %d0,FP_SCR0(%a6){&0:&2} # insert SM and SE into FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24398) # Clean up and restore all registers used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24400) fmov.l &0,%fpsr # clear possible inex2/ainex bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24401) fmovm.x (%sp)+,&0xe0 # {%fp0-%fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24402) movm.l (%sp)+,&0x4fc # {%d2-%d7/%a2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24403) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24405) global PTENRN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24406) PTENRN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24407) long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24408) long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24409) long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24410) long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24411) long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24412) long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24413) long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24414) long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24415) long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24416) long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24417) long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24418) long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24419) long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24421) global PTENRP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24422) PTENRP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24423) long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24424) long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24425) long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24426) long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24427) long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24428) long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24429) long 0x40D30000,0xC2781F49,0xFFCFA6D6 # 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24430) long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24431) long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24432) long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24433) long 0x4D480000,0xC9767586,0x81750C18 # 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24434) long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24435) long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24437) global PTENRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24438) PTENRM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24439) long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24440) long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24441) long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24442) long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24443) long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24444) long 0x40690000,0x9DC5ADA8,0x2B70B59D # 10 ^ 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24445) long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24446) long 0x41A80000,0x93BA47C9,0x80E98CDF # 10 ^ 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24447) long 0x43510000,0xAA7EEBFB,0x9DF9DE8D # 10 ^ 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24448) long 0x46A30000,0xE319A0AE,0xA60E91C6 # 10 ^ 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24449) long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24450) long 0x5A920000,0x9E8B3B5D,0xC53D5DE4 # 10 ^ 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24451) long 0x75250000,0xC4605202,0x8A20979A # 10 ^ 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24453) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24454) # binstr(): Converts a 64-bit binary integer to bcd. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24455) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24456) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24457) # d2:d3 = 64-bit binary integer #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24458) # d0 = desired length (LEN) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24459) # a0 = pointer to start in memory for bcd characters #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24460) # (This pointer must point to byte 4 of the first #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24461) # lword of the packed decimal memory string.) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24462) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24463) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24464) # a0 = pointer to LEN bcd digits representing the 64-bit integer. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24465) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24466) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24467) # The 64-bit binary is assumed to have a decimal point before #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24468) # bit 63. The fraction is multiplied by 10 using a mul by 2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24469) # shift and a mul by 8 shift. The bits shifted out of the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24470) # msb form a decimal digit. This process is iterated until #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24471) # LEN digits are formed. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24472) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24473) # A1. Init d7 to 1. D7 is the byte digit counter, and if 1, the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24474) # digit formed will be assumed the least significant. This is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24475) # to force the first byte formed to have a 0 in the upper 4 bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24476) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24477) # A2. Beginning of the loop: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24478) # Copy the fraction in d2:d3 to d4:d5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24479) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24480) # A3. Multiply the fraction in d2:d3 by 8 using bit-field #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24481) # extracts and shifts. The three msbs from d2 will go into d1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24482) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24483) # A4. Multiply the fraction in d4:d5 by 2 using shifts. The msb #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24484) # will be collected by the carry. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24485) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24486) # A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24487) # into d2:d3. D1 will contain the bcd digit formed. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24488) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24489) # A6. Test d7. If zero, the digit formed is the ms digit. If non- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24490) # zero, it is the ls digit. Put the digit in its place in the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24491) # upper word of d0. If it is the ls digit, write the word #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24492) # from d0 to memory. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24493) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24494) # A7. Decrement d6 (LEN counter) and repeat the loop until zero. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24495) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24496) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24498) # Implementation Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24499) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24500) # The registers are used as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24501) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24502) # d0: LEN counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24503) # d1: temp used to form the digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24504) # d2: upper 32-bits of fraction for mul by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24505) # d3: lower 32-bits of fraction for mul by 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24506) # d4: upper 32-bits of fraction for mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24507) # d5: lower 32-bits of fraction for mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24508) # d6: temp for bit-field extracts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24509) # d7: byte digit formation word;digit count {0,1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24510) # a0: pointer into memory for packed bcd string formation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24511) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24513) global binstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24514) binstr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24515) movm.l &0xff00,-(%sp) # {%d0-%d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24517) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24518) # A1: Init d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24519) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24520) mov.l &1,%d7 # init d7 for second digit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24521) subq.l &1,%d0 # for dbf d0 would have LEN+1 passes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24522) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24523) # A2. Copy d2:d3 to d4:d5. Start loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24524) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24525) loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24526) mov.l %d2,%d4 # copy the fraction before muls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24527) mov.l %d3,%d5 # to d4:d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24528) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24529) # A3. Multiply d2:d3 by 8; extract msbs into d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24530) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24531) bfextu %d2{&0:&3},%d1 # copy 3 msbs of d2 into d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24532) asl.l &3,%d2 # shift d2 left by 3 places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24533) bfextu %d3{&0:&3},%d6 # copy 3 msbs of d3 into d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24534) asl.l &3,%d3 # shift d3 left by 3 places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24535) or.l %d6,%d2 # or in msbs from d3 into d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24536) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24537) # A4. Multiply d4:d5 by 2; add carry out to d1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24538) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24539) asl.l &1,%d5 # mul d5 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24540) roxl.l &1,%d4 # mul d4 by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24541) swap %d6 # put 0 in d6 lower word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24542) addx.w %d6,%d1 # add in extend from mul by 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24543) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24544) # A5. Add mul by 8 to mul by 2. D1 contains the digit formed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24545) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24546) add.l %d5,%d3 # add lower 32 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24547) nop # ERRATA FIX #13 (Rev. 1.2 6/6/90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24548) addx.l %d4,%d2 # add with extend upper 32 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24549) nop # ERRATA FIX #13 (Rev. 1.2 6/6/90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24550) addx.w %d6,%d1 # add in extend from add to d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24551) swap %d6 # with d6 = 0; put 0 in upper word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24552) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24553) # A6. Test d7 and branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24554) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24555) tst.w %d7 # if zero, store digit & to loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24556) beq.b first_d # if non-zero, form byte & write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24557) sec_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24558) swap %d7 # bring first digit to word d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24559) asl.w &4,%d7 # first digit in upper 4 bits d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24560) add.w %d1,%d7 # add in ls digit to d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24561) mov.b %d7,(%a0)+ # store d7b byte in memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24562) swap %d7 # put LEN counter in word d7a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24563) clr.w %d7 # set d7a to signal no digits done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24564) dbf.w %d0,loop # do loop some more!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24565) bra.b end_bstr # finished, so exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24566) first_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24567) swap %d7 # put digit word in d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24568) mov.w %d1,%d7 # put new digit in d7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24569) swap %d7 # put LEN counter in word d7a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24570) addq.w &1,%d7 # set d7a to signal first digit done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24571) dbf.w %d0,loop # do loop some more!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24572) swap %d7 # put last digit in string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24573) lsl.w &4,%d7 # move it to upper 4 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24574) mov.b %d7,(%a0)+ # store it in memory string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24575) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24576) # Clean up and return with result in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24577) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24578) end_bstr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24579) movm.l (%sp)+,&0xff # {%d0-%d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24580) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24582) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24583) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24584) # facc_in_b(): dmem_read_byte failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24585) # facc_in_w(): dmem_read_word failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24586) # facc_in_l(): dmem_read_long failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24587) # facc_in_d(): dmem_read of dbl prec failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24588) # facc_in_x(): dmem_read of ext prec failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24589) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24590) # facc_out_b(): dmem_write_byte failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24591) # facc_out_w(): dmem_write_word failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24592) # facc_out_l(): dmem_write_long failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24593) # facc_out_d(): dmem_write of dbl prec failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24594) # facc_out_x(): dmem_write of ext prec failed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24595) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24596) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24597) # _real_access() - exit through access error handler #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24598) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24599) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24600) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24601) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24602) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24603) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24604) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24605) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24606) # Flow jumps here when an FP data fetch call gets an error #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24607) # result. This means the operating system wants an access error frame #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24608) # made out of the current exception stack frame. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24609) # So, we first call restore() which makes sure that any updated #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24610) # -(an)+ register gets returned to its pre-exception value and then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24611) # we change the stack to an access error stack frame. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24612) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24613) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24615) facc_in_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24616) movq.l &0x1,%d0 # one byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24617) bsr.w restore # fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24619) mov.w &0x0121,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24620) bra.w facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24622) facc_in_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24623) movq.l &0x2,%d0 # two bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24624) bsr.w restore # fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24626) mov.w &0x0141,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24627) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24629) facc_in_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24630) movq.l &0x4,%d0 # four bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24631) bsr.w restore # fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24633) mov.w &0x0101,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24634) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24636) facc_in_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24637) movq.l &0x8,%d0 # eight bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24638) bsr.w restore # fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24640) mov.w &0x0161,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24641) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24643) facc_in_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24644) movq.l &0xc,%d0 # twelve bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24645) bsr.w restore # fix An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24647) mov.w &0x0161,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24648) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24650) ################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24652) facc_out_b:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24653) movq.l &0x1,%d0 # one byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24654) bsr.w restore # restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24656) mov.w &0x00a1,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24657) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24659) facc_out_w:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24660) movq.l &0x2,%d0 # two bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24661) bsr.w restore # restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24663) mov.w &0x00c1,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24664) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24666) facc_out_l:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24667) movq.l &0x4,%d0 # four bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24668) bsr.w restore # restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24670) mov.w &0x0081,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24671) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24673) facc_out_d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24674) movq.l &0x8,%d0 # eight bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24675) bsr.w restore # restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24677) mov.w &0x00e1,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24678) bra.b facc_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24680) facc_out_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24681) mov.l &0xc,%d0 # twelve bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24682) bsr.w restore # restore An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24684) mov.w &0x00e1,EXC_VOFF(%a6) # set FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24686) # here's where we actually create the access error frame from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24687) # current exception stack frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24688) facc_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24689) mov.l USER_FPIAR(%a6),EXC_PC(%a6) # store current PC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24691) fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24692) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24693) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24695) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24697) mov.l (%sp),-(%sp) # store SR, hi(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24698) mov.l 0x8(%sp),0x4(%sp) # store lo(PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24699) mov.l 0xc(%sp),0x8(%sp) # store EA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24700) mov.l &0x00000001,0xc(%sp) # store FSLW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24701) mov.w 0x6(%sp),0xc(%sp) # fix FSLW (size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24702) mov.w &0x4008,0x6(%sp) # store voff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24704) btst &0x5,(%sp) # supervisor or user mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24705) beq.b facc_out2 # user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24706) bset &0x2,0xd(%sp) # set supervisor TM bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24708) facc_out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24709) bra.l _real_access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24711) ##################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24713) # if the effective addressing mode was predecrement or postincrement,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24714) # the emulation has already changed its value to the correct post-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24715) # instruction value. but since we're exiting to the access error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24716) # handler, then AN must be returned to its pre-instruction value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24717) # we do that here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24718) restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24719) mov.b EXC_OPWORD+0x1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24720) andi.b &0x38,%d1 # extract opmode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24721) cmpi.b %d1,&0x18 # postinc?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24722) beq.w rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24723) cmpi.b %d1,&0x20 # predec?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24724) beq.w rest_dec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24725) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24727) rest_inc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24728) mov.b EXC_OPWORD+0x1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24729) andi.w &0x0007,%d1 # fetch An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24731) mov.w (tbl_rest_inc.b,%pc,%d1.w*2),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24732) jmp (tbl_rest_inc.b,%pc,%d1.w*1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24734) tbl_rest_inc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24735) short ri_a0 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24736) short ri_a1 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24737) short ri_a2 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24738) short ri_a3 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24739) short ri_a4 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24740) short ri_a5 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24741) short ri_a6 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24742) short ri_a7 - tbl_rest_inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24744) ri_a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24745) sub.l %d0,EXC_DREGS+0x8(%a6) # fix stacked a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24746) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24747) ri_a1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24748) sub.l %d0,EXC_DREGS+0xc(%a6) # fix stacked a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24749) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24750) ri_a2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24751) sub.l %d0,%a2 # fix a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24752) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24753) ri_a3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24754) sub.l %d0,%a3 # fix a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24755) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24756) ri_a4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24757) sub.l %d0,%a4 # fix a4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24758) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24759) ri_a5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24760) sub.l %d0,%a5 # fix a5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24761) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24762) ri_a6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24763) sub.l %d0,(%a6) # fix stacked a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24764) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24765) # if it's a fmove out instruction, we don't have to fix a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24766) # because we hadn't changed it yet. if it's an opclass two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24767) # instruction (data moved in) and the exception was in supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24768) # mode, then also also wasn't updated. if it was user mode, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24769) # restore the correct a7 which is in the USP currently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24770) ri_a7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24771) cmpi.b EXC_VOFF(%a6),&0x30 # move in or out?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24772) bne.b ri_a7_done # out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24774) btst &0x5,EXC_SR(%a6) # user or supervisor?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24775) bne.b ri_a7_done # supervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24776) movc %usp,%a0 # restore USP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24777) sub.l %d0,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24778) movc %a0,%usp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24779) ri_a7_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24780) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24782) # need to invert adjustment value if the <ea> was predec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24783) rest_dec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24784) neg.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24785) bra.b rest_inc