^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) # lfptop.s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) # This file is appended to the top of the 060ILSP 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 here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) bra.l _facoss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) bra.l _facosd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bra.l _facosx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bra.l _fasins_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) bra.l _fasind_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) bra.l _fasinx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) bra.l _fatans_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) bra.l _fatand_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) bra.l _fatanx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) bra.l _fatanhs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bra.l _fatanhd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) bra.l _fatanhx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bra.l _fcoss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) bra.l _fcosd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) bra.l _fcosx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bra.l _fcoshs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bra.l _fcoshd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) bra.l _fcoshx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) bra.l _fetoxs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) bra.l _fetoxd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) bra.l _fetoxx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) bra.l _fetoxm1s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) bra.l _fetoxm1d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) bra.l _fetoxm1x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) bra.l _fgetexps_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) bra.l _fgetexpd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bra.l _fgetexpx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bra.l _fgetmans_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) bra.l _fgetmand_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) bra.l _fgetmanx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) bra.l _flog10s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bra.l _flog10d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) bra.l _flog10x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bra.l _flog2s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) bra.l _flog2d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) bra.l _flog2x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bra.l _flogns_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) bra.l _flognd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) bra.l _flognx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) bra.l _flognp1s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) bra.l _flognp1d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bra.l _flognp1x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bra.l _fmods_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) bra.l _fmodd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) bra.l _fmodx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) bra.l _frems_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) bra.l _fremd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) bra.l _fremx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bra.l _fscales_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bra.l _fscaled_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) bra.l _fscalex_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bra.l _fsins_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) bra.l _fsind_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) bra.l _fsinx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) bra.l _fsincoss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) bra.l _fsincosd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) bra.l _fsincosx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) bra.l _fsinhs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) bra.l _fsinhd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) bra.l _fsinhx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) bra.l _ftans_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) bra.l _ftand_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) bra.l _ftanx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) bra.l _ftanhs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) bra.l _ftanhd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) bra.l _ftanhx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bra.l _ftentoxs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) bra.l _ftentoxd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bra.l _ftentoxx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) bra.l _ftwotoxs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) bra.l _ftwotoxd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) bra.l _ftwotoxx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) bra.l _fabss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) bra.l _fabsd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) bra.l _fabsx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) bra.l _fadds_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) bra.l _faddd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) bra.l _faddx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) bra.l _fdivs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) bra.l _fdivd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) bra.l _fdivx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) bra.l _fints_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) bra.l _fintd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) bra.l _fintx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) bra.l _fintrzs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) bra.l _fintrzd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) bra.l _fintrzx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) bra.l _fmuls_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) bra.l _fmuld_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) bra.l _fmulx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) bra.l _fnegs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) bra.l _fnegd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) bra.l _fnegx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bra.l _fsqrts_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) bra.l _fsqrtd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) bra.l _fsqrtx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) bra.l _fsubs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) bra.l _fsubd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) bra.l _fsubx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) short 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) # leave room for future possible additions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) align 0x400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) # This file contains a set of define statements for constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) # in order to promote readability within the corecode itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) set LOCAL_SIZE, 192 # stack frame size(bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) set LV, -LOCAL_SIZE # stack offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) set EXC_SR, 0x4 # stack status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) set EXC_PC, 0x6 # stack pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) set EXC_VOFF, 0xa # stacked vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) set EXC_EA, 0xc # stacked <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) set EXC_FP, 0x0 # frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) set EXC_AREGS, -68 # offset of all address regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) set EXC_DREGS, -100 # offset of all data regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) set EXC_FPREGS, -36 # offset of all fp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) set EXC_A7, EXC_AREGS+(7*4) # offset of saved a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) set OLD_A7, EXC_AREGS+(6*4) # extra copy of saved a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) set EXC_A6, EXC_AREGS+(6*4) # offset of saved a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) set EXC_A5, EXC_AREGS+(5*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) set EXC_A4, EXC_AREGS+(4*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) set EXC_A3, EXC_AREGS+(3*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) set EXC_A2, EXC_AREGS+(2*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) set EXC_A1, EXC_AREGS+(1*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) set EXC_A0, EXC_AREGS+(0*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) set EXC_D7, EXC_DREGS+(7*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) set EXC_D6, EXC_DREGS+(6*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) set EXC_D5, EXC_DREGS+(5*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) set EXC_D4, EXC_DREGS+(4*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) set EXC_D3, EXC_DREGS+(3*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) set EXC_D2, EXC_DREGS+(2*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) set EXC_D1, EXC_DREGS+(1*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) set EXC_D0, EXC_DREGS+(0*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) set EXC_FP0, EXC_FPREGS+(0*12) # offset of saved fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) set EXC_FP1, EXC_FPREGS+(1*12) # offset of saved fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) set EXC_FP2, EXC_FPREGS+(2*12) # offset of saved fp2 (not used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) set FP_SCR1, LV+80 # fp scratch 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) set FP_SCR1_EX, FP_SCR1+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) set FP_SCR1_SGN, FP_SCR1+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) set FP_SCR1_HI, FP_SCR1+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) set FP_SCR1_LO, FP_SCR1+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) set FP_SCR0, LV+68 # fp scratch 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) set FP_SCR0_EX, FP_SCR0+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) set FP_SCR0_SGN, FP_SCR0+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) set FP_SCR0_HI, FP_SCR0+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) set FP_SCR0_LO, FP_SCR0+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) set FP_DST, LV+56 # fp destination operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) set FP_DST_EX, FP_DST+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) set FP_DST_SGN, FP_DST+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) set FP_DST_HI, FP_DST+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) set FP_DST_LO, FP_DST+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) set FP_SRC, LV+44 # fp source operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) set FP_SRC_EX, FP_SRC+0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) set FP_SRC_SGN, FP_SRC+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) set FP_SRC_HI, FP_SRC+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) set FP_SRC_LO, FP_SRC+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) set USER_FPIAR, LV+40 # FP instr address register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) set USER_FPSR, LV+36 # FP status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) set FPSR_CC, USER_FPSR+0 # FPSR condition codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) set FPSR_QBYTE, USER_FPSR+1 # FPSR qoutient byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) set FPSR_EXCEPT, USER_FPSR+2 # FPSR exception status byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) set FPSR_AEXCEPT, USER_FPSR+3 # FPSR accrued exception byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) set USER_FPCR, LV+32 # FP control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) set FPCR_ENABLE, USER_FPCR+2 # FPCR exception enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) set FPCR_MODE, USER_FPCR+3 # FPCR rounding mode control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) set L_SCR3, LV+28 # integer scratch 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) set L_SCR2, LV+24 # integer scratch 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) set L_SCR1, LV+20 # integer scratch 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) set STORE_FLG, LV+19 # flag: operand store (ie. not fcmp/ftst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) set EXC_TEMP2, LV+24 # temporary space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) set EXC_TEMP, LV+16 # temporary space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) set DTAG, LV+15 # destination operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) set STAG, LV+14 # source operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) set SPCOND_FLG, LV+10 # flag: special case (see below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) set EXC_CC, LV+8 # saved condition codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) set EXC_EXTWPTR, LV+4 # saved current PC (active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) set EXC_EXTWORD, LV+2 # saved extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) set EXC_CMDREG, LV+2 # saved extension word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) set EXC_OPWORD, LV+0 # saved operation word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) # Helpful macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) set FTEMP, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) set FTEMP_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) set FTEMP_SGN, 2 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) set FTEMP_HI, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) set FTEMP_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) set FTEMP_GRS, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) set LOCAL, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) set LOCAL_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) set LOCAL_SGN, 2 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) set LOCAL_HI, 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) set LOCAL_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) set LOCAL_GRS, 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) set DST, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) set DST_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) set DST_HI, 4 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) set DST_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) set SRC, 0 # offsets within an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) set SRC_EX, 0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) set SRC_HI, 4 # value saved in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) set SRC_LO, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) set SGL_LO, 0x3f81 # min sgl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) set SGL_HI, 0x407e # max sgl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) set DBL_LO, 0x3c01 # min dbl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) set DBL_HI, 0x43fe # max dbl prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) set EXT_LO, 0x0 # min ext prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) set EXT_HI, 0x7ffe # max ext prec exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) set EXT_BIAS, 0x3fff # extended precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) set SGL_BIAS, 0x007f # single precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) set DBL_BIAS, 0x03ff # double precision bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) set NORM, 0x00 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) set ZERO, 0x01 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) set INF, 0x02 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) set QNAN, 0x03 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) set DENORM, 0x04 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) set SNAN, 0x05 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) set UNNORM, 0x06 # operand type for STAG/DTAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ##################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) # FPSR/FPCR bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ##################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) set neg_bit, 0x3 # negative result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) set z_bit, 0x2 # zero result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) set inf_bit, 0x1 # infinite result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) set nan_bit, 0x0 # NAN result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) set q_sn_bit, 0x7 # sign bit of quotient byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) set bsun_bit, 7 # branch on unordered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) set snan_bit, 6 # signalling NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) set operr_bit, 5 # operand error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) set ovfl_bit, 4 # overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) set unfl_bit, 3 # underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) set dz_bit, 2 # divide by zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) set inex2_bit, 1 # inexact result 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) set inex1_bit, 0 # inexact result 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) set aiop_bit, 7 # accrued inexact operation bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) set aovfl_bit, 6 # accrued overflow bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) set aunfl_bit, 5 # accrued underflow bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) set adz_bit, 4 # accrued dz bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) set ainex_bit, 3 # accrued inexact bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) # FPSR individual bit masks #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) set neg_mask, 0x08000000 # negative bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) set inf_mask, 0x02000000 # infinity bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) set z_mask, 0x04000000 # zero bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) set nan_mask, 0x01000000 # nan bit mask (lw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) set neg_bmask, 0x08 # negative bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) set inf_bmask, 0x02 # infinity bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) set z_bmask, 0x04 # zero bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) set nan_bmask, 0x01 # nan bit mask (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) set bsun_mask, 0x00008000 # bsun exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) set snan_mask, 0x00004000 # snan exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) set operr_mask, 0x00002000 # operr exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) set ovfl_mask, 0x00001000 # overflow exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) set unfl_mask, 0x00000800 # underflow exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) set dz_mask, 0x00000400 # dz exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) set inex2_mask, 0x00000200 # inex2 exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) set inex1_mask, 0x00000100 # inex1 exception mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) set aiop_mask, 0x00000080 # accrued illegal operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) set aovfl_mask, 0x00000040 # accrued overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) set aunfl_mask, 0x00000020 # accrued underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) set adz_mask, 0x00000010 # accrued divide by zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) set ainex_mask, 0x00000008 # accrued inexact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) # FPSR combinations used in the FPSP #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ######################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) set dzinf_mask, inf_mask+dz_mask+adz_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) set opnan_mask, nan_mask+operr_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) set nzi_mask, 0x01ffffff #clears N, Z, and I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) set unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) set unf2inx_mask, unfl_mask+inex2_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) set ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) set inx1a_mask, inex1_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) set inx2a_mask, inex2_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) set snaniop_mask, nan_mask+snan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) set snaniop2_mask, snan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) set naniop_mask, nan_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) set neginf_mask, neg_mask+inf_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) set infaiop_mask, inf_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) set negz_mask, neg_mask+z_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) set opaop_mask, operr_mask+aiop_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) set unfl_inx_mask, unfl_mask+aunfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) set ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) # misc. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #########
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) set rnd_stky_bit, 29 # stky bit pos in longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) set sign_bit, 0x7 # sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) set signan_bit, 0x6 # signalling nan bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) set sgl_thresh, 0x3f81 # minimum sgl exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) set dbl_thresh, 0x3c01 # minimum dbl exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) set x_mode, 0x0 # extended precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) set s_mode, 0x4 # single precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) set d_mode, 0x8 # double precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) set rn_mode, 0x0 # round-to-nearest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) set rz_mode, 0x1 # round-to-zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) set rm_mode, 0x2 # round-tp-minus-infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) set rp_mode, 0x3 # round-to-plus-infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) set mantissalen, 64 # length of mantissa in bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) set BYTE, 1 # len(byte) == 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) set WORD, 2 # len(word) == 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) set LONG, 4 # len(longword) == 2 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) set BSUN_VEC, 0xc0 # bsun vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) set INEX_VEC, 0xc4 # inexact vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) set DZ_VEC, 0xc8 # dz vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) set UNFL_VEC, 0xcc # unfl vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) set OPERR_VEC, 0xd0 # operr vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) set OVFL_VEC, 0xd4 # ovfl vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) set SNAN_VEC, 0xd8 # snan vector offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) # SPecial CONDition FLaGs #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ###########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) set ftrapcc_flg, 0x01 # flag bit: ftrapcc exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) set fbsun_flg, 0x02 # flag bit: bsun exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) set mia7_flg, 0x04 # flag bit: (a7)+ <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) set mda7_flg, 0x08 # flag bit: -(a7) <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) set fmovm_flg, 0x40 # flag bit: fmovm instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) set immed_flg, 0x80 # flag bit: &<data> <ea>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) set ftrapcc_bit, 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) set fbsun_bit, 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) set mia7_bit, 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) set mda7_bit, 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) set immed_bit, 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ##################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) # TRANSCENDENTAL "LAST-OP" FLAGS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ##################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) set FMUL_OP, 0x0 # fmul instr performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) set FDIV_OP, 0x1 # fdiv performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) set FADD_OP, 0x2 # fadd performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) set FMOV_OP, 0x3 # fmov performed last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) # CONSTANTS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) #############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) T1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) T2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) PI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) PIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) TWOBYPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) long 0x3FE45F30,0x6DC9C883
^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) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) global _fsins_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) _fsins_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) bne.b _L0_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) bsr.l ssin # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) bra.b _L0_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) _L0_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) bne.b _L0_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) bra.b _L0_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) _L0_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) bne.b _L0_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) bra.b _L0_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) _L0_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) bne.b _L0_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) bra.b _L0_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) _L0_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) bsr.l ssind # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) _L0_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) global _fsind_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) _fsind_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) bne.b _L0_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) bsr.l ssin # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) bra.b _L0_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) _L0_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) bne.b _L0_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) bra.b _L0_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) _L0_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) bne.b _L0_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) bra.b _L0_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) _L0_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) bne.b _L0_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) bra.b _L0_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) _L0_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) bsr.l ssind # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) _L0_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) global _fsinx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) _fsinx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) bne.b _L0_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) bsr.l ssin # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) bra.b _L0_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) _L0_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) bne.b _L0_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) bra.b _L0_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) _L0_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) bne.b _L0_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) bra.b _L0_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) _L0_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) bne.b _L0_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) bra.b _L0_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) _L0_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) bsr.l ssind # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) _L0_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) global _fcoss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) _fcoss_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) bne.b _L1_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) bsr.l scos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) bra.b _L1_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) _L1_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) bne.b _L1_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) bra.b _L1_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) _L1_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) bne.b _L1_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) bra.b _L1_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) _L1_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) bne.b _L1_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) bra.b _L1_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) _L1_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) bsr.l scosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) _L1_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) global _fcosd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) _fcosd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) bne.b _L1_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) bsr.l scos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) bra.b _L1_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) _L1_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) bne.b _L1_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) bra.b _L1_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) _L1_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) bne.b _L1_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) bra.b _L1_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) _L1_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) bne.b _L1_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) bra.b _L1_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) _L1_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) bsr.l scosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) _L1_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) global _fcosx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) _fcosx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) bne.b _L1_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) bsr.l scos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) bra.b _L1_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) _L1_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) bne.b _L1_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) bra.b _L1_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) _L1_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) bne.b _L1_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) bra.b _L1_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) _L1_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) bne.b _L1_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) bra.b _L1_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) _L1_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) bsr.l scosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) _L1_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) global _fsinhs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) _fsinhs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) bne.b _L2_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) bsr.l ssinh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) bra.b _L2_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) _L2_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) bne.b _L2_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) bra.b _L2_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) _L2_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) bne.b _L2_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) bsr.l src_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) bra.b _L2_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) _L2_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) bne.b _L2_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) bra.b _L2_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) _L2_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) bsr.l ssinhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) _L2_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) global _fsinhd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) _fsinhd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) bne.b _L2_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) bsr.l ssinh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) bra.b _L2_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) _L2_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) bne.b _L2_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) bra.b _L2_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) _L2_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) bne.b _L2_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) bsr.l src_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) bra.b _L2_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) _L2_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) bne.b _L2_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) bra.b _L2_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) _L2_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) bsr.l ssinhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) _L2_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) global _fsinhx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) _fsinhx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) bne.b _L2_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) bsr.l ssinh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) bra.b _L2_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) _L2_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) bne.b _L2_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) bra.b _L2_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) _L2_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) bne.b _L2_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) bsr.l src_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) bra.b _L2_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) _L2_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) bne.b _L2_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) bra.b _L2_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) _L2_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) bsr.l ssinhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) _L2_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) global _flognp1s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) _flognp1s_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) bne.b _L3_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) bsr.l slognp1 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) bra.b _L3_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) _L3_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) bne.b _L3_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) bra.b _L3_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) _L3_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) bne.b _L3_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) bra.b _L3_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) _L3_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) bne.b _L3_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) bra.b _L3_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) _L3_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) bsr.l slognp1d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) _L3_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) global _flognp1d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) _flognp1d_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) bne.b _L3_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) bsr.l slognp1 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) bra.b _L3_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) _L3_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) bne.b _L3_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) bra.b _L3_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) _L3_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) bne.b _L3_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) bra.b _L3_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) _L3_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) bne.b _L3_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) bra.b _L3_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) _L3_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) bsr.l slognp1d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) _L3_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) global _flognp1x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) _flognp1x_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) bne.b _L3_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) bsr.l slognp1 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) bra.b _L3_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) _L3_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) bne.b _L3_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) bra.b _L3_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) _L3_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) bne.b _L3_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) bra.b _L3_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) _L3_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) bne.b _L3_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) bra.b _L3_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) _L3_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) bsr.l slognp1d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) _L3_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) global _fetoxm1s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) _fetoxm1s_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) bne.b _L4_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) bsr.l setoxm1 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) bra.b _L4_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) _L4_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) bne.b _L4_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) bra.b _L4_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) _L4_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) bne.b _L4_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) bsr.l setoxm1i # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) bra.b _L4_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) _L4_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) bne.b _L4_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) bra.b _L4_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) _L4_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) bsr.l setoxm1d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) _L4_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) global _fetoxm1d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) _fetoxm1d_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) bne.b _L4_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) bsr.l setoxm1 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) bra.b _L4_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) _L4_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) bne.b _L4_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) bra.b _L4_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) _L4_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) bne.b _L4_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) bsr.l setoxm1i # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) bra.b _L4_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) _L4_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) bne.b _L4_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) bra.b _L4_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) _L4_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) bsr.l setoxm1d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) _L4_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) global _fetoxm1x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) _fetoxm1x_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) bne.b _L4_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) bsr.l setoxm1 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) bra.b _L4_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) _L4_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) bne.b _L4_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) bra.b _L4_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) _L4_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) bne.b _L4_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) bsr.l setoxm1i # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) bra.b _L4_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) _L4_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) bne.b _L4_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) bra.b _L4_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) _L4_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) bsr.l setoxm1d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) _L4_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) global _ftanhs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) _ftanhs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) bne.b _L5_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) bsr.l stanh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) bra.b _L5_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) _L5_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) bne.b _L5_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) bra.b _L5_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) _L5_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) bne.b _L5_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) bsr.l src_one # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) bra.b _L5_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) _L5_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) bne.b _L5_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) bra.b _L5_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) _L5_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) bsr.l stanhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) _L5_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) global _ftanhd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) _ftanhd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) bne.b _L5_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) bsr.l stanh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) bra.b _L5_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) _L5_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) bne.b _L5_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) bra.b _L5_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) _L5_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) bne.b _L5_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) bsr.l src_one # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) bra.b _L5_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) _L5_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) bne.b _L5_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) bra.b _L5_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) _L5_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) bsr.l stanhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) _L5_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) global _ftanhx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) _ftanhx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) bne.b _L5_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) bsr.l stanh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) bra.b _L5_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) _L5_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) bne.b _L5_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) bra.b _L5_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) _L5_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) bne.b _L5_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) bsr.l src_one # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) bra.b _L5_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) _L5_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) bne.b _L5_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) bra.b _L5_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) _L5_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) bsr.l stanhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) _L5_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) global _fatans_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) _fatans_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) bne.b _L6_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) bsr.l satan # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) bra.b _L6_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) _L6_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) bne.b _L6_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) bra.b _L6_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) _L6_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) bne.b _L6_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) bsr.l spi_2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) bra.b _L6_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) _L6_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) bne.b _L6_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) bra.b _L6_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) _L6_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) bsr.l satand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) _L6_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) global _fatand_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) _fatand_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) bne.b _L6_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) bsr.l satan # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) bra.b _L6_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) _L6_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) bne.b _L6_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) bra.b _L6_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) _L6_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) bne.b _L6_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) bsr.l spi_2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) bra.b _L6_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) _L6_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) bne.b _L6_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) bra.b _L6_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) _L6_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) bsr.l satand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) _L6_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) global _fatanx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) _fatanx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) bne.b _L6_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) bsr.l satan # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) bra.b _L6_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) _L6_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) bne.b _L6_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) bra.b _L6_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) _L6_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) bne.b _L6_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) bsr.l spi_2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) bra.b _L6_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) _L6_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) bne.b _L6_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) bra.b _L6_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) _L6_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) bsr.l satand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) _L6_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) global _fasins_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) _fasins_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) bne.b _L7_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) bsr.l sasin # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) bra.b _L7_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) _L7_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) bne.b _L7_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) bra.b _L7_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) _L7_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) bne.b _L7_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) bra.b _L7_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) _L7_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) bne.b _L7_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) bra.b _L7_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) _L7_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) bsr.l sasind # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) _L7_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) global _fasind_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) _fasind_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) bne.b _L7_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) bsr.l sasin # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) bra.b _L7_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) _L7_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) bne.b _L7_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) bra.b _L7_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) _L7_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) bne.b _L7_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) bra.b _L7_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) _L7_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) bne.b _L7_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) bra.b _L7_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) _L7_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) bsr.l sasind # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) _L7_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) global _fasinx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) _fasinx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) bne.b _L7_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) bsr.l sasin # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) bra.b _L7_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) _L7_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) bne.b _L7_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) bra.b _L7_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) _L7_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) bne.b _L7_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) bra.b _L7_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) _L7_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) bne.b _L7_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) bra.b _L7_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) _L7_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) bsr.l sasind # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) _L7_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) global _fatanhs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) _fatanhs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) bne.b _L8_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) bsr.l satanh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) bra.b _L8_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) _L8_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) bne.b _L8_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) bra.b _L8_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) _L8_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) bne.b _L8_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) bra.b _L8_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) _L8_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) bne.b _L8_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) bra.b _L8_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) _L8_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) bsr.l satanhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) _L8_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) global _fatanhd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) _fatanhd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) bne.b _L8_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) bsr.l satanh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) bra.b _L8_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) _L8_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) bne.b _L8_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) bra.b _L8_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) _L8_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) bne.b _L8_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) bra.b _L8_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) _L8_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) bne.b _L8_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) bra.b _L8_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) _L8_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) bsr.l satanhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) _L8_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) global _fatanhx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) _fatanhx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) bne.b _L8_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) bsr.l satanh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) bra.b _L8_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) _L8_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) bne.b _L8_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) bra.b _L8_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) _L8_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) bne.b _L8_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) bra.b _L8_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) _L8_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) bne.b _L8_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) bra.b _L8_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) _L8_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) bsr.l satanhd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) _L8_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) global _ftans_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) _ftans_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) bne.b _L9_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) bsr.l stan # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) bra.b _L9_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) _L9_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) bne.b _L9_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) bra.b _L9_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) _L9_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) bne.b _L9_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) bra.b _L9_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) _L9_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) bne.b _L9_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) bra.b _L9_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) _L9_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) bsr.l stand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) _L9_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) global _ftand_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) _ftand_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) bne.b _L9_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) bsr.l stan # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) bra.b _L9_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) _L9_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) bne.b _L9_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) bra.b _L9_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) _L9_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) bne.b _L9_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) bra.b _L9_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) _L9_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) bne.b _L9_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) bra.b _L9_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) _L9_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) bsr.l stand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) _L9_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) global _ftanx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) _ftanx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) bne.b _L9_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) bsr.l stan # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) bra.b _L9_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) _L9_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) bne.b _L9_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) bra.b _L9_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) _L9_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) bne.b _L9_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) bra.b _L9_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) _L9_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) bne.b _L9_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) bra.b _L9_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) _L9_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) bsr.l stand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) _L9_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) unlk %a6
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) global _fetoxs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) _fetoxs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) bne.b _L10_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) bsr.l setox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) bra.b _L10_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) _L10_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) bne.b _L10_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) bra.b _L10_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) _L10_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) bne.b _L10_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) bra.b _L10_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) _L10_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) bne.b _L10_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) bra.b _L10_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) _L10_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) bsr.l setoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) _L10_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) global _fetoxd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) _fetoxd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) bne.b _L10_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) bsr.l setox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) bra.b _L10_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) _L10_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) bne.b _L10_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) bra.b _L10_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) _L10_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) bne.b _L10_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) bra.b _L10_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) _L10_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) bne.b _L10_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) bra.b _L10_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) _L10_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) bsr.l setoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) _L10_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) global _fetoxx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) _fetoxx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) bne.b _L10_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) bsr.l setox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) bra.b _L10_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) _L10_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) bne.b _L10_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) bra.b _L10_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) _L10_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) bne.b _L10_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) bra.b _L10_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) _L10_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) bne.b _L10_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) bra.b _L10_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) _L10_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) bsr.l setoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) _L10_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) global _ftwotoxs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) _ftwotoxs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) bne.b _L11_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) bsr.l stwotox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) bra.b _L11_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) _L11_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) bne.b _L11_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) bra.b _L11_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) _L11_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) bne.b _L11_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) bra.b _L11_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) _L11_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) bne.b _L11_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) bra.b _L11_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) _L11_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) bsr.l stwotoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) _L11_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) global _ftwotoxd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) _ftwotoxd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) bne.b _L11_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) bsr.l stwotox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) bra.b _L11_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) _L11_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) bne.b _L11_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) bra.b _L11_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) _L11_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) bne.b _L11_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) bra.b _L11_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) _L11_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) bne.b _L11_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) bra.b _L11_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) _L11_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) bsr.l stwotoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) _L11_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) global _ftwotoxx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) _ftwotoxx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) bne.b _L11_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) bsr.l stwotox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) bra.b _L11_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) _L11_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) bne.b _L11_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) bra.b _L11_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) _L11_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) bne.b _L11_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) bra.b _L11_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) _L11_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) bne.b _L11_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) bra.b _L11_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) _L11_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) bsr.l stwotoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) _L11_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) global _ftentoxs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) _ftentoxs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) bne.b _L12_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) bsr.l stentox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) bra.b _L12_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) _L12_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) bne.b _L12_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) bra.b _L12_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) _L12_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) bne.b _L12_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) bra.b _L12_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) _L12_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) bne.b _L12_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) bra.b _L12_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) _L12_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) bsr.l stentoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) _L12_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) global _ftentoxd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) _ftentoxd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) bne.b _L12_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) bsr.l stentox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) bra.b _L12_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) _L12_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) bne.b _L12_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) bra.b _L12_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) _L12_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) bne.b _L12_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) bra.b _L12_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) _L12_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) bne.b _L12_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) bra.b _L12_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) _L12_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) bsr.l stentoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) _L12_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) global _ftentoxx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) _ftentoxx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) bne.b _L12_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) bsr.l stentox # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) bra.b _L12_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) _L12_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) bne.b _L12_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) bra.b _L12_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) _L12_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) bne.b _L12_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) bsr.l szr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) bra.b _L12_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) _L12_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) bne.b _L12_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) bra.b _L12_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) _L12_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) bsr.l stentoxd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) _L12_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) global _flogns_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) _flogns_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) bne.b _L13_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) bsr.l slogn # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) bra.b _L13_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) _L13_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) bne.b _L13_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) bra.b _L13_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) _L13_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) bne.b _L13_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) bra.b _L13_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) _L13_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) bne.b _L13_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) bra.b _L13_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) _L13_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) bsr.l slognd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) _L13_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) global _flognd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) _flognd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) bne.b _L13_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) bsr.l slogn # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) bra.b _L13_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) _L13_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) bne.b _L13_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) bra.b _L13_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) _L13_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) bne.b _L13_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) bra.b _L13_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) _L13_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) bne.b _L13_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) bra.b _L13_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) _L13_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) bsr.l slognd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) _L13_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) global _flognx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) _flognx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) bne.b _L13_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) bsr.l slogn # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) bra.b _L13_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) _L13_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) bne.b _L13_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) bra.b _L13_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) _L13_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) bne.b _L13_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) bra.b _L13_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) _L13_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) bne.b _L13_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) bra.b _L13_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) _L13_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) bsr.l slognd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) _L13_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) global _flog10s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) _flog10s_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) bne.b _L14_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) bsr.l slog10 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) bra.b _L14_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) _L14_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) bne.b _L14_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) bra.b _L14_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) _L14_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) bne.b _L14_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) bra.b _L14_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) _L14_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) bne.b _L14_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) bra.b _L14_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) _L14_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) bsr.l slog10d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) _L14_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) global _flog10d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) _flog10d_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) bne.b _L14_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) bsr.l slog10 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) bra.b _L14_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) _L14_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) bne.b _L14_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) bra.b _L14_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) _L14_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) bne.b _L14_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) bra.b _L14_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) _L14_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) bne.b _L14_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) bra.b _L14_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) _L14_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) bsr.l slog10d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) _L14_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) global _flog10x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) _flog10x_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) bne.b _L14_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) bsr.l slog10 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) bra.b _L14_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) _L14_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) bne.b _L14_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) bra.b _L14_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) _L14_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) bne.b _L14_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) bra.b _L14_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) _L14_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) bne.b _L14_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) bra.b _L14_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) _L14_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) bsr.l slog10d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) _L14_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) global _flog2s_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) _flog2s_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) bne.b _L15_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) bsr.l slog2 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) bra.b _L15_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) _L15_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) bne.b _L15_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) bra.b _L15_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) _L15_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) bne.b _L15_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) bra.b _L15_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) _L15_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) bne.b _L15_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) bra.b _L15_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) _L15_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) bsr.l slog2d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) _L15_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) global _flog2d_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) _flog2d_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) bne.b _L15_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) bsr.l slog2 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) bra.b _L15_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) _L15_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) bne.b _L15_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) bra.b _L15_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) _L15_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) bne.b _L15_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) bra.b _L15_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) _L15_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) bne.b _L15_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) bra.b _L15_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) _L15_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) bsr.l slog2d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) _L15_6d:
^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) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) global _flog2x_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) _flog2x_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) bne.b _L15_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) bsr.l slog2 # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) bra.b _L15_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) _L15_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) bne.b _L15_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) bsr.l t_dz2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) bra.b _L15_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) _L15_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) bne.b _L15_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) bsr.l sopr_inf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) bra.b _L15_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) _L15_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) bne.b _L15_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) bra.b _L15_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) _L15_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) bsr.l slog2d # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) _L15_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) global _fcoshs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) _fcoshs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) bne.b _L16_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) bsr.l scosh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) bra.b _L16_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) _L16_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) bne.b _L16_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) bra.b _L16_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) _L16_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) bne.b _L16_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) bsr.l ld_pinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) bra.b _L16_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) _L16_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) bne.b _L16_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) bra.b _L16_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) _L16_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) bsr.l scoshd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) _L16_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) global _fcoshd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) _fcoshd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) bne.b _L16_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) bsr.l scosh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) bra.b _L16_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) _L16_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) bne.b _L16_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) bra.b _L16_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) _L16_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) bne.b _L16_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) bsr.l ld_pinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) bra.b _L16_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) _L16_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) bne.b _L16_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) bra.b _L16_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) _L16_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) bsr.l scoshd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) _L16_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) global _fcoshx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) _fcoshx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) bne.b _L16_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) bsr.l scosh # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) bra.b _L16_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) _L16_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) bne.b _L16_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) bsr.l ld_pone # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) bra.b _L16_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) _L16_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) bne.b _L16_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) bsr.l ld_pinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) bra.b _L16_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) _L16_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) bne.b _L16_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) bra.b _L16_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) _L16_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) bsr.l scoshd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) _L16_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) global _facoss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) _facoss_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) bne.b _L17_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) bsr.l sacos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) bra.b _L17_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) _L17_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) bne.b _L17_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) bsr.l ld_ppi2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) bra.b _L17_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) _L17_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) bne.b _L17_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) bra.b _L17_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) _L17_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) bne.b _L17_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) bra.b _L17_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) _L17_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) bsr.l sacosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) _L17_6s:
^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) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) global _facosd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) _facosd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) bne.b _L17_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) bsr.l sacos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) bra.b _L17_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) _L17_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) bne.b _L17_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) bsr.l ld_ppi2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) bra.b _L17_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) _L17_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) bne.b _L17_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) bra.b _L17_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) _L17_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) bne.b _L17_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) bra.b _L17_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) _L17_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) bsr.l sacosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) _L17_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) global _facosx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) _facosx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) bne.b _L17_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) bsr.l sacos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) bra.b _L17_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) _L17_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) bne.b _L17_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) bsr.l ld_ppi2 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) bra.b _L17_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) _L17_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) bne.b _L17_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) bra.b _L17_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) _L17_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) bne.b _L17_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) bra.b _L17_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) _L17_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) bsr.l sacosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) _L17_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) global _fgetexps_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) _fgetexps_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) bne.b _L18_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) bsr.l sgetexp # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) bra.b _L18_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) _L18_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) bne.b _L18_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) bra.b _L18_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) _L18_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) bne.b _L18_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) bra.b _L18_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) _L18_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) bne.b _L18_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) bra.b _L18_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) _L18_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) bsr.l sgetexpd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) _L18_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) global _fgetexpd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) _fgetexpd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) bne.b _L18_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) bsr.l sgetexp # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) bra.b _L18_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) _L18_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) bne.b _L18_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) bra.b _L18_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) _L18_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) bne.b _L18_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) bra.b _L18_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) _L18_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) bne.b _L18_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) bra.b _L18_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) _L18_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) bsr.l sgetexpd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) _L18_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) global _fgetexpx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) _fgetexpx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) bne.b _L18_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) bsr.l sgetexp # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) bra.b _L18_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) _L18_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) bne.b _L18_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) bra.b _L18_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) _L18_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) bne.b _L18_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) bra.b _L18_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) _L18_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) bne.b _L18_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) bra.b _L18_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) _L18_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) bsr.l sgetexpd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) _L18_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) global _fgetmans_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) _fgetmans_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) bne.b _L19_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) bsr.l sgetman # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) bra.b _L19_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) _L19_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) bne.b _L19_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) bra.b _L19_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) _L19_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) bne.b _L19_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) bra.b _L19_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) _L19_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) bne.b _L19_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) bra.b _L19_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) _L19_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) bsr.l sgetmand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) _L19_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) global _fgetmand_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) _fgetmand_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) bne.b _L19_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) bsr.l sgetman # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) bra.b _L19_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) _L19_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) bne.b _L19_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) bra.b _L19_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) _L19_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) bne.b _L19_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) bra.b _L19_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) _L19_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) bne.b _L19_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) bra.b _L19_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) _L19_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) bsr.l sgetmand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) _L19_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) global _fgetmanx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) _fgetmanx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) bne.b _L19_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) bsr.l sgetman # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) bra.b _L19_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) _L19_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) bne.b _L19_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) bsr.l src_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) bra.b _L19_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) _L19_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) bne.b _L19_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) bsr.l t_operr # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) bra.b _L19_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) _L19_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) bne.b _L19_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) bsr.l src_qnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) bra.b _L19_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) _L19_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) bsr.l sgetmand # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) _L19_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) # MONADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) global _fsincoss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) _fsincoss_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) fmov.s 0x8(%a6),%fp0 # load sgl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) bne.b _L20_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) bsr.l ssincos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) bra.b _L20_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) _L20_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) bne.b _L20_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) bsr.l ssincosz # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) bra.b _L20_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) _L20_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) bne.b _L20_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) bsr.l ssincosi # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) bra.b _L20_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) _L20_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) bne.b _L20_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) bsr.l ssincosqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) bra.b _L20_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) _L20_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) bsr.l ssincosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) _L20_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) fmovm.x &0x03,-(%sp) # store off fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) fmovm.x (%sp)+,&0x40 # fp0 now in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) fmovm.x (%sp)+,&0x80 # fp1 now in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) global _fsincosd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) _fsincosd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) fmov.d 0x8(%a6),%fp0 # load dbl input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) mov.b %d1,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) bne.b _L20_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) bsr.l ssincos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) bra.b _L20_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) _L20_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) bne.b _L20_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) bsr.l ssincosz # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) bra.b _L20_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) _L20_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) bne.b _L20_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) bsr.l ssincosi # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) bra.b _L20_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) _L20_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) bne.b _L20_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) bsr.l ssincosqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) bra.b _L20_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) _L20_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) bsr.l ssincosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) _L20_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) fmovm.x &0x03,-(%sp) # store off fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) fmovm.x (%sp)+,&0x40 # fp0 now in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) fmovm.x (%sp)+,&0x80 # fp1 now in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) global _fsincosx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) _fsincosx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) mov.b %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) bne.b _L20_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) bsr.l ssincos # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) bra.b _L20_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) _L20_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) bne.b _L20_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) bsr.l ssincosz # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) bra.b _L20_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) _L20_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) bne.b _L20_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) bsr.l ssincosi # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) bra.b _L20_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) _L20_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) bne.b _L20_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) bsr.l ssincosqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) bra.b _L20_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) _L20_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) bsr.l ssincosd # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) _L20_6x:
^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) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) fmovm.x &0x03,-(%sp) # store off fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) fmovm.x (%sp)+,&0x40 # fp0 now in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) fmovm.x (%sp)+,&0x80 # fp1 now in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) # DYADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) global _frems_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) _frems_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) fmov.s 0x8(%a6),%fp0 # load sgl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) fmov.x %fp0,FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) fmov.s 0xc(%a6),%fp0 # load sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) bne.b _L21_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) bsr.l srem_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) bra.b _L21_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) _L21_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) bne.b _L21_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) bsr.l srem_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) bra.b _L21_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) _L21_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) bne.b _L21_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) bsr.l srem_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) bra.b _L21_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) _L21_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) bne.b _L21_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) bra.b _L21_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) _L21_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) bsr.l srem_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) _L21_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) global _fremd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) _fremd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) fmov.d 0x8(%a6),%fp0 # load dbl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) fmov.x %fp0,FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) fmov.d 0x10(%a6),%fp0 # load dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) bne.b _L21_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) bsr.l srem_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) bra.b _L21_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) _L21_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) bne.b _L21_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) bsr.l srem_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) bra.b _L21_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) _L21_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) bne.b _L21_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) bsr.l srem_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) bra.b _L21_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) _L21_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) bne.b _L21_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) bra.b _L21_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) _L21_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) bsr.l srem_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) _L21_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) global _fremx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) _fremx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) mov.l 0x14+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) mov.l 0x14+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) bne.b _L21_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) bsr.l srem_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) bra.b _L21_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) _L21_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) bne.b _L21_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) bsr.l srem_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) bra.b _L21_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) _L21_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) bne.b _L21_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) bsr.l srem_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) bra.b _L21_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) _L21_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) bne.b _L21_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) bra.b _L21_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) _L21_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) bsr.l srem_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) _L21_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) # DYADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) global _fmods_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) _fmods_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) fmov.s 0x8(%a6),%fp0 # load sgl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) fmov.x %fp0,FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) fmov.s 0xc(%a6),%fp0 # load sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) bne.b _L22_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) bsr.l smod_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) bra.b _L22_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) _L22_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) bne.b _L22_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) bsr.l smod_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) bra.b _L22_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) _L22_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) bne.b _L22_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) bsr.l smod_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) bra.b _L22_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) _L22_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) bne.b _L22_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) bra.b _L22_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) _L22_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) bsr.l smod_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) _L22_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) global _fmodd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) _fmodd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) fmov.d 0x8(%a6),%fp0 # load dbl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) fmov.x %fp0,FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) fmov.d 0x10(%a6),%fp0 # load dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) bne.b _L22_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) bsr.l smod_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) bra.b _L22_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) _L22_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) bne.b _L22_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) bsr.l smod_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) bra.b _L22_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) _L22_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) bne.b _L22_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) bsr.l smod_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) bra.b _L22_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) _L22_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) bne.b _L22_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) bra.b _L22_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) _L22_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) bsr.l smod_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) _L22_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) global _fmodx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) _fmodx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) mov.l 0x14+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) mov.l 0x14+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) bne.b _L22_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) bsr.l smod_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) bra.b _L22_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) _L22_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) bne.b _L22_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) bsr.l smod_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) bra.b _L22_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) _L22_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) bne.b _L22_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) bsr.l smod_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) bra.b _L22_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) _L22_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) bne.b _L22_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) bra.b _L22_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) _L22_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) bsr.l smod_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) _L22_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) # DYADIC TEMPLATE #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) global _fscales_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) _fscales_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) fmov.s 0x8(%a6),%fp0 # load sgl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) fmov.x %fp0,FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) fmov.s 0xc(%a6),%fp0 # load sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) bne.b _L23_2s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) bsr.l sscale_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) bra.b _L23_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) _L23_2s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) bne.b _L23_3s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) bsr.l sscale_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) bra.b _L23_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) _L23_3s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) bne.b _L23_4s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) bsr.l sscale_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) bra.b _L23_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) _L23_4s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) bne.b _L23_5s # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) bra.b _L23_6s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) _L23_5s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) bsr.l sscale_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) _L23_6s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) global _fscaled_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) _fscaled_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) fmov.d 0x8(%a6),%fp0 # load dbl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) fmov.x %fp0,FP_DST(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) fmov.d 0x10(%a6),%fp0 # load dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) fmov.x %fp0,FP_SRC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) bne.b _L23_2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) bsr.l sscale_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) bra.b _L23_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) _L23_2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) bne.b _L23_3d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) bsr.l sscale_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) bra.b _L23_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) _L23_3d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) bne.b _L23_4d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) bsr.l sscale_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) bra.b _L23_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) _L23_4d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) bne.b _L23_5d # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) bra.b _L23_6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) _L23_5d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) bsr.l sscale_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) _L23_6d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) global _fscalex_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) _fscalex_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) link %a6,&-LOCAL_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) fmovm.l %fpcr,%fpsr,USER_FPCR(%a6) # save ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) fmovm.x &0xc0,EXC_FP0(%a6) # save fp0/fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) fmov.l &0x0,%fpcr # zero FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) # copy, convert, and tag input argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) lea FP_DST(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) mov.l 0x8+0x0(%a6),0x0(%a0) # load ext dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) mov.l 0x8+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) mov.l 0x8+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) mov.b %d0,DTAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) lea FP_SRC(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) mov.l 0x14+0x0(%a6),0x0(%a0) # load ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) mov.l 0x14+0x4(%a6),0x4(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) mov.l 0x14+0x8(%a6),0x8(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) bsr.l tag # fetch operand type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) mov.b %d0,STAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) mov.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) andi.l &0x00ff00ff,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) mov.b FPCR_MODE(%a6),%d0 # pass rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) lea FP_SRC(%a6),%a0 # pass ptr to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) lea FP_DST(%a6),%a1 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) tst.b %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) bne.b _L23_2x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) bsr.l sscale_snorm # operand is a NORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) bra.b _L23_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) _L23_2x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) cmpi.b %d1,&ZERO # is operand a ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) bne.b _L23_3x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) bsr.l sscale_szero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) bra.b _L23_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) _L23_3x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) cmpi.b %d1,&INF # is operand an INF?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) bne.b _L23_4x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) bsr.l sscale_sinf # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) bra.b _L23_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) _L23_4x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) cmpi.b %d1,&QNAN # is operand a QNAN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) bne.b _L23_5x # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) bsr.l sop_sqnan # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) bra.b _L23_6x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) _L23_5x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) bsr.l sscale_sdnrm # operand is a DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) _L23_6x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) # Result is now in FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) fmovm.l USER_FPCR(%a6),%fpcr,%fpsr # restore ctrl regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) fmovm.x EXC_FP1(%a6),&0x40 # restore fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) unlk %a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) # ssin(): computes the sine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) # ssind(): computes the sine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) # scos(): computes the cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) # scosd(): computes the cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) # ssincos(): computes the sine and cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) # ssincosd(): computes the sine and cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) # fp0 = sin(X) or cos(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) # For ssincos(X): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) # fp0 = sin(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) # fp1 = cos(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) # The returned result is within 1 ulp in 64 significant bit, i.e. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) # within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) # SIN and COS: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) # 1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) # 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) # 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) # k = N mod 4, so in particular, k = 0,1,2,or 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) # Overwrite k by k := k + AdjN. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) # 4. If k is even, go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) # 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) # Return sgn*cos(r) where cos(r) is approximated by an #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) # even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) # s = r*r. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) # 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) # where sin(r) is approximated by an odd polynomial in r #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) # r + r*s*(A1+s*(A2+ ... + s*A7)), s = r*r. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) # 7. If |X| > 1, go to 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) # 8. (|X|<2**(-40)) If SIN is invoked, return X; #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) # otherwise return 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) # 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) # go back to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) # SINCOS: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) # k = N mod 4, so in particular, k = 0,1,2,or 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) # 3. If k is even, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) # 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 4959) # j1 exclusive or with the l.s.b. of k. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) # sgn1 := (-1)**j1, sgn2 := (-1)**j2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) # SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) # sin(r) and cos(r) are computed as odd and even #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) # polynomials in r, respectively. Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) # 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) # SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) # sin(r) and cos(r) are computed as odd and even #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) # polynomials in r, respectively. Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) # 6. If |X| > 1, go to 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) # 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) # go back to 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) SINA7: long 0xBD6AAA77,0xCCC994F5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) SINA6: long 0x3DE61209,0x7AAE8DA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) SINA5: long 0xBE5AE645,0x2A118AE4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) SINA4: long 0x3EC71DE3,0xA5341531
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) SINA3: long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) SINA2: long 0x3FF80000,0x88888888,0x888859AF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) SINA1: long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) COSB8: long 0x3D2AC4D0,0xD6011EE3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) COSB7: long 0xBDA9396F,0x9F45AC19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) COSB6: long 0x3E21EED9,0x0612C972
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) COSB5: long 0xBE927E4F,0xB79D9FCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) COSB4: long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) COSB3: long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) COSB2: long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) COSB1: long 0xBF000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) set INARG,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) # set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) set RPRIME,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) set SPRIME,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) set POSNEG1,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) set TWOTO63,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) set ENDFLAG,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) set INT,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) set ADJN,L_SCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) global ssin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) ssin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) mov.l &0,ADJN(%a6) # yes; SET ADJN TO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) bra.b SINBGN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) global scos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) scos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) mov.l &1,ADJN(%a6) # yes; SET ADJN TO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) SINBGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) fmov.x %fp0,X(%a6) # save input at X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) # "COMPACTIFY" X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) mov.l (%a0),%d1 # put exp in hi word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) mov.w 4(%a0),%d1 # fetch hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) and.l &0x7FFFFFFF,%d1 # strip sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) cmpi.l %d1,&0x3FD78000 # is |X| >= 2**(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) bge.b SOK1 # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) bra.w SINSM # yes; input is very small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) SOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) cmp.l %d1,&0x4004BC7E # is |X| < 15 PI?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) blt.b SINMAIN # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) bra.w SREDUCEX # yes; input is very large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) #--THIS IS THE USUAL CASE, |X| <= 15 PI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) SINMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) mov.l INT(%a6),%d1 # make a copy of N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) asl.l &4,%d1 # N *= 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) add.l %d1,%a1 # tbl_addr = a1 + (N*16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) # A1 IS THE ADDRESS OF N*PIBY2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) # ...WHICH IS IN TWO PIECES Y1 & Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) fsub.x (%a1)+,%fp0 # X-Y1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) fsub.s (%a1),%fp0 # fp0 = R = (X-Y1)-Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) SINCONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) #--continuation from REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) add.l ADJN(%a6),%d1 # SEE IF D0 IS ODD OR EVEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) ror.l &1,%d1 # D0 WAS ODD IFF D0 IS NEGATIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) blt.w COSPOLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) #--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) #--WHERE T=S*S.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) SINPOLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) fmov.x %fp0,X(%a6) # X IS R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) fmul.x %fp0,%fp0 # FP0 IS S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) fmov.d SINA7(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) fmov.d SINA6(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) fmul.x %fp1,%fp1 # FP1 IS T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) eor.l %d1,X(%a6) # X IS NOW R'= SGN*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) fmul.x %fp1,%fp3 # TA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) fmul.x %fp1,%fp2 # TA6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) fadd.d SINA5(%pc),%fp3 # A5+TA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) fadd.d SINA4(%pc),%fp2 # A4+TA6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) fmul.x %fp1,%fp3 # T(A5+TA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) fmul.x %fp1,%fp2 # T(A4+TA6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) fadd.d SINA3(%pc),%fp3 # A3+T(A5+TA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) fadd.x SINA2(%pc),%fp2 # A2+T(A4+TA6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) fmul.x %fp3,%fp1 # T(A3+T(A5+TA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) fmul.x %fp0,%fp2 # S(A2+T(A4+TA6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) fadd.x SINA1(%pc),%fp1 # A1+T(A3+T(A5+TA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) fmul.x X(%a6),%fp0 # R'*S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) fadd.x %fp2,%fp1 # [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) fmul.x %fp1,%fp0 # SIN(R')-R'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) fadd.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) #--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) #--WHERE T=S*S.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) #--AND IS THEREFORE STORED AS SINGLE PRECISION.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) COSPOLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) fmul.x %fp0,%fp0 # FP0 IS S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) fmov.d COSB8(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) fmov.d COSB7(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) fmul.x %fp1,%fp1 # FP1 IS T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) fmov.x %fp0,X(%a6) # X IS S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) # ...LEAST SIG. BIT OF D0 IN SIGN POSITION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) fmul.x %fp1,%fp2 # TB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) eor.l %d1,X(%a6) # X IS NOW S'= SGN*S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) fmul.x %fp1,%fp3 # TB7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) or.l &0x3F800000,%d1 # D0 IS SGN IN SINGLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) mov.l %d1,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) fadd.d COSB6(%pc),%fp2 # B6+TB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) fadd.d COSB5(%pc),%fp3 # B5+TB7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) fmul.x %fp1,%fp2 # T(B6+TB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) fmul.x %fp1,%fp3 # T(B5+TB7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) fadd.d COSB4(%pc),%fp2 # B4+T(B6+TB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) fadd.x COSB3(%pc),%fp3 # B3+T(B5+TB7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) fmul.x %fp1,%fp2 # T(B4+T(B6+TB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) fmul.x %fp3,%fp1 # T(B3+T(B5+TB7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) fadd.x COSB2(%pc),%fp2 # B2+T(B4+T(B6+TB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) fadd.s COSB1(%pc),%fp1 # B1+T(B3+T(B5+TB7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) fmul.x %fp2,%fp0 # S(B2+T(B4+T(B6+TB8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) fadd.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) fmul.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) fadd.s POSNEG1(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) ##############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) # SINe: Big OR Small?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) #--IF |X| < 2**(-40), RETURN X OR 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) SINBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) bgt.l SREDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) SINSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) mov.l ADJN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) bgt.b COSTINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) # here, the operation may underflow iff the precision is sgl or dbl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) # extended denorms are handled through another entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) SINTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) # mov.w &0x0000,XDCARE(%a6) # JUST IN CASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) fmov.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) COSTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) fmov.s &0x3F800000,%fp0 # fp0 = 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) fadd.s &0x80800000,%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) ################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) global ssind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) #--SIN(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) ssind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) global scosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) #--COS(X) = 1 FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) scosd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) fmov.s &0x3F800000,%fp0 # fp0 = 1.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) ##################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) global ssincos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) ssincos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) #--SET ADJN TO 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) mov.l &4,ADJN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) and.l &0x7FFFFFFF,%d1 # COMPACTIFY X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) bge.b SCOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) bra.w SCSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) SCOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) cmp.l %d1,&0x4004BC7E # |X| < 15 PI?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) blt.b SCMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) bra.w SREDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) #--THIS IS THE USUAL CASE, |X| <= 15 PI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) SCMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) asl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) add.l %d1,%a1 # ADDRESS OF N*PIBY2, IN Y1, Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) fsub.x (%a1)+,%fp0 # X-Y1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) SCCONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) #--continuation point from REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) cmp.l %d1,&0 # D0 < 0 IFF N IS ODD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) bge.w NEVEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) SNODD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) #--REGISTERS SAVED SO FAR: D0, A0, FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) fmovm.x &0x04,-(%sp) # save fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) fmov.x %fp0,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) fmul.x %fp0,%fp0 # FP0 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) fmov.d SINA7(%pc),%fp1 # A7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) fmov.d COSB8(%pc),%fp2 # B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) fmul.x %fp0,%fp1 # SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) fmul.x %fp0,%fp2 # SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) mov.l %d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) mov.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) ror.l &1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) eor.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) fadd.d SINA6(%pc),%fp1 # A6+SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) fadd.d COSB7(%pc),%fp2 # B7+SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) fmul.x %fp0,%fp1 # S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) eor.l %d2,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) mov.l (%sp)+,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) fmul.x %fp0,%fp2 # S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) mov.l &0x3F800000,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) eor.l %d1,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) fadd.d SINA5(%pc),%fp1 # A5+S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) fadd.d COSB6(%pc),%fp2 # B6+S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) fmul.x %fp0,%fp1 # S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) fmul.x %fp0,%fp2 # S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) fmov.x %fp0,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) fadd.d SINA4(%pc),%fp1 # A4+S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) eor.l %d1,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) fadd.d COSB5(%pc),%fp2 # B5+S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) fmul.x %fp0,%fp1 # S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) fmul.x %fp0,%fp2 # S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) fadd.d SINA3(%pc),%fp1 # A3+S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) fadd.d COSB4(%pc),%fp2 # B4+S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) fmul.x %fp0,%fp1 # S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) fmul.x %fp0,%fp2 # S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) fadd.x SINA2(%pc),%fp1 # A2+S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) fadd.x COSB3(%pc),%fp2 # B3+S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) fmul.x %fp0,%fp1 # S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) fmul.x %fp0,%fp2 # S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) fadd.x SINA1(%pc),%fp1 # A1+S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) fadd.x COSB2(%pc),%fp2 # B2+S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) fmul.x %fp0,%fp1 # S(A1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) fmul.x %fp2,%fp0 # S(B2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) fmul.x RPRIME(%a6),%fp1 # R'S(A1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) fadd.s COSB1(%pc),%fp0 # B1+S(B2...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) fmul.x SPRIME(%a6),%fp0 # S'(B1+S(B2+...))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) fmovm.x (%sp)+,&0x20 # restore fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) fadd.x RPRIME(%a6),%fp1 # COS(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) fadd.s POSNEG1(%a6),%fp0 # SIN(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) NEVEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) #--REGISTERS SAVED SO FAR: FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) fmovm.x &0x04,-(%sp) # save fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) fmov.x %fp0,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) fmul.x %fp0,%fp0 # FP0 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) fmov.d COSB8(%pc),%fp1 # B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) fmov.d SINA7(%pc),%fp2 # A7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) fmul.x %fp0,%fp1 # SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) fmov.x %fp0,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) fmul.x %fp0,%fp2 # SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) fadd.d COSB7(%pc),%fp1 # B7+SB8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) fadd.d SINA6(%pc),%fp2 # A6+SA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) eor.l %d1,RPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) eor.l %d1,SPRIME(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) fmul.x %fp0,%fp1 # S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) or.l &0x3F800000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) mov.l %d1,POSNEG1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) fmul.x %fp0,%fp2 # S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) fadd.d COSB6(%pc),%fp1 # B6+S(B7+SB8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) fadd.d SINA5(%pc),%fp2 # A5+S(A6+SA7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) fmul.x %fp0,%fp1 # S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) fmul.x %fp0,%fp2 # S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) fadd.d COSB5(%pc),%fp1 # B5+S(B6+S(B7+SB8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) fadd.d SINA4(%pc),%fp2 # A4+S(A5+S(A6+SA7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) fmul.x %fp0,%fp1 # S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) fmul.x %fp0,%fp2 # S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) fadd.d COSB4(%pc),%fp1 # B4+S(B5+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) fadd.d SINA3(%pc),%fp2 # A3+S(A4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) fmul.x %fp0,%fp1 # S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) fmul.x %fp0,%fp2 # S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) fadd.x COSB3(%pc),%fp1 # B3+S(B4+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) fadd.x SINA2(%pc),%fp2 # A2+S(A3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) fmul.x %fp0,%fp1 # S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) fmul.x %fp0,%fp2 # S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) fadd.x COSB2(%pc),%fp1 # B2+S(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) fadd.x SINA1(%pc),%fp2 # A1+S(A2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) fmul.x %fp0,%fp1 # S(B2+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) fmul.x %fp2,%fp0 # s(a1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) fadd.s COSB1(%pc),%fp1 # B1+S(B2...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) fmul.x RPRIME(%a6),%fp0 # R'S(A1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) fmul.x SPRIME(%a6),%fp1 # S'(B1+S(B2+...))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) fmovm.x (%sp)+,&0x20 # restore fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) fadd.s POSNEG1(%a6),%fp1 # COS(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) fadd.x RPRIME(%a6),%fp0 # SIN(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) ################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) SCBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) bgt.w SREDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) ################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) SCSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) # mov.w &0x0000,XDCARE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) fsub.s &0x00800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) fmov.l %fpcr,%d0 # d0 must have fpcr,too
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) ##############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) global ssincosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) #--SIN AND COS OF X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) ssincosd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) mov.l %d0,-(%sp) # save d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) bsr sto_cos # store cosine result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) ############################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) SREDUCEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) fmovm.x &0x3c,-(%sp) # save {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) fmov.s &0x00000000,%fp1 # fp1 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) #--there is a danger of unwanted overflow in first LOOP iteration. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) #--case, reduce argument by one remainder step to make subsequent reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) #--safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) cmp.l %d1,&0x7ffeffff # is arg dangerously large?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) bne.b SLOOP # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) # yes; create 2**16383*PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) mov.w &0x7ffe,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) mov.l &0xc90fdaa2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) clr.l FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) # create low half of 2**16383*PI/2 at FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) mov.w &0x7fdc,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) mov.l &0x85a308d3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) clr.l FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) ftest.x %fp0 # test sign of argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) fblt.w sred_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) or.b &0x80,FP_SCR0_EX(%a6) # positive arg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) or.b &0x80,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) sred_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) fmov.x %fp0,%fp1 # save high result in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) fadd.x FP_SCR1(%a6),%fp0 # low part of reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) fsub.x %fp0,%fp1 # determine low component of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) #--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 5500) #--integer quotient will be stored in N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) SLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) mov.w INARG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) mov.l %d1,%a1 # save a copy of D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) and.l &0x00007FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) sub.l &0x00003FFF,%d1 # d0 = K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) cmp.l %d1,&28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) ble.b SLASTLOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) SCONTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) sub.l &27,%d1 # d0 = L := K-27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) mov.b &0,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) bra.b SWORK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) SLASTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) clr.l %d1 # d0 = L := 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) mov.b &1,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) SWORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) #--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 5520) #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) #--2**L * (PIby2_1), 2**L * (PIby2_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) mov.l &0xA2F9836E,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) mov.l &0x4E44152A,FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) #--US THE DESIRED VALUE IN FLOATING POINT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) mov.l %a1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) swap %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) mov.l %d2,TWOTO63(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) fsub.s TWOTO63(%a6),%fp2 # fp2 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) # fint.x %fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) mov.l %d1,%d2 # d2 = L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) mov.w %d2,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) mov.l &0xC90FDAA2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) add.l &0x00003FDD,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) mov.w %d1,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) mov.l &0x85A308D3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) mov.b ENDFLAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) #--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 5565) #--P2 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) fmov.x %fp2,%fp4 # fp4 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) fmov.x %fp2,%fp5 # fp5 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) fmov.x %fp4,%fp3 # fp3 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) #--we want P+p = W+w but |p| <= half ulp of P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) #--Then, we need to compute A := R-P and a := r-p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) fadd.x %fp5,%fp3 # fp3 = P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) fsub.x %fp3,%fp4 # fp4 = W-P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) fsub.x %fp3,%fp0 # fp0 = A := R - P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) fmov.x %fp0,%fp3 # fp3 = A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) fsub.x %fp4,%fp1 # fp1 = a := r - p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) #--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 5584) #--|r| <= half ulp of R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) fadd.x %fp1,%fp0 # fp0 = R := A+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) #--No need to calculate r if this is the last loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) cmp.b %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) bgt.w SRESTORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) #--Need to calculate r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) fsub.x %fp0,%fp3 # fp3 = A-R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) bra.w SLOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) SRESTORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) fmov.l %fp2,INT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) fmovm.x (%sp)+,&0x3c # restore {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) mov.l ADJN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) cmp.l %d1,&4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) blt.w SINCONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) bra.w SCCONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) # stan(): computes the tangent of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) # stand(): computes the tangent of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) # fp0 = tan(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) # The returned result is within 3 ulp in 64 significant bit, i.e. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) # within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) # k = N mod 2, so in particular, k = 0 or 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) # 3. If k is odd, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) # 4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) # rational function U/V where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) # U = r + r*s*(P1 + s*(P2 + s*P3)), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) # 4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) # a rational function U/V where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) # U = r + r*s*(P1 + s*(P2 + s*P3)), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) # -Cot(r) = -V/U. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) # 6. If |X| > 1, go to 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) # 7. (|X|<2**(-40)) Tan(X) = X. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) # to 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) TANQ4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) long 0x3EA0B759,0xF50F8688
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) TANP3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) long 0xBEF2BAA5,0xA8924F04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) TANQ3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) long 0xBF346F59,0xB39BA65F,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) TANP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) long 0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) TANQ2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) long 0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) TANP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) long 0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) TANQ1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) long 0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) INVTWOPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) long 0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) TWOPI1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) long 0x40010000,0xC90FDAA2,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) TWOPI2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) #--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 5683) #--MOST 69 BITS LONG.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) # global PITBL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) PITBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) long 0xC0040000,0xC90FDAA2,0x2168C235,0x21800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) long 0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) long 0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) long 0xC0040000,0xB6365E22,0xEE46F000,0x21480000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) long 0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) long 0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) long 0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) long 0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) long 0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) long 0xC0040000,0x90836524,0x88034B96,0x20B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) long 0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) long 0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) long 0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) long 0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) long 0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) long 0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) long 0xC0030000,0xC90FDAA2,0x2168C235,0x21000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) long 0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) long 0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) long 0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) long 0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) long 0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) long 0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) long 0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) long 0xC0020000,0xC90FDAA2,0x2168C235,0x20800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) long 0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) long 0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) long 0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) long 0xC0010000,0xC90FDAA2,0x2168C235,0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) long 0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) long 0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) long 0x00000000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) long 0x40000000,0xC90FDAA2,0x2168C235,0x9F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) long 0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) long 0x40010000,0xC90FDAA2,0x2168C235,0xA0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) long 0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) long 0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) long 0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) long 0x40020000,0xC90FDAA2,0x2168C235,0xA0800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) long 0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) long 0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) long 0x40030000,0x8A3AE64F,0x76F80584,0x21080000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) long 0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) long 0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) long 0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) long 0x40030000,0xBC7EDCF7,0xFF523611,0x21680000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) long 0x40030000,0xC90FDAA2,0x2168C235,0xA1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) long 0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) long 0x40030000,0xE231D5F6,0x6595DA7B,0x21300000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) long 0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) long 0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) long 0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) long 0x40040000,0x8A3AE64F,0x76F80584,0x21880000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) long 0x40040000,0x90836524,0x88034B96,0xA0B00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) long 0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) long 0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) long 0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) long 0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) long 0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) long 0x40040000,0xB6365E22,0xEE46F000,0xA1480000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) long 0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) long 0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) long 0x40040000,0xC90FDAA2,0x2168C235,0xA1800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) set INARG,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) set TWOTO63,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) set INT,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) set ENDFLAG,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) global stan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) stan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) bge.b TANOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) bra.w TANSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) TANOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) cmp.l %d1,&0x4004BC7E # |X| < 15 PI?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) blt.b TANMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) bra.w REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) TANMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) #--THIS IS THE USUAL CASE, |X| <= 15 PI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) fmul.d TWOBYPI(%pc),%fp1 # X*2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) lea.l PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) fmov.l %fp1,%d1 # CONVERT TO INTEGER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) asl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) add.l %d1,%a1 # ADDRESS N*PIBY2 IN Y1, Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) fsub.x (%a1)+,%fp0 # X-Y1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) ror.l &5,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) and.l &0x80000000,%d1 # D0 WAS ODD IFF D0 < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) TANCONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) fmovm.x &0x0c,-(%sp) # save fp2,fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) blt.w NODD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) fmul.x %fp1,%fp1 # S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) fmov.d TANQ4(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) fmov.d TANP3(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) fmul.x %fp1,%fp3 # SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) fmul.x %fp1,%fp2 # SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) fadd.d TANQ3(%pc),%fp3 # Q3+SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) fadd.x TANP2(%pc),%fp2 # P2+SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) fmul.x %fp1,%fp3 # S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) fmul.x %fp1,%fp2 # S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) fmul.x %fp1,%fp3 # S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) fmul.x %fp1,%fp2 # S(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) fmul.x %fp0,%fp2 # RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) fmul.x %fp3,%fp1 # S(Q1+S(Q2+S(Q3+SQ4)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) fadd.x %fp2,%fp0 # R+RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) fadd.s &0x3F800000,%fp1 # 1+S(Q1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) fmovm.x (%sp)+,&0x30 # restore fp2,fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) fdiv.x %fp1,%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) NODD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) fmul.x %fp0,%fp0 # S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) fmov.d TANQ4(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) fmov.d TANP3(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) fmul.x %fp0,%fp3 # SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) fmul.x %fp0,%fp2 # SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) fadd.d TANQ3(%pc),%fp3 # Q3+SQ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) fadd.x TANP2(%pc),%fp2 # P2+SP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) fmul.x %fp0,%fp3 # S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) fmul.x %fp0,%fp2 # S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) fmul.x %fp0,%fp3 # S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) fmul.x %fp0,%fp2 # S(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) fmul.x %fp1,%fp2 # RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) fmul.x %fp3,%fp0 # S(Q1+S(Q2+S(Q3+SQ4)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) fadd.x %fp2,%fp1 # R+RS(P1+S(P2+SP3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) fadd.s &0x3F800000,%fp0 # 1+S(Q1+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) fmovm.x (%sp)+,&0x30 # restore fp2,fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) fmov.x %fp1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) eor.l &0x80000000,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) fdiv.x (%sp)+,%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) TANBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) #--IF |X| < 2**(-40), RETURN X OR 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) bgt.b REDUCEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) TANSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) fmov.x %fp0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) fmov.l %d0,%fpcr # restore users round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) fmov.x (%sp)+,%fp0 # last inst - posibble exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) global stand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) #--TAN(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) stand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) REDUCEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) fmovm.x &0x3c,-(%sp) # save {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) mov.l %d2,-(%sp) # save d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) fmov.s &0x00000000,%fp1 # fp1 = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) #--there is a danger of unwanted overflow in first LOOP iteration. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) #--case, reduce argument by one remainder step to make subsequent reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) #--safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) cmp.l %d1,&0x7ffeffff # is arg dangerously large?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) bne.b LOOP # no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) # yes; create 2**16383*PI/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) mov.w &0x7ffe,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) mov.l &0xc90fdaa2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) clr.l FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) # create low half of 2**16383*PI/2 at FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) mov.w &0x7fdc,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) mov.l &0x85a308d3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) clr.l FP_SCR1_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) ftest.x %fp0 # test sign of argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) fblt.w red_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) or.b &0x80,FP_SCR0_EX(%a6) # positive arg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) or.b &0x80,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) red_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) fmov.x %fp0,%fp1 # save high result in fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) fadd.x FP_SCR1(%a6),%fp0 # low part of reduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) fsub.x %fp0,%fp1 # determine low component of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) #--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 5931) #--integer quotient will be stored in N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) LOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) mov.w INARG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) mov.l %d1,%a1 # save a copy of D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) and.l &0x00007FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) sub.l &0x00003FFF,%d1 # d0 = K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) cmp.l %d1,&28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) ble.b LASTLOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) CONTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) sub.l &27,%d1 # d0 = L := K-27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) mov.b &0,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) bra.b WORK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) LASTLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) clr.l %d1 # d0 = L := 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) mov.b &1,ENDFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) WORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) #--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 5951) #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) #--2**L * (PIby2_1), 2**L * (PIby2_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) mov.l &0xA2F9836E,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) mov.l &0x4E44152A,FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) #--US THE DESIRED VALUE IN FLOATING POINT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) mov.l %a1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) swap %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) and.l &0x80000000,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) mov.l %d2,TWOTO63(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) fsub.s TWOTO63(%a6),%fp2 # fp2 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) # fintrz.x %fp2,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) mov.l %d1,%d2 # d2 = L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) mov.w %d2,FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) mov.l &0xC90FDAA2,FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) add.l &0x00003FDD,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) mov.w %d1,FP_SCR1_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) mov.l &0x85A308D3,FP_SCR1_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) mov.b ENDFLAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) #--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 5996) #--P2 = 2**(L) * Piby2_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) fmov.x %fp2,%fp4 # fp4 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) fmov.x %fp2,%fp5 # fp5 = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) fmov.x %fp4,%fp3 # fp3 = W = N*P1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) #--we want P+p = W+w but |p| <= half ulp of P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) #--Then, we need to compute A := R-P and a := r-p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) fadd.x %fp5,%fp3 # fp3 = P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) fsub.x %fp3,%fp4 # fp4 = W-P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) fsub.x %fp3,%fp0 # fp0 = A := R - P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) fmov.x %fp0,%fp3 # fp3 = A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) fsub.x %fp4,%fp1 # fp1 = a := r - p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) #--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 6015) #--|r| <= half ulp of R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) fadd.x %fp1,%fp0 # fp0 = R := A+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) #--No need to calculate r if this is the last loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) cmp.b %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) bgt.w RESTORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) #--Need to calculate r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) fsub.x %fp0,%fp3 # fp3 = A-R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) bra.w LOOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) RESTORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) fmov.l %fp2,INT(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) mov.l (%sp)+,%d2 # restore d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) fmovm.x (%sp)+,&0x3c # restore {fp2-fp5}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) ror.l &1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) bra.w TANCONT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) # satan(): computes the arctangent of a normalized number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) # satand(): computes the arctangent of a denormalized number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) # fp0 = arctan(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) # The returned result is within 2 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) # Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) # Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) # Note that k = -4, -3,..., or 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) # Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) # significant bits of X with a bit-1 attached at the 6-th #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) # bit position. Define u to be u = (X-F) / (1 + X*F). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) # Step 3. Approximate arctan(u) by a polynomial poly. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) # Step 4. Return arctan(F) + poly, arctan(F) is fetched from a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) # table of values calculated beforehand. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) # Step 5. If |X| >= 16, go to Step 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) # Step 6. Approximate arctan(X) by an odd polynomial in X. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) # Step 7. Define X' = -1/X. Approximate arctan(X') by an odd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) # polynomial in X'. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) # Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) ATANA3: long 0xBFF6687E,0x314987D8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) ATANA2: long 0x4002AC69,0x34A26DB3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) ATANA1: long 0xBFC2476F,0x4E1DA28E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) ATANB6: long 0x3FB34444,0x7F876989
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) ATANB5: long 0xBFB744EE,0x7FAF45DB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) ATANB4: long 0x3FBC71C6,0x46940220
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) ATANB3: long 0xBFC24924,0x921872F9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) ATANB2: long 0x3FC99999,0x99998FA9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) ATANB1: long 0xBFD55555,0x55555555
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) ATANC5: long 0xBFB70BF3,0x98539E6A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) ATANC4: long 0x3FBC7187,0x962D1D7D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) ATANC3: long 0xBFC24924,0x827107B8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) ATANC2: long 0x3FC99999,0x9996263E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) ATANC1: long 0xBFD55555,0x55555536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) PPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) NPIBY2: long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) PTINY: long 0x00010000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) NTINY: long 0x80010000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) ATANTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) long 0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) long 0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) long 0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) long 0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) long 0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) long 0x3FFB0000,0xAB98E943,0x62765619,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) long 0x3FFB0000,0xB389E502,0xF9C59862,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) long 0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) long 0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) long 0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) long 0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) long 0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) long 0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) long 0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) long 0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) long 0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) long 0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) long 0x3FFC0000,0x8B232A08,0x304282D8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) long 0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) long 0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) long 0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) long 0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) long 0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) long 0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) long 0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) long 0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) long 0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) long 0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) long 0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) long 0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) long 0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) long 0x3FFC0000,0xF7170A28,0xECC06666,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) long 0x3FFD0000,0x812FD288,0x332DAD32,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) long 0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) long 0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) long 0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) long 0x3FFD0000,0x9EB68949,0x3889A227,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) long 0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) long 0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) long 0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) long 0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) long 0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) long 0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) long 0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) long 0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) long 0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) long 0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) long 0x3FFD0000,0xEA2D764F,0x64315989,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) long 0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) long 0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) long 0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) long 0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) long 0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) long 0x3FFE0000,0x97731420,0x365E538C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) long 0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) long 0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) long 0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) long 0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) long 0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) long 0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) long 0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) long 0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) long 0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) long 0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) long 0x3FFE0000,0xCD000549,0xADEC7159,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) long 0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) long 0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) long 0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) long 0x3FFE0000,0xE8771129,0xC4353259,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) long 0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) long 0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) long 0x3FFE0000,0xF919039D,0x758B8D41,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) long 0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) long 0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) long 0x3FFF0000,0x83889E35,0x49D108E1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) long 0x3FFF0000,0x859CFA76,0x511D724B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) long 0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) long 0x3FFF0000,0x89732FD1,0x9557641B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) long 0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) long 0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) long 0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) long 0x3FFF0000,0x922DA7D7,0x91888487,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) long 0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) long 0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) long 0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) long 0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) long 0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) long 0x3FFF0000,0x9F100575,0x006CC571,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) long 0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) long 0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) long 0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) long 0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) long 0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) long 0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) long 0x3FFF0000,0xA83A5153,0x0956168F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) long 0x3FFF0000,0xA93A2007,0x7539546E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) long 0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198) long 0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) long 0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) long 0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) long 0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) long 0x3FFF0000,0xB1846515,0x0F71496A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) long 0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) long 0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) long 0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) long 0x3FFF0000,0xB525529D,0x562246BD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) long 0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) long 0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) long 0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) long 0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) long 0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) long 0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) long 0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) long 0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) long 0x3FFF0000,0xBB471285,0x7637E17D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) long 0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) long 0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) long 0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) long 0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) long 0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) long 0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) long 0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) long 0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) long 0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) long 0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) long 0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) long 0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) long 0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) set XFRACLO,X+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) set ATANF,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) set ATANFHI,ATANF+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) set ATANFLO,ATANF+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) global satan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) satan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) cmp.l %d1,&0x3FFB8000 # |X| >= 1/16?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) bge.b ATANOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) bra.w ATANSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) ATANOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) cmp.l %d1,&0x4002FFFF # |X| < 16 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) ble.b ATANMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) bra.w ATANBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) #--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 6261) #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) #--WILL INVOLVE A VERY LONG POLYNOMIAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) #--WE CHOSE F TO BE +-2^K * 1.BBBB1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) ATANMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) and.l &0xF8000000,XFRAC(%a6) # FIRST 5 BITS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) or.l &0x04000000,XFRAC(%a6) # SET 6-TH BIT TO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) mov.l &0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) fmov.x %fp0,%fp1 # FP1 IS X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) fmul.x X(%a6),%fp1 # FP1 IS X*F, NOTE THAT X*F > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) fsub.x X(%a6),%fp0 # FP0 IS X-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) fadd.s &0x3F800000,%fp1 # FP1 IS 1 + X*F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) fdiv.x %fp1,%fp0 # FP0 IS U = (X-F)/(1+X*F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) #--CREATE ATAN(F) AND STORE IT IN ATANF, AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) #--SAVE REGISTERS FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) mov.l %d2,-(%sp) # SAVE d2 TEMPORARILY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) mov.l %d1,%d2 # THE EXP AND 16 BITS OF X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) and.l &0x00007800,%d1 # 4 VARYING BITS OF F'S FRACTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) and.l &0x7FFF0000,%d2 # EXPONENT OF F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) sub.l &0x3FFB0000,%d2 # K+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) asr.l &1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) add.l %d2,%d1 # THE 7 BITS IDENTIFYING F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) asr.l &7,%d1 # INDEX INTO TBL OF ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) lea ATANTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) add.l %d1,%a1 # ADDRESS OF ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) mov.l (%a1)+,ATANF(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) mov.l (%a1)+,ATANFHI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) mov.l (%a1)+,ATANFLO(%a6) # ATANF IS NOW ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) mov.l X(%a6),%d1 # LOAD SIGN AND EXPO. AGAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) and.l &0x80000000,%d1 # SIGN(F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) or.l %d1,ATANF(%a6) # ATANF IS NOW SIGN(F)*ATAN(|F|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) mov.l (%sp)+,%d2 # RESTORE d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) #--THAT'S ALL I HAVE TO DO FOR NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) #--BUT ALAS, THE DIVIDE IS STILL CRANKING!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) #--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = A1/A3, A3 = A2/A3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) fmovm.x &0x04,-(%sp) # save fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) fmul.x %fp1,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) fmov.d ATANA3(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) fadd.x %fp1,%fp2 # A3+V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) fmul.x %fp1,%fp2 # V*(A3+V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) fmul.x %fp0,%fp1 # U*V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) fadd.d ATANA2(%pc),%fp2 # A2+V*(A3+V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) fmul.d ATANA1(%pc),%fp1 # A1*U*V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334) fmul.x %fp2,%fp1 # A1*U*V*(A2+V*(A3+V))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) fadd.x %fp1,%fp0 # ATAN(U), FP1 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) fmovm.x (%sp)+,&0x20 # restore fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) fadd.x ATANF(%a6),%fp0 # ATAN(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) ATANBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) bgt.w ATANBIG # I.E. |X| >= 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) ATANSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) #--|X| <= 1/16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) #--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 6353) #--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 6354) #--WHERE Y = X*X, AND Z = Y*Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) cmp.l %d1,&0x3FD78000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) blt.w ATANTINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) #--COMPUTE POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) fmul.x %fp0,%fp0 # FPO IS Y = X*X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) fmov.d ATANB6(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) fmov.d ATANB5(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) fmul.x %fp1,%fp2 # Z*B6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) fmul.x %fp1,%fp3 # Z*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) fadd.d ATANB4(%pc),%fp2 # B4+Z*B6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) fadd.d ATANB3(%pc),%fp3 # B3+Z*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) fmul.x %fp1,%fp2 # Z*(B4+Z*B6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377) fmul.x %fp3,%fp1 # Z*(B3+Z*B5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) fadd.d ATANB2(%pc),%fp2 # B2+Z*(B4+Z*B6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) fadd.d ATANB1(%pc),%fp1 # B1+Z*(B3+Z*B5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) fmul.x %fp0,%fp2 # Y*(B2+Z*(B4+Z*B6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) fmul.x X(%a6),%fp0 # X*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) fadd.x %fp2,%fp1 # [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) 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 6388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) fadd.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) ATANTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) #--|X| < 2^(-40), ATAN(X) = X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) fmov.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) ATANBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) #--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 - TINY). OTHERWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) #--RETURN SIGN(X)*PI/2 + ATAN(-1/X).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) cmp.l %d1,&0x40638000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) bgt.w ATANHUGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) #--APPROXIMATE ATAN(-1/X) BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) #--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 6412) #--THIS CAN BE RE-WRITTEN AS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) fmov.s &0xBF800000,%fp1 # LOAD -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) fdiv.x %fp0,%fp1 # FP1 IS -1/X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) #--DIVIDE IS STILL CRANKING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) fmov.x %fp1,%fp0 # FP0 IS X'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) fmul.x %fp0,%fp0 # FP0 IS Y = X'*X'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) fmov.x %fp1,X(%a6) # X IS REALLY X'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) fmov.d ATANC5(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) fmov.d ATANC4(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) fmul.x %fp1,%fp3 # Z*C5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) fmul.x %fp1,%fp2 # Z*B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) fadd.d ATANC3(%pc),%fp3 # C3+Z*C5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) fadd.d ATANC2(%pc),%fp2 # C2+Z*C4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) fmul.x %fp3,%fp1 # Z*(C3+Z*C5), FP3 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) fmul.x %fp0,%fp2 # Y*(C2+Z*C4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) fadd.d ATANC1(%pc),%fp1 # C1+Z*(C3+Z*C5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) fmul.x X(%a6),%fp0 # X'*Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) fadd.x %fp2,%fp1 # [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) fmul.x %fp1,%fp0 # X'*Y*([B1+Z*(B3+Z*B5)]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) # ... +[Y*(B2+Z*(B4+Z*B6))])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) fadd.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) tst.b (%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) bpl.b pos_big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) neg_big:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) fadd.x NPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) pos_big:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) fadd.x PPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) ATANHUGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) tst.b (%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) bpl.b pos_huge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) neg_huge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) fmov.x NPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472) fadd.x PTINY(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) pos_huge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) fmov.x PPIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478) fadd.x NTINY(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) global satand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) satand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) # sasin(): computes the inverse sine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) # sasind(): computes the inverse sine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) # fp0 = arcsin(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) # ASIN #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) # 1. If |X| >= 1, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) # 2. (|X| < 1) Calculate asin(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) # z := sqrt( [1-X][1+X] ) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) # asin(X) = atan( x / z ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) # 3. If |X| > 1, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) # 4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) global sasin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) sasin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) bge.b ASINBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) # This catch is added here for the '060 QSP. Originally, the call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) # satan() would handle this case by causing the exception which would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) # not be caught until gen_except(). Now, with the exceptions being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) # detected inside of satan(), the exception would have been handled there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) # instead of inside sasin() as expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) cmp.l %d1,&0x3FD78000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) blt.w ASINTINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) #--THIS IS THE USUAL CASE, |X| < 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) ASINMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) fsub.x %fp0,%fp1 # 1-X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) fmovm.x &0x4,-(%sp) # {fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) fmov.s &0x3F800000,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) fadd.x %fp0,%fp2 # 1+X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) fmul.x %fp2,%fp1 # (1+X)(1-X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) fmovm.x (%sp)+,&0x20 # {fp2}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) fsqrt.x %fp1 # SQRT([1-X][1+X])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) fdiv.x %fp1,%fp0 # X/SQRT([1-X][1+X])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) fmovm.x &0x01,-(%sp) # save X/SQRT(...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) lea (%sp),%a0 # pass ptr to X/SQRT(...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) bsr satan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) add.l &0xc,%sp # clear X/SQRT(...) from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) ASINBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) fabs.x %fp0 # |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) fcmp.s %fp0,&0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) fbgt t_operr # cause an operr exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) #--|X| = 1, ASIN(X) = +- PI/2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) ASINONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) fmov.x PIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) and.l &0x80000000,%d1 # SIGN BIT OF X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) or.l &0x3F800000,%d1 # +-1 IN SGL FORMAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) mov.l %d1,-(%sp) # push SIGN(X) IN SGL-FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) fmul.s (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) #--|X| < 2^(-40), ATAN(X) = X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) ASINTINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) fmov.l %d0,%fpcr # restore users rnd mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) fmov.x (%a0),%fp0 # last inst - possible exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) global sasind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) #--ASIN(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) sasind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) # sacos(): computes the inverse cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) # sacosd(): computes the inverse cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) # fp0 = arccos(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) # ACOS #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) # 1. If |X| >= 1, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) # 2. (|X| < 1) Calculate acos(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) # z := (1-X) / (1+X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) # acos(X) = 2 * atan( sqrt(z) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) # 3. If |X| > 1, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) # 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) global sacos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) sacos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) mov.l (%a0),%d1 # pack exp w/ upper 16 fraction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) bge.b ACOSBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) #--THIS IS THE USUAL CASE, |X| < 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) #--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) ACOSMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) fmov.s &0x3F800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) fadd.x %fp0,%fp1 # 1+X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) fneg.x %fp0 # -X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) fadd.s &0x3F800000,%fp0 # 1-X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) fdiv.x %fp1,%fp0 # (1-X)/(1+X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) fsqrt.x %fp0 # SQRT((1-X)/(1+X))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) mov.l %d0,-(%sp) # save original users fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) fmovm.x &0x01,-(%sp) # save SQRT(...) to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) lea (%sp),%a0 # pass ptr to sqrt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) bsr satan # ATAN(SQRT([1-X]/[1+X]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) add.l &0xc,%sp # clear SQRT(...) from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) fmov.l (%sp)+,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) fadd.x %fp0,%fp0 # 2 * ATAN( STUFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) ACOSBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) fabs.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) fcmp.s %fp0,&0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) fbgt t_operr # cause an operr exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) #--|X| = 1, ACOS(X) = 0 OR PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) tst.b (%a0) # is X positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) bpl.b ACOSP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) #--X = -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) #Returns PI and inexact exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) ACOSM1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) fmov.x PI(%pc),%fp0 # load PI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) fmov.l %d0,%fpcr # load round mode,prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) fadd.s &0x00800000,%fp0 # add a small value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) ACOSP1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) bra ld_pzero # answer is positive zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) global sacosd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) #--ACOS(X) = PI/2 FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) sacosd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) fmov.l %d0,%fpcr # load user's rnd mode/prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) fmov.x PIBY2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) # setox(): computes the exponential for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) # setoxd(): computes the exponential for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) # setoxm1(): computes the exponential minus 1 for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) # setoxm1d(): computes the exponential minus 1 for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692) # fp0 = exp(X) or exp(X)-1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) # The returned result is within 0.85 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) # ALGORITHM and IMPLEMENTATION **************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) # setoxd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) # ------ #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) # Step 1. Set ans := 1.0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) # Step 2. Return ans := ans + sign(X)*2^(-126). Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) # Notes: This will always generate one exception -- inexact. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) # setox #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) # ----- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) # Step 1. Filter out extreme cases of input argument. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) # 1.1 If |X| >= 2^(-65), go to Step 1.3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) # 1.2 Go to Step 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) # 1.3 If |X| < 16380 log(2), go to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) # 1.4 Go to Step 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) # To avoid the use of floating-point comparisons, a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720) # compact representation of |X| is used. This format is a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) # 32-bit integer, the upper (more significant) 16 bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) # are the sign and biased exponent field of |X|; the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) # lower 16 bits are the 16 most significant fraction #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) # (including the explicit bit) bits of |X|. Consequently, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) # the comparisons in Steps 1.1 and 1.3 can be performed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) # by integer comparison. Note also that the constant #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) # 16380 log(2) used in Step 1.3 is also in the compact #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) # form. Thus taking the branch to Step 2 guarantees #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) # |X| < 16380 log(2). There is no harm to have a small #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) # number of cases where |X| is less than, but close to, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) # 16380 log(2) and the branch to Step 9 is taken. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) # 2.1 Set AdjFlag := 0 (indicates the branch 1.3 -> 2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) # was taken) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) # 2.2 N := round-to-nearest-integer( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) # 2.3 Calculate J = N mod 64; so J = 0,1,2,..., #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738) # or 63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) # 2.4 Calculate M = (N - J)/64; so N = 64M + J. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) # 2.5 Calculate the address of the stored value of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) # 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) # 2.6 Create the value Scale = 2^M. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) # Notes: The calculation in 2.2 is really performed by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) # Z := X * constant #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) # N := round-to-nearest-integer(Z) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) # where #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) # constant := single-precision( 64/log 2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) # Using a single-precision constant avoids memory #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) # access. Another effect of using a single-precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) # "constant" is that the calculated value Z is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) # Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) # This error has to be considered later in Steps 3 and 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) # Step 3. Calculate X - N*log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) # 3.1 R := X + N*L1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) # where L1 := single-precision(-log2/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) # 3.2 R := R + N*L2, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) # L2 := extended-precision(-log2/64 - L1).#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) # Notes: a) The way L1 and L2 are chosen ensures L1+L2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) # approximate the value -log2/64 to 88 bits of accuracy. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) # b) N*L1 is exact because N is no longer than 22 bits #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) # and L1 is no longer than 24 bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) # c) The calculation X+N*L1 is also exact due to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) # cancellation. Thus, R is practically X+N(L1+L2) to full #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) # 64 bits. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) # d) It is important to estimate how large can |R| be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) # after Step 3.2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) # N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) # X*64/log2 (1+eps) = N + f, |f| <= 0.5 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) # X*64/log2 - N = f - eps*X 64/log2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) # X - N*log2/64 = f*log2/64 - eps*X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) # Now |X| <= 16446 log2, thus #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) # |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) # <= 0.57 log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) # This bound will be used in Step 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) # Step 4. Approximate exp(R)-1 by a polynomial #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) # p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) # Notes: a) In order to reduce memory access, the coefficients #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) # are made as "short" as possible: A1 (which is 1/2), A4 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) # and A5 are single precision; A2 and A3 are double #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789) # precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) # b) Even with the restrictions above, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) # |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) # Note that 0.0062 is slightly bigger than 0.57 log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) # c) To fully utilize the pipeline, p is separated into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) # two independent pieces of roughly equal complexities #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) # p = [ R + R*S*(A2 + S*A4) ] + #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) # [ S*(A1 + S*(A3 + S*A5)) ] #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) # where S = R*R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) # Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) # ans := T + ( T*p + t) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) # where T and t are the stored values for 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) # Notes: 2^(J/64) is stored as T and t where T+t approximates #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) # 2^(J/64) to roughly 85 bits; T is in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) # and t is in single precision. Note also that T is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) # rounded to 62 bits so that the last two bits of T are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) # zero. The reason for such a special form is that T-1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) # T-2, and T-8 will all be exact --- a property that will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) # give much more accurate computation of the function #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) # EXPM1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) # Step 6. Reconstruction of exp(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) # exp(X) = 2^M * 2^(J/64) * exp(R). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) # 6.1 If AdjFlag = 0, go to 6.3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) # 6.2 ans := ans * AdjScale #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) # 6.3 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) # 6.4 Return ans := ans * Scale. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) # Notes: If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) # |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) # neither overflow nor underflow. If AdjFlag = 1, that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) # means that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) # X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) # Hence, exp(X) may overflow or underflow or neither. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) # When that is the case, AdjScale = 2^(M1) where M1 is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) # approximately M. Thus 6.2 will never cause #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) # over/underflow. Possible exception in 6.4 is overflow #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) # or underflow. The inexact exception is not generated in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) # 6.4. Although one can argue that the inexact flag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) # should always be raised, to simulate that exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) # cost to much than the flag is worth in practical uses. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) # Step 7. Return 1 + X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) # 7.1 ans := X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) # 7.2 Restore user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) # 7.3 Return ans := 1 + ans. Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) # Notes: For non-zero X, the inexact exception will always be #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) # raised by 7.3. That is the only exception raised by 7.3.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) # Note also that we use the FMOVEM instruction to move X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) # in Step 7.1 to avoid unnecessary trapping. (Although #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) # the FMOVEM may not seem relevant since X is normalized, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) # the precaution will be useful in the library version of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) # this code where the separate entry for denormalized #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) # inputs will be done away with.) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) # Step 8. Handle exp(X) where |X| >= 16380log2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) # 8.1 If |X| > 16480 log2, go to Step 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) # (mimic 2.2 - 2.6) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) # 8.2 N := round-to-integer( X * 64/log2 ) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) # 8.3 Calculate J = N mod 64, J = 0,1,...,63 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) # 8.4 K := (N-J)/64, M1 := truncate(K/2), M = K-M1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) # AdjFlag := 1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) # 8.5 Calculate the address of the stored value #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) # 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) # 8.6 Create the values Scale = 2^M, AdjScale = 2^M1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) # 8.7 Go to Step 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) # Notes: Refer to notes for 2.2 - 2.6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) # Step 9. Handle exp(X), |X| > 16480 log2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) # 9.1 If X < 0, go to 9.3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) # 9.2 ans := Huge, go to 9.4 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) # 9.3 ans := Tiny. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) # 9.4 Restore user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) # 9.5 Return ans := ans * ans. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) # Notes: Exp(X) will surely overflow or underflow, depending on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) # X's sign. "Huge" and "Tiny" are respectively large/tiny #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) # extended-precision numbers whose square over/underflow #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) # with an inexact result. Thus, 9.5 always raises the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) # inexact together with either overflow or underflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) # setoxm1d #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) # -------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) # Step 1. Set ans := 0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) # Step 2. Return ans := X + ans. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) # Notes: This will return X with the appropriate rounding #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) # precision prescribed by the user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) # setoxm1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) # ------- #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) # Step 1. Check |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) # 1.1 If |X| >= 1/4, go to Step 1.3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) # 1.2 Go to Step 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) # 1.3 If |X| < 70 log(2), go to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) # 1.4 Go to Step 10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) # However, it is conceivable |X| can be small very often #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) # because EXPM1 is intended to evaluate exp(X)-1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) # accurately when |X| is small. For further details on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) # the comparisons, see the notes on Step 1 of setox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) # 2.1 N := round-to-nearest-integer( X * 64/log2 ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) # 2.2 Calculate J = N mod 64; so J = 0,1,2,..., #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) # or 63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) # 2.3 Calculate M = (N - J)/64; so N = 64M + J. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) # 2.4 Calculate the address of the stored value of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) # 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) # 2.5 Create the values Sc = 2^M and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) # OnebySc := -2^(-M). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) # Notes: See the notes on Step 2 of setox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) # Step 3. Calculate X - N*log2/64. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) # 3.1 R := X + N*L1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) # where L1 := single-precision(-log2/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) # 3.2 R := R + N*L2, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) # L2 := extended-precision(-log2/64 - L1).#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) # Notes: Applying the analysis of Step 3 of setox in this case #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) # shows that |R| <= 0.0055 (note that |X| <= 70 log2 in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) # this case). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) # Step 4. Approximate exp(R)-1 by a polynomial #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) # p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6))))) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) # Notes: a) In order to reduce memory access, the coefficients #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) # are made as "short" as possible: A1 (which is 1/2), A5 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) # and A6 are single precision; A2, A3 and A4 are double #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) # precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) # b) Even with the restriction above, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) # |p - (exp(R)-1)| < |R| * 2^(-72.7) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) # for all |R| <= 0.0055. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) # c) To fully utilize the pipeline, p is separated into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) # two independent pieces of roughly equal complexity #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) # p = [ R*S*(A2 + S*(A4 + S*A6)) ] + #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) # [ R + S*(A1 + S*(A3 + S*A5)) ] #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) # where S = R*R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) # Step 5. Compute 2^(J/64)*p by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) # p := T*p #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) # where T and t are the stored values for 2^(J/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) # Notes: 2^(J/64) is stored as T and t where T+t approximates #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) # 2^(J/64) to roughly 85 bits; T is in extended precision #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) # and t is in single precision. Note also that T is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) # rounded to 62 bits so that the last two bits of T are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) # zero. The reason for such a special form is that T-1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) # T-2, and T-8 will all be exact --- a property that will #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) # be exploited in Step 6 below. The total relative error #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) # in p is no bigger than 2^(-67.7) compared to the final #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) # result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) # Step 6. Reconstruction of exp(X)-1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) # exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) # 6.1 If M <= 63, go to Step 6.3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) # 6.2 ans := T + (p + (t + OnebySc)). Go to 6.6 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) # 6.3 If M >= -3, go to 6.5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) # 6.4 ans := (T + (p + t)) + OnebySc. Go to 6.6 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) # 6.5 ans := (T + OnebySc) + (p + t). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) # 6.6 Restore user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) # 6.7 Return ans := Sc * ans. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) # Notes: The various arrangements of the expressions give #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) # accurate evaluations. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) # Step 7. exp(X)-1 for |X| < 1/4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) # 7.1 If |X| >= 2^(-65), go to Step 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) # 7.2 Go to Step 8. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) # Step 8. Calculate exp(X)-1, |X| < 2^(-65). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) # 8.1 If |X| < 2^(-16312), goto 8.3 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) # 8.2 Restore FPCR; return ans := X - 2^(-16382). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) # 8.3 X := X * 2^(140). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) # 8.4 Restore FPCR; ans := ans - 2^(-16382). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) # Return ans := ans*2^(140). Exit #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) # Notes: The idea is to return "X - tiny" under the user #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) # precision and rounding modes. To avoid unnecessary #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) # inefficiency, we stay away from denormalized numbers #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) # the best we can. For |X| >= 2^(-16312), the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) # straightforward 8.2 generates the inexact exception as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) # the case warrants. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) # Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971) # p = X + X*X*(B1 + X*(B2 + ... + X*B12)) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) # Notes: a) In order to reduce memory access, the coefficients #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) # are made as "short" as possible: B1 (which is 1/2), B9 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) # to B12 are single precision; B3 to B8 are double #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) # precision; and B2 is double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) # b) Even with the restriction above, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) # |p - (exp(X)-1)| < |X| 2^(-70.6) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) # for all |X| <= 0.251. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) # Note that 0.251 is slightly bigger than 1/4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) # c) To fully preserve accuracy, the polynomial is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) # computed as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) # X + ( S*B1 + Q ) where S = X*X and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) # Q = X*S*(B2 + X*(B3 + ... + X*B12)) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) # d) To fully utilize the pipeline, Q is separated into #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) # two independent pieces of roughly equal complexity #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) # Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] + #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) # [ S*S*(B3 + S*(B5 + ... + S*B11)) ] #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) # Step 10. Calculate exp(X)-1 for |X| >= 70 log 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) # 10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) # practical purposes. Therefore, go to Step 1 of setox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992) # 10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) # purposes. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) # ans := -1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) # Restore user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) # Return ans := ans + 2^(-126). Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) # Notes: 10.2 will always create an inexact and return -1 + tiny #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) # in the user rounding precision and mode. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) L2: long 0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) EEXPA3: long 0x3FA55555,0x55554CC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) EEXPA2: long 0x3FC55555,0x55554A54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) EM1A4: long 0x3F811111,0x11174385
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) EM1A3: long 0x3FA55555,0x55554F5A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) EM1A2: long 0x3FC55555,0x55555555,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) EM1B8: long 0x3EC71DE3,0xA5774682
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) EM1B7: long 0x3EFA01A0,0x19D7CB68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) EM1B6: long 0x3F2A01A0,0x1A019DF3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) EM1B5: long 0x3F56C16C,0x16C170E2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) EM1B4: long 0x3F811111,0x11111111
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) EM1B3: long 0x3FA55555,0x55555555
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) EM1B2: long 0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) long 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) TWO140: long 0x48B00000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) TWON140:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) long 0x37300000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) EEXPTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) long 0x3FFF0000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) long 0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) long 0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) long 0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) long 0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) long 0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) long 0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) long 0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038) long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) long 0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) long 0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) long 0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) long 0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) long 0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) long 0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) long 0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) long 0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) long 0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) long 0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) long 0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) long 0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) long 0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) long 0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) long 0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) long 0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) long 0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) long 0x3FFF0000,0xB311C412,0xA9112488,0x201F678A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) long 0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062) long 0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) long 0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) long 0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) long 0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) long 0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) long 0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) long 0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) long 0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) long 0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) long 0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) long 0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) long 0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) long 0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) long 0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) long 0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) long 0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) long 0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) long 0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) long 0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) long 0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) long 0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) long 0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) long 0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) long 0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) long 0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) long 0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) set ADJFLAG,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) set SCALE,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) set ADJSCALE,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) set SC,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) set ONEBYSC,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) global setox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) setox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) #--entry point for EXP(X), here X is finite, non-zero, and not NaN's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) #--Step 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) mov.l (%a0),%d1 # load part of input X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) and.l &0x7FFF0000,%d1 # biased expo. of X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107) cmp.l %d1,&0x3FBE0000 # 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) bge.b EXPC1 # normal case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) bra EXPSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) EXPC1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) #--The case |X| >= 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) mov.w 4(%a0),%d1 # expo. and partial sig. of |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) cmp.l %d1,&0x400CB167 # 16380 log2 trunc. 16 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) blt.b EXPMAIN # normal case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) bra EEXPBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) EXPMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) #--Step 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120) #--This is the normal branch: 2^(-65) <= |X| < 16380 log2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) fmov.x (%a0),%fp0 # load input from (a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124) fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) mov.l &0,ADJFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) fmov.l %fp0,%d1 # N = int( X * 64/log2 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128) lea EEXPTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) fmov.l %d1,%fp0 # convert to floating-format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131) mov.l %d1,L_SCR1(%a6) # save N temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) and.l &0x3F,%d1 # D0 is J = N mod 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133) lsl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134) add.l %d1,%a1 # address of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) mov.l L_SCR1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) asr.l &6,%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) add.w &0x3FFF,%d1 # biased expo. of 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138) mov.w L2(%pc),L_SCR1(%a6) # prefetch L2, no need in CB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140) EXPCONT1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) #--Step 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) fadd.x %fp1,%fp0 # X + N*L1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) fadd.x %fp2,%fp0 # fp0 is R, reduced arg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150) #--Step 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151) #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153) #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) fmul.x %fp1,%fp1 # fp1 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) fmov.s &0x3AB60B70,%fp2 # fp2 IS A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) fmul.x %fp1,%fp2 # fp2 IS S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162) fmov.x %fp1,%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) fmul.s &0x3C088895,%fp3 # fp3 IS S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) fadd.d EEXPA3(%pc),%fp2 # fp2 IS A3+S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) fadd.d EEXPA2(%pc),%fp3 # fp3 IS A2+S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) fmul.x %fp1,%fp2 # fp2 IS S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) mov.w %d1,SCALE(%a6) # SCALE is 2^(M) in extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) mov.l &0x80000000,SCALE+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) clr.l SCALE+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) fmul.x %fp1,%fp3 # fp3 IS S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175) fadd.s &0x3F000000,%fp2 # fp2 IS A1+S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) fmul.x %fp0,%fp3 # fp3 IS R*S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) fmul.x %fp1,%fp2 # fp2 IS S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) fadd.x %fp3,%fp0 # fp0 IS R+R*S*(A2+S*A4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) fmov.x (%a1)+,%fp1 # fp1 is lead. pt. of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) fadd.x %fp2,%fp0 # fp0 is EXP(R) - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) #--Step 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185) #--final reconstruction process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) fmul.x %fp1,%fp0 # 2^(J/64)*(Exp(R)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189) fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) fadd.s (%a1),%fp0 # accurate 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192) fadd.x %fp1,%fp0 # 2^(J/64) + 2^(J/64)*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) mov.l ADJFLAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195) #--Step 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) tst.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) beq.b NORMAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) ADJUST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199) fmul.x ADJSCALE(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) fmov.l %d0,%fpcr # restore user FPCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) fmul.x SCALE(%a6),%fp0 # multiply 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) EXPSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) #--Step 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) fmovm.x (%a0),&0x80 # load X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) fadd.s &0x3F800000,%fp0 # 1+X in user mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213) EEXPBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214) #--Step 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) cmp.l %d1,&0x400CB27C # 16480 log2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216) bgt.b EXP2BIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) #--Steps 8.2 -- 8.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218) fmov.x (%a0),%fp0 # load input from (a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) mov.l &1,ADJFLAG(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) fmov.l %fp0,%d1 # N = int( X * 64/log2 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) lea EEXPTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226) fmov.l %d1,%fp0 # convert to floating-format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) mov.l %d1,L_SCR1(%a6) # save N temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228) and.l &0x3F,%d1 # D0 is J = N mod 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) lsl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) add.l %d1,%a1 # address of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) mov.l L_SCR1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) asr.l &6,%d1 # D0 is K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) mov.l %d1,L_SCR1(%a6) # save K temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) asr.l &1,%d1 # D0 is M1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) sub.l %d1,L_SCR1(%a6) # a1 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236) add.w &0x3FFF,%d1 # biased expo. of 2^(M1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) mov.w %d1,ADJSCALE(%a6) # ADJSCALE := 2^(M1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) mov.l &0x80000000,ADJSCALE+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) clr.l ADJSCALE+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) mov.l L_SCR1(%a6),%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) add.w &0x3FFF,%d1 # biased expo. of 2^(M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) bra.w EXPCONT1 # go back to Step 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244) EXP2BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) #--Step 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246) tst.b (%a0) # is X positive or negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247) bmi t_unfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) bra t_ovfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250) global setoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251) setoxd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) #--entry point for EXP(X), X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253) mov.l (%a0),-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) andi.l &0x80000000,(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255) ori.l &0x00800000,(%sp) # sign(X)*2^(-126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) fmov.s &0x3F800000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) fadd.s (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) global setoxm1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264) setoxm1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265) #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) #--Step 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268) #--Step 1.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) mov.l (%a0),%d1 # load part of input X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270) and.l &0x7FFF0000,%d1 # biased expo. of X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271) cmp.l %d1,&0x3FFD0000 # 1/4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) bge.b EM1CON1 # |X| >= 1/4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273) bra EM1SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) EM1CON1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276) #--Step 1.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277) #--The case |X| >= 1/4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278) mov.w 4(%a0),%d1 # expo. and partial sig. of |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) cmp.l %d1,&0x4004C215 # 70log2 rounded up to 16 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280) ble.b EM1MAIN # 1/4 <= |X| <= 70log2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) bra EM1BIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283) EM1MAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) #--Step 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285) #--This is the case: 1/4 <= |X| <= 70 log2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286) fmov.x (%a0),%fp0 # load input from (a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289) fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291) fmov.l %fp0,%d1 # N = int( X * 64/log2 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) lea EEXPTBL(%pc),%a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293) fmov.l %d1,%fp0 # convert to floating-format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) mov.l %d1,L_SCR1(%a6) # save N temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296) and.l &0x3F,%d1 # D0 is J = N mod 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297) lsl.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) add.l %d1,%a1 # address of 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299) mov.l L_SCR1(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300) asr.l &6,%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301) mov.l %d1,L_SCR1(%a6) # save a copy of M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303) #--Step 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) #--a0 points to 2^(J/64), D0 and a1 both contain M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) fadd.x %fp1,%fp0 # X + N*L1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310) fadd.x %fp2,%fp0 # fp0 is R, reduced arg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311) add.w &0x3FFF,%d1 # D0 is biased expo. of 2^M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) #--Step 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315) #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6)))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320) fmul.x %fp1,%fp1 # fp1 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322) fmov.s &0x3950097B,%fp2 # fp2 IS a6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324) fmul.x %fp1,%fp2 # fp2 IS S*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325) fmov.x %fp1,%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) fmul.s &0x3AB60B6A,%fp3 # fp3 IS S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328) fadd.d EM1A4(%pc),%fp2 # fp2 IS A4+S*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329) fadd.d EM1A3(%pc),%fp3 # fp3 IS A3+S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330) mov.w %d1,SC(%a6) # SC is 2^(M) in extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) mov.l &0x80000000,SC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) clr.l SC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) fmul.x %fp1,%fp2 # fp2 IS S*(A4+S*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335) mov.l L_SCR1(%a6),%d1 # D0 is M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336) neg.w %d1 # D0 is -M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) fmul.x %fp1,%fp3 # fp3 IS S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) add.w &0x3FFF,%d1 # biased expo. of 2^(-M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) fadd.d EM1A2(%pc),%fp2 # fp2 IS A2+S*(A4+S*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340) fadd.s &0x3F000000,%fp3 # fp3 IS A1+S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) fmul.x %fp1,%fp2 # fp2 IS S*(A2+S*(A4+S*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343) or.w &0x8000,%d1 # signed/expo. of -2^(-M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344) mov.w %d1,ONEBYSC(%a6) # OnebySc is -2^(-M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) mov.l &0x80000000,ONEBYSC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) clr.l ONEBYSC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347) fmul.x %fp3,%fp1 # fp1 IS S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349) fmul.x %fp0,%fp2 # fp2 IS R*S*(A2+S*(A4+S*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) fadd.x %fp1,%fp0 # fp0 IS R+S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352) fadd.x %fp2,%fp0 # fp0 IS EXP(R)-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354) fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356) #--Step 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357) #--Compute 2^(J/64)*p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359) fmul.x (%a1),%fp0 # 2^(J/64)*(Exp(R)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) #--Step 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362) #--Step 6.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363) mov.l L_SCR1(%a6),%d1 # retrieve M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364) cmp.l %d1,&63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) ble.b MLE63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366) #--Step 6.2 M >= 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) fmov.s 12(%a1),%fp1 # fp1 is t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368) fadd.x ONEBYSC(%a6),%fp1 # fp1 is t+OnebySc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369) fadd.x %fp1,%fp0 # p+(t+OnebySc), fp1 released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) fadd.x (%a1),%fp0 # T+(p+(t+OnebySc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371) bra EM1SCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372) MLE63:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) #--Step 6.3 M <= 63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) cmp.l %d1,&-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) bge.b MGEN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376) MLTN3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377) #--Step 6.4 M <= -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378) fadd.s 12(%a1),%fp0 # p+t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) fadd.x (%a1),%fp0 # T+(p+t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380) fadd.x ONEBYSC(%a6),%fp0 # OnebySc + (T+(p+t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381) bra EM1SCALE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) MGEN3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383) #--Step 6.5 -3 <= M <= 63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384) fmov.x (%a1)+,%fp1 # fp1 is T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) fadd.s (%a1),%fp0 # fp0 is p+t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386) fadd.x ONEBYSC(%a6),%fp1 # fp1 is T+OnebySc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387) fadd.x %fp1,%fp0 # (T+OnebySc)+(p+t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389) EM1SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390) #--Step 6.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) fmul.x SC(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395) EM1SM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396) #--Step 7 |X| < 1/4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) cmp.l %d1,&0x3FBE0000 # 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398) bge.b EM1POLY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400) EM1TINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) #--Step 8 |X| < 2^(-65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402) cmp.l %d1,&0x00330000 # 2^(-16312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403) blt.b EM12TINY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) #--Step 8.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) mov.l &0x80010000,SC(%a6) # SC is -2^(-16382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406) mov.l &0x80000000,SC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) clr.l SC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408) fmov.x (%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) mov.b &FADD_OP,%d1 # last inst is ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411) fadd.x SC(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414) EM12TINY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) #--Step 8.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416) fmov.x (%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417) fmul.d TWO140(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418) mov.l &0x80010000,SC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) mov.l &0x80000000,SC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420) clr.l SC+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421) fadd.x SC(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424) fmul.d TWON140(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427) EM1POLY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428) #--Step 9 exp(X)-1 by a simple polynomial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429) fmov.x (%a0),%fp0 # fp0 is X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) fmul.x %fp0,%fp0 # fp0 is S := X*X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) fmov.s &0x2F30CAA8,%fp1 # fp1 is B12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433) fmul.x %fp0,%fp1 # fp1 is S*B12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434) fmov.s &0x310F8290,%fp2 # fp2 is B11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435) fadd.s &0x32D73220,%fp1 # fp1 is B10+S*B12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437) fmul.x %fp0,%fp2 # fp2 is S*B11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438) fmul.x %fp0,%fp1 # fp1 is S*(B10 + ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440) fadd.s &0x3493F281,%fp2 # fp2 is B9+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441) fadd.d EM1B8(%pc),%fp1 # fp1 is B8+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) fmul.x %fp0,%fp2 # fp2 is S*(B9+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444) fmul.x %fp0,%fp1 # fp1 is S*(B8+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) fadd.d EM1B7(%pc),%fp2 # fp2 is B7+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447) fadd.d EM1B6(%pc),%fp1 # fp1 is B6+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449) fmul.x %fp0,%fp2 # fp2 is S*(B7+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) fmul.x %fp0,%fp1 # fp1 is S*(B6+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) fadd.d EM1B5(%pc),%fp2 # fp2 is B5+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453) fadd.d EM1B4(%pc),%fp1 # fp1 is B4+S*...
^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 S*(B5+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456) fmul.x %fp0,%fp1 # fp1 is S*(B4+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458) fadd.d EM1B3(%pc),%fp2 # fp2 is B3+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459) fadd.x EM1B2(%pc),%fp1 # fp1 is B2+S*...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461) fmul.x %fp0,%fp2 # fp2 is S*(B3+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) fmul.x %fp0,%fp1 # fp1 is S*(B2+...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464) fmul.x %fp0,%fp2 # fp2 is S*S*(B3+...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465) fmul.x (%a0),%fp1 # fp1 is X*S*(B2...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) fmul.s &0x3F000000,%fp0 # fp0 is S*B1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468) fadd.x %fp2,%fp1 # fp1 is Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470) fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472) fadd.x %fp1,%fp0 # fp0 is S*B1+Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475) fadd.x (%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) EM1BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479) #--Step 10 |X| > 70 log2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482) bgt.w EXPC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483) #--Step 10.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484) fmov.s &0xBF800000,%fp0 # fp0 is -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486) fadd.s &0x00800000,%fp0 # -1 + 2^(-126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489) global setoxm1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) setoxm1d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491) #--entry point for EXPM1(X), here X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) #--Step 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) # sgetexp(): returns the exponent portion of the input argument. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497) # The exponent bias is removed and the exponent value is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) # returned as an extended precision number in fp0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499) # sgetexpd(): handles denormalized numbers. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) # sgetman(): extracts the mantissa of the input argument. The #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502) # mantissa is converted to an extended precision number w/ #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503) # an exponent of $3fff and is returned in fp0. The range of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504) # the result is [1.0 - 2.0). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505) # sgetmand(): handles denormalized numbers. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) # fp0 = exponent(X) or mantissa(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515) global sgetexp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) sgetexp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) mov.w SRC_EX(%a0),%d0 # get the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) bclr &0xf,%d0 # clear the sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519) subi.w &0x3fff,%d0 # subtract off the bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520) fmov.w %d0,%fp0 # return exp in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) blt.b sgetexpn # it's negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524) sgetexpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) global sgetexpd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) sgetexpd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530) bsr.l norm # normalize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) neg.w %d0 # new exp = -(shft amt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7532) subi.w &0x3fff,%d0 # subtract off the bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7533) fmov.w %d0,%fp0 # return exp in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7534) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7535) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7537) global sgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7538) sgetman:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7539) mov.w SRC_EX(%a0),%d0 # get the exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7540) ori.w &0x7fff,%d0 # clear old exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7541) bclr &0xe,%d0 # make it the new exp +-3fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7543) # 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 7544) mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7545) mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7546) mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7547) fmov.x FP_SCR0(%a6),%fp0 # put new value back in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7548) bmi.b sgetmann # it's negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7549) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7551) sgetmann:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7552) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7553) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7555) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7556) # For denormalized numbers, shift the mantissa until the j-bit = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7557) # then load the exponent with +/1 $3fff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7558) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7559) global sgetmand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7560) sgetmand:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7561) bsr.l norm # normalize exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7562) bra.b sgetman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7564) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7565) # scosh(): computes the hyperbolic cosine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7566) # scoshd(): computes the hyperbolic cosine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7567) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7568) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7569) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7570) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7571) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7572) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7573) # fp0 = cosh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7574) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7575) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7576) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7577) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7578) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7579) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7580) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7581) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7582) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7583) # COSH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7584) # 1. If |X| > 16380 log2, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7585) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7586) # 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7587) # y = |X|, z = exp(Y), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7588) # cosh(X) = (1/2)*( z + 1/z ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7589) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7590) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7591) # 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7592) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7593) # 4. (16380 log2 < |X| <= 16480 log2) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7594) # cosh(X) = sign(X) * exp(|X|)/2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7595) # However, invoking exp(|X|) may cause premature #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7596) # overflow. Thus, we calculate sinh(X) as follows: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7597) # Y := |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7598) # Fact := 2**(16380) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7599) # Y' := Y - 16381 log2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7600) # cosh(X) := Fact * exp(Y'). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7601) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7602) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7603) # 5. (|X| > 16480 log2) sinh(X) must overflow. Return #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7604) # Huge*Huge to generate overflow and an infinity with #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7605) # the appropriate sign. Huge is the largest finite number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7606) # in extended format. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7607) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7608) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7610) TWO16380:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7611) long 0x7FFB0000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7613) global scosh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7614) scosh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7615) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7617) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7618) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7619) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7620) cmp.l %d1,&0x400CB167
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7621) bgt.b COSHBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7623) #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7624) #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7626) fabs.x %fp0 # |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7628) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7629) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7630) fmovm.x &0x01,-(%sp) # save |X| to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7631) lea (%sp),%a0 # pass ptr to |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7632) bsr setox # FP0 IS EXP(|X|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7633) add.l &0xc,%sp # erase |X| from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7634) fmul.s &0x3F000000,%fp0 # (1/2)EXP(|X|)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7635) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7637) fmov.s &0x3E800000,%fp1 # (1/4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7638) fdiv.x %fp0,%fp1 # 1/(2 EXP(|X|))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7640) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7641) mov.b &FADD_OP,%d1 # last inst is ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7642) fadd.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7643) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7645) COSHBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7646) cmp.l %d1,&0x400CB2B3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7647) bgt.b COSHHUGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7649) fabs.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7650) fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7651) fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7653) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7654) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7655) fmovm.x &0x01,-(%sp) # save fp0 to stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7656) lea (%sp),%a0 # pass ptr to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7657) bsr setox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7658) add.l &0xc,%sp # clear fp0 from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7659) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7661) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7662) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7663) fmul.x TWO16380(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7664) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7666) COSHHUGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7667) bra t_ovfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7669) global scoshd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7670) #--COSH(X) = 1 FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7671) scoshd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7672) fmov.s &0x3F800000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7674) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7675) fadd.s &0x00800000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7676) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7678) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7679) # ssinh(): computes the hyperbolic sine of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7680) # ssinhd(): computes the hyperbolic sine of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7681) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7682) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7683) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7684) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7685) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7686) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7687) # fp0 = sinh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7688) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7689) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7690) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7691) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7692) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7693) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7694) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7695) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7696) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7697) # SINH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7698) # 1. If |X| > 16380 log2, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7699) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7700) # 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7701) # y = |X|, sgn = sign(X), and z = expm1(Y), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7702) # sinh(X) = sgn*(1/2)*( z + z/(1+z) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7703) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7704) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7705) # 3. If |X| > 16480 log2, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7706) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7707) # 4. (16380 log2 < |X| <= 16480 log2) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7708) # sinh(X) = sign(X) * exp(|X|)/2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7709) # However, invoking exp(|X|) may cause premature overflow. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7710) # Thus, we calculate sinh(X) as follows: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7711) # Y := |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7712) # sgn := sign(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7713) # sgnFact := sgn * 2**(16380) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7714) # Y' := Y - 16381 log2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7715) # sinh(X) := sgnFact * exp(Y'). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7716) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7717) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7718) # 5. (|X| > 16480 log2) sinh(X) must overflow. Return #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7719) # sign(X)*Huge*Huge to generate overflow and an infinity with #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7720) # the appropriate sign. Huge is the largest finite number in #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7721) # extended format. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7722) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7723) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7725) global ssinh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7726) ssinh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7727) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7729) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7730) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7731) mov.l %d1,%a1 # save (compacted) operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7732) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7733) cmp.l %d1,&0x400CB167
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7734) bgt.b SINHBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7736) #--THIS IS THE USUAL CASE, |X| < 16380 LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7737) #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7739) fabs.x %fp0 # Y = |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7741) movm.l &0x8040,-(%sp) # {a1/d0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7742) fmovm.x &0x01,-(%sp) # save Y on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7743) lea (%sp),%a0 # pass ptr to Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7744) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7745) bsr setoxm1 # FP0 IS Z = EXPM1(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7746) add.l &0xc,%sp # clear Y from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7747) fmov.l &0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7748) movm.l (%sp)+,&0x0201 # {a1/d0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7750) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7751) fadd.s &0x3F800000,%fp1 # 1+Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7752) fmov.x %fp0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7753) fdiv.x %fp1,%fp0 # Z/(1+Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7754) mov.l %a1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7755) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7756) or.l &0x3F000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7757) fadd.x (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7758) mov.l %d1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7760) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7761) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7762) fmul.s (%sp)+,%fp0 # last fp inst - possible exceptions set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7763) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7765) SINHBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7766) cmp.l %d1,&0x400CB2B3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7767) bgt t_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7768) fabs.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7769) fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7770) mov.l &0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7771) mov.l &0x80000000,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7772) mov.l %a1,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7773) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7774) or.l &0x7FFB0000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7775) mov.l %d1,-(%sp) # EXTENDED FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7776) fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7778) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7779) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7780) fmovm.x &0x01,-(%sp) # save fp0 on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7781) lea (%sp),%a0 # pass ptr to fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7782) bsr setox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7783) add.l &0xc,%sp # clear fp0 from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7785) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7786) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7787) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7788) fmul.x (%sp)+,%fp0 # possible exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7789) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7791) global ssinhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7792) #--SINH(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7793) ssinhd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7794) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7796) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7797) # stanh(): computes the hyperbolic tangent of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7798) # stanhd(): computes the hyperbolic tangent of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7799) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7800) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7801) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7802) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7803) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7804) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7805) # fp0 = tanh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7806) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7807) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7808) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7809) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7810) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7811) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7812) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7813) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7814) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7815) # TANH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7816) # 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7817) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7818) # 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7819) # sgn := sign(X), y := 2|X|, z := expm1(Y), and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7820) # tanh(X) = sgn*( z/(2+z) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7821) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7822) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7823) # 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7824) # go to 7. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7825) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7826) # 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7827) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7828) # 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7829) # sgn := sign(X), y := 2|X|, z := exp(Y), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7830) # tanh(X) = sgn - [ sgn*2/(1+z) ]. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7831) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7832) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7833) # 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7834) # calculate Tanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7835) # sgn := sign(X), Tiny := 2**(-126), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7836) # tanh(X) := sgn - sgn*Tiny. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7837) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7838) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7839) # 7. (|X| < 2**(-40)). Tanh(X) = X. Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7840) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7841) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7843) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7844) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7846) set SGN,L_SCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7848) set V,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7850) global stanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7851) stanh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7852) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7854) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7855) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7856) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7857) mov.l %d1,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7858) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7859) cmp.l %d1, &0x3fd78000 # is |X| < 2^(-40)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7860) blt.w TANHBORS # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7861) cmp.l %d1, &0x3fffddce # is |X| > (5/2)LOG2?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7862) bgt.w TANHBORS # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7864) #--THIS IS THE USUAL CASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7865) #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7867) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7868) mov.l %d1,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7869) and.l &0x7FFF0000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7870) add.l &0x00010000,%d1 # EXPONENT OF 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7871) mov.l %d1,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7872) and.l &0x80000000,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7873) fmov.x X(%a6),%fp0 # FP0 IS Y = 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7875) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7876) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7877) fmovm.x &0x1,-(%sp) # save Y on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7878) lea (%sp),%a0 # pass ptr to Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7879) bsr setoxm1 # FP0 IS Z = EXPM1(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7880) add.l &0xc,%sp # clear Y from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7881) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7883) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7884) fadd.s &0x40000000,%fp1 # Z+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7885) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7886) fmov.x %fp1,V(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7887) eor.l %d1,V(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7889) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7890) fdiv.x V(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7891) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7893) TANHBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7894) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7895) blt.w TANHSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7897) cmp.l %d1,&0x40048AA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7898) bgt.w TANHHUGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7900) #-- (5/2) LOG2 < |X| < 50 LOG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7901) #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7902) #--TANH(X) = SGN - SGN*2/[EXP(Y)+1].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7904) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7905) mov.l %d1,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7906) and.l &0x7FFF0000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7907) add.l &0x00010000,%d1 # EXPO OF 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7908) mov.l %d1,X(%a6) # Y = 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7909) and.l &0x80000000,SGN(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7910) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7911) fmov.x X(%a6),%fp0 # Y = 2|X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7913) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7914) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7915) fmovm.x &0x01,-(%sp) # save Y on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7916) lea (%sp),%a0 # pass ptr to Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7917) bsr setox # FP0 IS EXP(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7918) add.l &0xc,%sp # clear Y from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7919) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7920) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7921) fadd.s &0x3F800000,%fp0 # EXP(Y)+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7923) eor.l &0xC0000000,%d1 # -SIGN(X)*2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7924) fmov.s %d1,%fp1 # -SIGN(X)*2 IN SGL FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7925) fdiv.x %fp0,%fp1 # -SIGN(X)2 / [EXP(Y)+1 ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7927) mov.l SGN(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7928) or.l &0x3F800000,%d1 # SGN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7929) fmov.s %d1,%fp0 # SGN IN SGL FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7931) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7932) mov.b &FADD_OP,%d1 # last inst is ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7933) fadd.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7934) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7936) TANHSM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7937) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7938) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7939) fmov.x X(%a6),%fp0 # last inst - possible exception set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7940) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7942) #---RETURN SGN(X) - SGN(X)EPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7943) TANHHUGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7944) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7945) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7946) or.l &0x3F800000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7947) fmov.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7948) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7949) eor.l &0x80800000,%d1 # -SIGN(X)*EPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7951) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7952) fadd.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7953) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7955) global stanhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7956) #--TANH(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7957) stanhd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7958) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7960) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7961) # slogn(): computes the natural logarithm of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7962) # slognd(): computes the natural logarithm of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7963) # slognp1(): computes the log(1+X) of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7964) # slognp1d(): computes the log(1+X) of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7965) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7966) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7967) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7968) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7969) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7970) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7971) # fp0 = log(X) or log(1+X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7972) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7973) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7974) # The returned result is within 2 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7975) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7976) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7977) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7978) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7979) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7980) # LOGN: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7981) # Step 1. If |X-1| < 1/16, approximate log(X) by an odd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7982) # polynomial in u, where u = 2(X-1)/(X+1). Otherwise, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7983) # move on to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7984) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7985) # 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 7986) # seven significant bits of Y plus 2**(-7), i.e. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7987) # F = 1.xxxxxx1 in base 2 where the six "x" match those #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7988) # of Y. Note that |Y-F| <= 2**(-7). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7989) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7990) # Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7991) # polynomial in u, log(1+u) = poly. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7992) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7993) # Step 4. Reconstruct #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7994) # log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7995) # by k*log(2) + (log(F) + poly). The values of log(F) are #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7996) # calculated beforehand and stored in the program. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7997) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7998) # lognp1: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7999) # Step 1: If |X| < 1/16, approximate log(1+X) by an odd #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8000) # polynomial in u where u = 2X/(2+X). Otherwise, move on #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8001) # to Step 2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8002) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8003) # 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 8004) # in Step 2 of the algorithm for LOGN and compute #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8005) # log(1+X) as k*log(2) + log(F) + poly where poly #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8006) # approximates log(1+u), u = (Y-F)/F. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8007) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8008) # Implementation Notes: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8009) # Note 1. There are 64 different possible values for F, thus 64 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8010) # log(F)'s need to be tabulated. Moreover, the values of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8011) # 1/F are also tabulated so that the division in (Y-F)/F #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8012) # can be performed by a multiplication. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8013) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8014) # Note 2. In Step 2 of lognp1, in order to preserved accuracy, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8015) # the value Y-F has to be calculated carefully when #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8016) # 1/2 <= X < 3/2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8017) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8018) # Note 3. To fully exploit the pipeline, polynomials are usually #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8019) # separated into two parts evaluated independently before #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8020) # being added up. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8021) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8022) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8023) LOGOF2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8024) long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8026) one:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8027) long 0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8028) zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8029) long 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8030) infty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8031) long 0x7F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8032) negone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8033) long 0xBF800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8035) LOGA6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8036) long 0x3FC2499A,0xB5E4040B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8037) LOGA5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8038) long 0xBFC555B5,0x848CB7DB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8040) LOGA4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8041) long 0x3FC99999,0x987D8730
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8042) LOGA3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8043) long 0xBFCFFFFF,0xFF6F7E97
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8045) LOGA2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8046) long 0x3FD55555,0x555555A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8047) LOGA1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8048) long 0xBFE00000,0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8050) LOGB5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8051) long 0x3F175496,0xADD7DAD6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8052) LOGB4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8053) long 0x3F3C71C2,0xFE80C7E0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8055) LOGB3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8056) long 0x3F624924,0x928BCCFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8057) LOGB2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8058) long 0x3F899999,0x999995EC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8060) LOGB1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8061) long 0x3FB55555,0x55555555
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8062) TWO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8063) long 0x40000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8065) LTHOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8066) long 0x3f990000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8068) LOGTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8069) long 0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8070) long 0x3FF70000,0xFF015358,0x833C47E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8071) long 0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8072) long 0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8073) long 0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8074) long 0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8075) long 0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8076) long 0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8077) long 0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8078) long 0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8079) long 0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8080) long 0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8081) long 0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8082) long 0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8083) long 0x3FFE0000,0xE525982A,0xF70C880E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8084) long 0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8085) long 0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8086) long 0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8087) long 0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8088) long 0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8089) long 0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8090) long 0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8091) long 0x3FFE0000,0xD901B203,0x6406C80E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8092) long 0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8093) long 0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8094) long 0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8095) long 0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8096) long 0x3FFC0000,0xC3FD0329,0x06488481,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8097) long 0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8098) long 0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8099) long 0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8100) long 0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8101) long 0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8102) long 0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8103) long 0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8104) long 0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8105) long 0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8106) long 0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8107) long 0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8108) long 0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8109) long 0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8110) long 0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8111) long 0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8112) long 0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8113) long 0x3FFE0000,0xBD691047,0x07661AA3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8114) long 0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8115) long 0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8116) long 0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8117) long 0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8118) long 0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8119) long 0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8120) long 0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8121) long 0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8122) long 0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8123) long 0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8124) long 0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8125) long 0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8126) long 0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8127) long 0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8128) long 0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8129) long 0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8130) long 0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8131) long 0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8132) long 0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8133) long 0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8134) long 0x3FFD0000,0xD2420487,0x2DD85160,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8135) long 0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8136) long 0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8137) long 0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8138) long 0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8139) long 0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8140) long 0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8141) long 0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8142) long 0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8143) long 0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8144) long 0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8145) long 0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8146) long 0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8147) long 0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8148) long 0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8149) long 0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8150) long 0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8151) long 0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8152) long 0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8153) long 0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8154) long 0x3FFE0000,0x825EFCED,0x49369330,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8155) long 0x3FFE0000,0x9868C809,0x868C8098,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8156) long 0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8157) long 0x3FFE0000,0x97012E02,0x5C04B809,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8158) long 0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8159) long 0x3FFE0000,0x95A02568,0x095A0257,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8160) long 0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8161) long 0x3FFE0000,0x94458094,0x45809446,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8162) long 0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8163) long 0x3FFE0000,0x92F11384,0x0497889C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8164) long 0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8165) long 0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8166) long 0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8167) long 0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8168) long 0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8169) long 0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8170) long 0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8171) long 0x3FFE0000,0x8DDA5202,0x37694809,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8172) long 0x3FFE0000,0x9723A1B7,0x20134203,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8173) long 0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8174) long 0x3FFE0000,0x995899C8,0x90EB8990,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8175) long 0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8176) long 0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8177) long 0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8178) long 0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8179) long 0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8180) long 0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8181) long 0x3FFE0000,0x87F78087,0xF78087F8,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8182) long 0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8183) long 0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8184) long 0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8185) long 0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8186) long 0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8187) long 0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8188) long 0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8189) long 0x3FFE0000,0x83993052,0x3FBE3368,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8190) long 0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8191) long 0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8192) long 0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8193) long 0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8194) long 0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8195) long 0x3FFE0000,0x80808080,0x80808081,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8196) long 0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8198) set ADJK,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8200) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8201) set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8202) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8204) set F,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8205) set FFRAC,F+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8207) set KLOG2,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8209) set SAVEU,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8211) global slogn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8212) #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8213) slogn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8214) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8215) mov.l &0x00000000,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8217) LOGBGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8218) #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8219) #--A FINITE, NON-ZERO, NORMALIZED NUMBER.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8221) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8222) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8224) mov.l (%a0),X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8225) mov.l 4(%a0),X+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8226) mov.l 8(%a0),X+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8228) cmp.l %d1,&0 # CHECK IF X IS NEGATIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8229) blt.w LOGNEG # LOG OF NEGATIVE ARGUMENT IS INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8230) # X IS POSITIVE, CHECK IF X IS NEAR 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8231) cmp.l %d1,&0x3ffef07d # IS X < 15/16?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8232) blt.b LOGMAIN # YES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8233) cmp.l %d1,&0x3fff8841 # IS X > 17/16?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8234) ble.w LOGNEAR1 # NO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8236) LOGMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8237) #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8239) #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8240) #--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 8241) #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8242) #-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8243) #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8244) #--LOG(1+U) CAN BE VERY EFFICIENT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8245) #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8246) #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8248) #--GET K, Y, F, AND ADDRESS OF 1/F.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8249) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8250) asr.l &8,%d1 # SHIFTED 16 BITS, BIASED EXPO. OF X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8251) sub.l &0x3FFF,%d1 # THIS IS K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8252) add.l ADJK(%a6),%d1 # ADJUST K, ORIGINAL INPUT MAY BE DENORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8253) lea LOGTBL(%pc),%a0 # BASE ADDRESS OF 1/F AND LOG(F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8254) fmov.l %d1,%fp1 # CONVERT K TO FLOATING-POINT FORMAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8256) #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8257) mov.l &0x3FFF0000,X(%a6) # X IS NOW Y, I.E. 2^(-K)*X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8258) mov.l XFRAC(%a6),FFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8259) and.l &0xFE000000,FFRAC(%a6) # FIRST 7 BITS OF Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8260) or.l &0x01000000,FFRAC(%a6) # GET F: ATTACH A 1 AT THE EIGHTH BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8261) mov.l FFRAC(%a6),%d1 # READY TO GET ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8262) and.l &0x7E000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8263) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8264) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8265) asr.l &4,%d1 # SHIFTED 20, D0 IS THE DISPLACEMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8266) add.l %d1,%a0 # A0 IS THE ADDRESS FOR 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8268) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8269) mov.l &0x3fff0000,F(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8270) clr.l F+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8271) fsub.x F(%a6),%fp0 # Y-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8272) fmovm.x &0xc,-(%sp) # SAVE FP2-3 WHILE FP0 IS NOT READY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8273) #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8274) #--REGISTERS SAVED: FPCR, FP1, FP2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8276) LP1CONT1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8277) #--AN RE-ENTRY POINT FOR LOGNP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8278) fmul.x (%a0),%fp0 # FP0 IS U = (Y-F)/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8279) fmul.x LOGOF2(%pc),%fp1 # GET K*LOG2 WHILE FP0 IS NOT READY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8280) fmov.x %fp0,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8281) fmul.x %fp2,%fp2 # FP2 IS V=U*U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8282) fmov.x %fp1,KLOG2(%a6) # PUT K*LOG2 IN MEMEORY, FREE FP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8284) #--LOG(1+U) IS APPROXIMATED BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8285) #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8286) #--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8288) fmov.x %fp2,%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8289) fmov.x %fp2,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8291) fmul.d LOGA6(%pc),%fp1 # V*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8292) fmul.d LOGA5(%pc),%fp2 # V*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8294) fadd.d LOGA4(%pc),%fp1 # A4+V*A6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8295) fadd.d LOGA3(%pc),%fp2 # A3+V*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8297) fmul.x %fp3,%fp1 # V*(A4+V*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8298) fmul.x %fp3,%fp2 # V*(A3+V*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8300) fadd.d LOGA2(%pc),%fp1 # A2+V*(A4+V*A6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8301) fadd.d LOGA1(%pc),%fp2 # A1+V*(A3+V*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8303) fmul.x %fp3,%fp1 # V*(A2+V*(A4+V*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8304) add.l &16,%a0 # ADDRESS OF LOG(F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8305) fmul.x %fp3,%fp2 # V*(A1+V*(A3+V*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8307) fmul.x %fp0,%fp1 # U*V*(A2+V*(A4+V*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8308) fadd.x %fp2,%fp0 # U+V*(A1+V*(A3+V*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8310) fadd.x (%a0),%fp1 # LOG(F)+U*V*(A2+V*(A4+V*A6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8311) fmovm.x (%sp)+,&0x30 # RESTORE FP2-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8312) fadd.x %fp1,%fp0 # FP0 IS LOG(F) + LOG(1+U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8314) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8315) fadd.x KLOG2(%a6),%fp0 # FINAL ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8316) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8319) LOGNEAR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8321) # if the input is exactly equal to one, then exit through ld_pzero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8322) # if these 2 lines weren't here, the correct answer would be returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8323) # but the INEX2 bit would be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8324) fcmp.b %fp0,&0x1 # is it equal to one?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8325) fbeq.l ld_pzero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8327) #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8328) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8329) fsub.s one(%pc),%fp1 # FP1 IS X-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8330) fadd.s one(%pc),%fp0 # FP0 IS X+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8331) fadd.x %fp1,%fp1 # FP1 IS 2(X-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8332) #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8333) #--IN U, U = 2(X-1)/(X+1) = FP1/FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8335) LP1CONT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8336) #--THIS IS AN RE-ENTRY POINT FOR LOGNP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8337) fdiv.x %fp0,%fp1 # FP1 IS U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8338) fmovm.x &0xc,-(%sp) # SAVE FP2-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8339) #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8340) #--LET V=U*U, W=V*V, CALCULATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8341) #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8342) #--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8343) fmov.x %fp1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8344) fmul.x %fp0,%fp0 # FP0 IS V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8345) fmov.x %fp1,SAVEU(%a6) # STORE U IN MEMORY, FREE FP1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8346) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8347) fmul.x %fp1,%fp1 # FP1 IS W
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8349) fmov.d LOGB5(%pc),%fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8350) fmov.d LOGB4(%pc),%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8352) fmul.x %fp1,%fp3 # W*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8353) fmul.x %fp1,%fp2 # W*B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8355) fadd.d LOGB3(%pc),%fp3 # B3+W*B5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8356) fadd.d LOGB2(%pc),%fp2 # B2+W*B4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8358) fmul.x %fp3,%fp1 # W*(B3+W*B5), FP3 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8360) fmul.x %fp0,%fp2 # V*(B2+W*B4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8362) fadd.d LOGB1(%pc),%fp1 # B1+W*(B3+W*B5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8363) fmul.x SAVEU(%a6),%fp0 # FP0 IS U*V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8365) fadd.x %fp2,%fp1 # B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8366) fmovm.x (%sp)+,&0x30 # FP2-3 RESTORED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8368) fmul.x %fp1,%fp0 # U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8370) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8371) fadd.x SAVEU(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8372) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8374) #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8375) LOGNEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8376) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8378) global slognd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8379) slognd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8380) #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8382) mov.l &-100,ADJK(%a6) # INPUT = 2^(ADJK) * FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8384) #----normalize the input value by left shifting k bits (k to be determined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8385) #----below), adjusting exponent and storing -k to ADJK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8386) #----the value TWOTO100 is no longer needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8387) #----Note that this code assumes the denormalized input is NON-ZERO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8389) movm.l &0x3f00,-(%sp) # save some registers {d2-d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8390) mov.l (%a0),%d3 # D3 is exponent of smallest norm. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8391) mov.l 4(%a0),%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8392) mov.l 8(%a0),%d5 # (D4,D5) is (Hi_X,Lo_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8393) clr.l %d2 # D2 used for holding K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8395) tst.l %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8396) bne.b Hi_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8398) Hi_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8399) mov.l %d5,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8400) clr.l %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8401) mov.l &32,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8402) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8403) bfffo %d4{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8404) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8405) add.l %d6,%d2 # (D3,D4,D5) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8407) mov.l %d3,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8408) mov.l %d4,XFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8409) mov.l %d5,XFRAC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8410) neg.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8411) mov.l %d2,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8412) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8413) movm.l (%sp)+,&0xfc # restore registers {d2-d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8414) lea X(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8415) bra.w LOGBGN # begin regular log(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8417) Hi_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8418) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8419) bfffo %d4{&0:&32},%d6 # find first 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8420) mov.l %d6,%d2 # get k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8421) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8422) mov.l %d5,%d7 # a copy of D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8423) lsl.l %d6,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8424) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8425) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8426) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8427) or.l %d7,%d4 # (D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8429) mov.l %d3,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8430) mov.l %d4,XFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8431) mov.l %d5,XFRAC+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8432) neg.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8433) mov.l %d2,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8434) fmov.x X(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8435) movm.l (%sp)+,&0xfc # restore registers {d2-d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8436) lea X(%a6),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8437) bra.w LOGBGN # begin regular log(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8439) global slognp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8440) #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8441) slognp1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8442) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8443) fabs.x %fp0 # test magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8444) fcmp.x %fp0,LTHOLD(%pc) # compare with min threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8445) fbgt.w LP1REAL # if greater, continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8446) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8447) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8448) fmov.x (%a0),%fp0 # return signed argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8449) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8451) LP1REAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8452) fmov.x (%a0),%fp0 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8453) mov.l &0x00000000,ADJK(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8454) fmov.x %fp0,%fp1 # FP1 IS INPUT Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8455) fadd.s one(%pc),%fp0 # X := ROUND(1+Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8456) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8457) mov.w XFRAC(%a6),XDCARE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8458) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8459) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8460) ble.w LP1NEG0 # LOG OF ZERO OR -VE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8461) cmp.l %d1,&0x3ffe8000 # IS BOUNDS [1/2,3/2]?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8462) blt.w LOGMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8463) cmp.l %d1,&0x3fffc000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8464) bgt.w LOGMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8465) #--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 8466) #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8467) #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8469) LP1NEAR1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8470) #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8471) cmp.l %d1,&0x3ffef07d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8472) blt.w LP1CARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8473) cmp.l %d1,&0x3fff8841
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8474) bgt.w LP1CARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8476) LP1ONE16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8477) #--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 8478) #--WHERE U = 2Z/(2+Z) = 2Z/(1+X).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8479) fadd.x %fp1,%fp1 # FP1 IS 2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8480) fadd.s one(%pc),%fp0 # FP0 IS 1+X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8481) #--U = FP1/FP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8482) bra.w LP1CONT2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8484) LP1CARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8485) #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8486) #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8487) #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8488) #--THERE ARE ONLY TWO CASES.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8489) #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8490) #--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1-F) + Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8491) #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8492) #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8494) mov.l XFRAC(%a6),FFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8495) and.l &0xFE000000,FFRAC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8496) or.l &0x01000000,FFRAC(%a6) # F OBTAINED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8497) cmp.l %d1,&0x3FFF8000 # SEE IF 1+Z > 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8498) bge.b KISZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8500) KISNEG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8501) fmov.s TWO(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8502) mov.l &0x3fff0000,F(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8503) clr.l F+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8504) fsub.x F(%a6),%fp0 # 2-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8505) mov.l FFRAC(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8506) and.l &0x7E000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8507) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8508) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8509) asr.l &4,%d1 # D0 CONTAINS DISPLACEMENT FOR 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8510) fadd.x %fp1,%fp1 # GET 2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8511) fmovm.x &0xc,-(%sp) # SAVE FP2 {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8512) fadd.x %fp1,%fp0 # FP0 IS Y-F = (2-F)+2Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8513) lea LOGTBL(%pc),%a0 # A0 IS ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8514) add.l %d1,%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8515) fmov.s negone(%pc),%fp1 # FP1 IS K = -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8516) bra.w LP1CONT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8518) KISZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8519) fmov.s one(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8520) mov.l &0x3fff0000,F(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8521) clr.l F+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8522) fsub.x F(%a6),%fp0 # 1-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8523) mov.l FFRAC(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8524) and.l &0x7E000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8525) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8526) asr.l &8,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8527) asr.l &4,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8528) fadd.x %fp1,%fp0 # FP0 IS Y-F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8529) fmovm.x &0xc,-(%sp) # FP2 SAVED {%fp2/%fp3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8530) lea LOGTBL(%pc),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8531) add.l %d1,%a0 # A0 IS ADDRESS OF 1/F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8532) fmov.s zero(%pc),%fp1 # FP1 IS K = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8533) bra.w LP1CONT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8535) LP1NEG0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8536) #--FPCR SAVED. D0 IS X IN COMPACT FORM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8537) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8538) blt.b LP1NEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8539) LP1ZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8540) fmov.s negone(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8542) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8543) bra t_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8545) LP1NEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8546) fmov.s zero(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8548) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8549) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8551) global slognp1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8552) #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8553) # Simply return the denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8554) slognp1d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8555) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8557) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8558) # satanh(): computes the inverse hyperbolic tangent of a norm input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8559) # satanhd(): computes the inverse hyperbolic tangent of a denorm input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8560) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8561) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8562) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8563) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8564) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8565) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8566) # fp0 = arctanh(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8567) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8568) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8569) # The returned result is within 3 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8570) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8571) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8572) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8573) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8574) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8575) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8576) # ATANH #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8577) # 1. If |X| >= 1, go to 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8578) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8579) # 2. (|X| < 1) Calculate atanh(X) by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8580) # sgn := sign(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8581) # y := |X| #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8582) # z := 2y/(1-y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8583) # atanh(X) := sgn * (1/2) * logp1(z) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8584) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8585) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8586) # 3. If |X| > 1, go to 5. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8587) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8588) # 4. (|X| = 1) Generate infinity with an appropriate sign and #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8589) # divide-by-zero by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8590) # sgn := sign(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8591) # atan(X) := sgn / (+0). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8592) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8593) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8594) # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8595) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8596) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8597) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8599) global satanh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8600) satanh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8601) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8602) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8603) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8604) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8605) bge.b ATANHBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8607) #--THIS IS THE USUAL CASE, |X| < 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8608) #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8610) fabs.x (%a0),%fp0 # Y = |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8611) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8612) fneg.x %fp1 # -Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8613) fadd.x %fp0,%fp0 # 2Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8614) fadd.s &0x3F800000,%fp1 # 1-Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8615) fdiv.x %fp1,%fp0 # 2Y/(1-Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8616) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8617) and.l &0x80000000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8618) or.l &0x3F000000,%d1 # SIGN(X)*HALF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8619) mov.l %d1,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8621) mov.l %d0,-(%sp) # save rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8622) clr.l %d0 # pass ext prec,RN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8623) fmovm.x &0x01,-(%sp) # save Z on stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8624) lea (%sp),%a0 # pass ptr to Z
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8625) bsr slognp1 # LOG1P(Z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8626) add.l &0xc,%sp # clear Z from stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8628) mov.l (%sp)+,%d0 # fetch old prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8629) fmov.l %d0,%fpcr # load it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8630) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8631) fmul.s (%sp)+,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8632) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8634) ATANHBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8635) fabs.x (%a0),%fp0 # |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8636) fcmp.s %fp0,&0x3F800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8637) fbgt t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8638) bra t_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8640) global satanhd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8641) #--ATANH(X) = X FOR DENORMALIZED X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8642) satanhd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8643) bra t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8645) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8646) # slog10(): computes the base-10 logarithm of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8647) # slog10d(): computes the base-10 logarithm of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8648) # slog2(): computes the base-2 logarithm of a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8649) # slog2d(): computes the base-2 logarithm of a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8650) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8651) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8652) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8653) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8654) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8655) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8656) # fp0 = log_10(X) or log_2(X) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8657) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8658) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8659) # The returned result is within 1.7 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8660) # i.e. within 0.5003 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8661) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8662) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8663) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8664) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8665) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8666) # slog10d: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8667) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8668) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8669) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8670) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8671) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8672) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8673) # Step 1. Call slognd to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8674) # Notes: Even if X is denormalized, log(X) is always normalized. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8675) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8676) # Step 2. Compute log_10(X) = log(X) * (1/log(10)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8677) # 2.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8678) # 2.2 Return ans := Y * INV_L10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8679) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8680) # slog10: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8681) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8682) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8683) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8684) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8685) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8686) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8687) # Step 1. Call sLogN to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8688) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8689) # Step 2. Compute log_10(X) = log(X) * (1/log(10)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8690) # 2.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8691) # 2.2 Return ans := Y * INV_L10. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8692) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8693) # sLog2d: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8694) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8695) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8696) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8697) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8698) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8699) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8700) # Step 1. Call slognd to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8701) # Notes: Even if X is denormalized, log(X) is always normalized. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8702) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8703) # Step 2. Compute log_10(X) = log(X) * (1/log(2)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8704) # 2.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8705) # 2.2 Return ans := Y * INV_L2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8706) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8707) # sLog2: #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8708) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8709) # Step 0. If X < 0, create a NaN and raise the invalid operation #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8710) # flag. Otherwise, save FPCR in D1; set FpCR to default. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8711) # Notes: Default means round-to-nearest mode, no floating-point #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8712) # traps, and precision control = double extended. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8713) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8714) # 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 8715) # go to Step 3. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8716) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8717) # Step 2. Return k. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8718) # 2.1 Get integer k, X = 2^k. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8719) # 2.2 Restore the user FPCR. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8720) # 2.3 Return ans := convert-to-double-extended(k). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8721) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8722) # Step 3. Call sLogN to obtain Y = log(X), the natural log of X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8723) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8724) # Step 4. Compute log_2(X) = log(X) * (1/log(2)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8725) # 4.1 Restore the user FPCR #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8726) # 4.2 Return ans := Y * INV_L2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8727) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8728) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8730) INV_L10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8731) long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8733) INV_L2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8734) long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8736) global slog10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8737) #--entry point for Log10(X), X is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8738) slog10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8739) fmov.b &0x1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8740) fcmp.x %fp0,(%a0) # if operand == 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8741) fbeq.l ld_pzero # return an EXACT zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8743) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8744) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8745) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8746) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8747) bsr slogn # log(X), X normal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8748) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8749) fmul.x INV_L10(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8750) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8752) global slog10d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8753) #--entry point for Log10(X), X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8754) slog10d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8755) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8756) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8757) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8758) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8759) bsr slognd # log(X), X denorm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8760) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8761) fmul.x INV_L10(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8762) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8764) global slog2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8765) #--entry point for Log2(X), X is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8766) slog2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8767) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8768) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8770) mov.l 8(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8771) bne.b continue # X is not 2^k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8773) mov.l 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8774) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8775) bne.b continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8777) #--X = 2^k.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8778) mov.w (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8779) and.l &0x00007FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8780) sub.l &0x3FFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8781) beq.l ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8782) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8783) fmov.l %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8784) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8786) continue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8787) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8788) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8789) bsr slogn # log(X), X normal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8790) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8791) fmul.x INV_L2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8792) bra t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8794) invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8795) bra t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8797) global slog2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8798) #--entry point for Log2(X), X is denormalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8799) slog2d:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8800) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8801) blt.w invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8802) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8803) clr.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8804) bsr slognd # log(X), X denorm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8805) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8806) fmul.x INV_L2(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8807) bra t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8809) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8810) # stwotox(): computes 2**X for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8811) # stwotoxd(): computes 2**X for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8812) # stentox(): computes 10**X for a normalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8813) # stentoxd(): computes 10**X for a denormalized input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8814) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8815) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8816) # a0 = pointer to extended precision input #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8817) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8818) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8819) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8820) # fp0 = 2**X or 10**X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8821) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8822) # ACCURACY and MONOTONICITY ******************************************* #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8823) # The returned result is within 2 ulps in 64 significant bit, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8824) # i.e. within 0.5001 ulp to 53 bits if the result is subsequently #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8825) # rounded to double precision. The result is provably monotonic #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8826) # in double precision. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8827) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8828) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8829) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8830) # twotox #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8831) # 1. If |X| > 16480, go to ExpBig. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8832) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8833) # 2. If |X| < 2**(-70), go to ExpSm. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8834) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8835) # 3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8836) # decompose N as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8837) # N = 64(M + M') + j, j = 0,1,2,...,63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8838) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8839) # 4. Overwrite r := r * log2. Then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8840) # 2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8841) # Go to expr to compute that expression. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8842) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8843) # tentox #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8844) # 1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8845) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8846) # 2. If |X| < 2**(-70), go to ExpSm. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8847) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8848) # 3. Set y := X*log_2(10)*64 (base 2 log of 10). Set #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8849) # N := round-to-int(y). Decompose N as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8850) # N = 64(M + M') + j, j = 0,1,2,...,63. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8851) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8852) # 4. Define r as #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8853) # r := ((X - N*L1)-N*L2) * L10 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8854) # where L1, L2 are the leading and trailing parts of #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8855) # log_10(2)/64 and L10 is the natural log of 10. Then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8856) # 10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8857) # Go to expr to compute that expression. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8858) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8859) # expr #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8860) # 1. Fetch 2**(j/64) from table as Fact1 and Fact2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8861) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8862) # 2. Overwrite Fact1 and Fact2 by #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8863) # Fact1 := 2**(M) * Fact1 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8864) # Fact2 := 2**(M) * Fact2 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8865) # Thus Fact1 + Fact2 = 2**(M) * 2**(j/64). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8866) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8867) # 3. Calculate P where 1 + P approximates exp(r): #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8868) # P = r + r*r*(A1+r*(A2+...+r*A5)). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8869) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8870) # 4. Let AdjFact := 2**(M'). Return #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8871) # AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ). #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8872) # Exit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8873) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8874) # ExpBig #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8875) # 1. Generate overflow by Huge * Huge if X > 0; otherwise, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8876) # generate underflow by Tiny * Tiny. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8877) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8878) # ExpSm #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8879) # 1. Return 1 + X. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8880) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8881) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8883) L2TEN64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8884) long 0x406A934F,0x0979A371 # 64LOG10/LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8885) L10TWO1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8886) long 0x3F734413,0x509F8000 # LOG2/64LOG10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8888) L10TWO2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8889) long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8891) LOG10: long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8893) LOG2: long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8895) EXPA5: long 0x3F56C16D,0x6F7BD0B2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8896) EXPA4: long 0x3F811112,0x302C712C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8897) EXPA3: long 0x3FA55555,0x55554CC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8898) EXPA2: long 0x3FC55555,0x55554A54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8899) EXPA1: long 0x3FE00000,0x00000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8901) TEXPTBL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8902) long 0x3FFF0000,0x80000000,0x00000000,0x3F738000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8903) long 0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8904) long 0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8905) long 0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8906) long 0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8907) long 0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8908) long 0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8909) long 0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8910) long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8911) long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8912) long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8913) long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8914) long 0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8915) long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8916) long 0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8917) long 0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8918) long 0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8919) long 0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8920) long 0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8921) long 0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8922) long 0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8923) long 0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8924) long 0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8925) long 0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8926) long 0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8927) long 0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8928) long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8929) long 0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8930) long 0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8931) long 0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8932) long 0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8933) long 0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8934) long 0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8935) long 0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8936) long 0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8937) long 0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8938) long 0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8939) long 0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8940) long 0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8941) long 0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8942) long 0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8943) long 0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8944) long 0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8945) long 0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8946) long 0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8947) long 0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8948) long 0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8949) long 0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8950) long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8951) long 0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8952) long 0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8953) long 0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8954) long 0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8955) long 0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8956) long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8957) long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8958) long 0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8959) long 0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8960) long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8961) long 0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8962) long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8963) long 0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8964) long 0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8965) long 0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8967) set INT,L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8969) set X,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8970) set XDCARE,X+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8971) set XFRAC,X+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8973) set ADJFACT,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8975) set FACT1,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8976) set FACT1HI,FACT1+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8977) set FACT1LOW,FACT1+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8979) set FACT2,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8980) set FACT2HI,FACT2+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8981) set FACT2LOW,FACT2+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8983) global stwotox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8984) #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8985) stwotox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8986) fmovm.x (%a0),&0x80 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8988) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8989) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8990) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8991) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8993) cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8994) bge.b TWOOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8995) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8997) TWOOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8998) cmp.l %d1,&0x400D80C0 # |X| > 16480?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8999) ble.b TWOMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9000) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9002) TWOMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9003) #--USUAL CASE, 2^(-70) <= |X| <= 16480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9005) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9006) fmul.s &0x42800000,%fp1 # 64 * X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9007) fmov.l %fp1,INT(%a6) # N = ROUND-TO-INT(64 X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9008) mov.l %d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9009) lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9010) fmov.l INT(%a6),%fp1 # N --> FLOATING FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9011) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9012) mov.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9013) and.l &0x3F,%d1 # D0 IS J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9014) asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9015) add.l %d1,%a1 # ADDRESS FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9016) asr.l &6,%d2 # d2 IS L, N = 64L + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9017) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9018) asr.l &1,%d1 # D0 IS M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9019) sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9020) add.l &0x3FFF,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9022) #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9023) #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9024) #--ADJFACT = 2^(M').
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9025) #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9027) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9029) fmul.s &0x3C800000,%fp1 # (1/64)*N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9030) mov.l (%a1)+,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9031) mov.l (%a1)+,FACT1HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9032) mov.l (%a1)+,FACT1LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9033) mov.w (%a1)+,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9035) fsub.x %fp1,%fp0 # X - (1/64)*INT(64 X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9037) mov.w (%a1)+,FACT2HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9038) clr.w FACT2HI+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9039) clr.l FACT2LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9040) add.w %d1,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9041) fmul.x LOG2(%pc),%fp0 # FP0 IS R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9042) add.w %d1,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9044) bra.w expr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9046) EXPBORS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9047) #--FPCR, D0 SAVED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9048) cmp.l %d1,&0x3FFF8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9049) bgt.b TEXPBIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9051) #--|X| IS SMALL, RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9053) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9054) fadd.s &0x3F800000,%fp0 # RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9055) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9057) TEXPBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9058) #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9059) #--REGISTERS SAVE SO FAR ARE FPCR AND D0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9060) mov.l X(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9061) cmp.l %d1,&0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9062) blt.b EXPNEG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9064) bra t_ovfl2 # t_ovfl expects positive value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9066) EXPNEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9067) bra t_unfl2 # t_unfl expects positive value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9069) global stwotoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9070) stwotoxd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9071) #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9073) fmov.l %d0,%fpcr # set user's rounding mode/precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9074) fmov.s &0x3F800000,%fp0 # RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9075) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9076) or.l &0x00800001,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9077) fadd.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9078) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9080) global stentox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9081) #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9082) stentox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9083) fmovm.x (%a0),&0x80 # LOAD INPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9085) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9086) mov.w 4(%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9087) fmov.x %fp0,X(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9088) and.l &0x7FFFFFFF,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9090) cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9091) bge.b TENOK1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9092) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9094) TENOK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9095) cmp.l %d1,&0x400B9B07 # |X| <= 16480*log2/log10 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9096) ble.b TENMAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9097) bra.w EXPBORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9099) TENMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9100) #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9102) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9103) fmul.d L2TEN64(%pc),%fp1 # X*64*LOG10/LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9104) fmov.l %fp1,INT(%a6) # N=INT(X*64*LOG10/LOG2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9105) mov.l %d2,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9106) lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9107) fmov.l INT(%a6),%fp1 # N --> FLOATING FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9108) mov.l INT(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9109) mov.l %d1,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9110) and.l &0x3F,%d1 # D0 IS J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9111) asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9112) add.l %d1,%a1 # ADDRESS FOR 2^(J/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9113) asr.l &6,%d2 # d2 IS L, N = 64L + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9114) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9115) asr.l &1,%d1 # D0 IS M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9116) sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9117) add.l &0x3FFF,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9119) #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9120) #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9121) #--ADJFACT = 2^(M').
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9122) #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9123) fmovm.x &0x0c,-(%sp) # save fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9125) fmov.x %fp1,%fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9127) fmul.d L10TWO1(%pc),%fp1 # N*(LOG2/64LOG10)_LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9128) mov.l (%a1)+,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9130) fmul.x L10TWO2(%pc),%fp2 # N*(LOG2/64LOG10)_TRAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9132) mov.l (%a1)+,FACT1HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9133) mov.l (%a1)+,FACT1LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9134) fsub.x %fp1,%fp0 # X - N L_LEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9135) mov.w (%a1)+,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9137) fsub.x %fp2,%fp0 # X - N L_TRAIL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9139) mov.w (%a1)+,FACT2HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9140) clr.w FACT2HI+2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9141) clr.l FACT2LOW(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9143) fmul.x LOG10(%pc),%fp0 # FP0 IS R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9144) add.w %d1,FACT1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9145) add.w %d1,FACT2(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9147) expr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9148) #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9149) #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9150) #--FP0 IS R. THE FOLLOWING CODE COMPUTES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9151) #-- 2**(M'+M) * 2**(J/64) * EXP(R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9153) fmov.x %fp0,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9154) fmul.x %fp1,%fp1 # FP1 IS S = R*R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9156) fmov.d EXPA5(%pc),%fp2 # FP2 IS A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9157) fmov.d EXPA4(%pc),%fp3 # FP3 IS A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9159) fmul.x %fp1,%fp2 # FP2 IS S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9160) fmul.x %fp1,%fp3 # FP3 IS S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9162) fadd.d EXPA3(%pc),%fp2 # FP2 IS A3+S*A5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9163) fadd.d EXPA2(%pc),%fp3 # FP3 IS A2+S*A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9165) fmul.x %fp1,%fp2 # FP2 IS S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9166) fmul.x %fp1,%fp3 # FP3 IS S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9168) fadd.d EXPA1(%pc),%fp2 # FP2 IS A1+S*(A3+S*A5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9169) fmul.x %fp0,%fp3 # FP3 IS R*S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9171) fmul.x %fp1,%fp2 # FP2 IS S*(A1+S*(A3+S*A5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9172) fadd.x %fp3,%fp0 # FP0 IS R+R*S*(A2+S*A4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9173) fadd.x %fp2,%fp0 # FP0 IS EXP(R) - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9175) fmovm.x (%sp)+,&0x30 # restore fp2/fp3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9177) #--FINAL RECONSTRUCTION PROCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9178) #--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 9179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9180) fmul.x FACT1(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9181) fadd.x FACT2(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9182) fadd.x FACT1(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9184) fmov.l %d0,%fpcr # restore users round prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9185) mov.w %d2,ADJFACT(%a6) # INSERT EXPONENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9186) mov.l (%sp)+,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9187) mov.l &0x80000000,ADJFACT+4(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9188) clr.l ADJFACT+8(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9189) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9190) fmul.x ADJFACT(%a6),%fp0 # FINAL ADJUSTMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9191) bra t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9193) global stentoxd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9194) stentoxd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9195) #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9197) fmov.l %d0,%fpcr # set user's rounding mode/precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9198) fmov.s &0x3F800000,%fp0 # RETURN 1 + X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9199) mov.l (%a0),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9200) or.l &0x00800001,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9201) fadd.s %d1,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9202) bra t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9204) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9205) # sscale(): computes the destination operand scaled by the source #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9206) # operand. If the absoulute value of the source operand is #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9207) # >= 2^14, an overflow or underflow is returned. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9208) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9209) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9210) # a0 = pointer to double-extended source operand X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9211) # a1 = pointer to double-extended destination operand Y #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9212) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9213) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9214) # fp0 = scale(X,Y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9215) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9216) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9218) set SIGN, L_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9220) global sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9221) sscale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9222) mov.l %d0,-(%sp) # store off ctrl bits for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9224) mov.w DST_EX(%a1),%d1 # get dst exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9225) smi.b SIGN(%a6) # use SIGN to hold dst sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9226) andi.l &0x00007fff,%d1 # strip sign from dst exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9228) mov.w SRC_EX(%a0),%d0 # check src bounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9229) andi.w &0x7fff,%d0 # clr src sign bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9230) cmpi.w %d0,&0x3fff # is src ~ ZERO?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9231) blt.w src_small # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9232) cmpi.w %d0,&0x400c # no; is src too big?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9233) bgt.w src_out # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9235) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9236) # Source is within 2^14 range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9237) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9238) src_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9239) fintrz.x SRC(%a0),%fp0 # calc int of src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9240) fmov.l %fp0,%d0 # int src to d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9241) # don't want any accrued bits from the fintrz showing up later since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9242) # we may need to read the fpsr for the last fp op in t_catch2().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9243) fmov.l &0x0,%fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9245) tst.b DST_HI(%a1) # is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9246) bmi.b sok_norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9248) # the dst is a DENORM. normalize the DENORM and add the adjustment to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9249) # the src value. then, jump to the norm part of the routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9250) sok_dnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9251) mov.l %d0,-(%sp) # save src for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9253) mov.w DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9254) mov.l DST_HI(%a1),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9255) mov.l DST_LO(%a1),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9257) lea FP_SCR0(%a6),%a0 # pass ptr to DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9258) bsr.l norm # normalize the DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9259) neg.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9260) add.l (%sp)+,%d0 # add adjustment to src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9262) fmovm.x FP_SCR0(%a6),&0x80 # load normalized DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9264) cmpi.w %d0,&-0x3fff # is the shft amt really low?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9265) bge.b sok_norm2 # thank goodness no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9267) # the multiply factor that we're trying to create should be a denorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9268) # for the multiply to work. therefore, we're going to actually do a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9269) # multiply with a denorm which will cause an unimplemented data type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9270) # exception to be put into the machine which will be caught and corrected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9271) # later. we don't do this with the DENORMs above because this method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9272) # is slower. but, don't fret, I don't see it being used much either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9273) fmov.l (%sp)+,%fpcr # restore user fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9274) mov.l &0x80000000,%d1 # load normalized mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9275) subi.l &-0x3fff,%d0 # how many should we shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9276) neg.l %d0 # make it positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9277) cmpi.b %d0,&0x20 # is it > 32?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9278) bge.b sok_dnrm_32 # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9279) lsr.l %d0,%d1 # no; bit stays in upper lw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9280) clr.l -(%sp) # insert zero low mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9281) mov.l %d1,-(%sp) # insert new high mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9282) clr.l -(%sp) # make zero exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9283) bra.b sok_norm_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9284) sok_dnrm_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9285) subi.b &0x20,%d0 # get shift count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9286) lsr.l %d0,%d1 # make low mantissa longword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9287) mov.l %d1,-(%sp) # insert new low mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9288) clr.l -(%sp) # insert zero high mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9289) clr.l -(%sp) # make zero exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9290) bra.b sok_norm_cont
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9292) # the src will force the dst to a DENORM value or worse. so, let's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9293) # create an fp multiply that will create the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9294) sok_norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9295) fmovm.x DST(%a1),&0x80 # load fp0 with normalized src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9296) sok_norm2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9297) fmov.l (%sp)+,%fpcr # restore user fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9299) addi.w &0x3fff,%d0 # turn src amt into exp value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9300) swap %d0 # put exponent in high word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9301) clr.l -(%sp) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9302) mov.l &0x80000000,-(%sp) # insert new high mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9303) mov.l %d0,-(%sp) # insert new lo mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9305) sok_norm_cont:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9306) fmov.l %fpcr,%d0 # d0 needs fpcr for t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9307) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9308) fmul.x (%sp)+,%fp0 # do the multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9309) bra t_catch2 # catch any exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9311) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9312) # Source is outside of 2^14 range. Test the sign and branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9313) # to the appropriate exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9314) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9315) src_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9316) mov.l (%sp)+,%d0 # restore ctrl bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9317) exg %a0,%a1 # swap src,dst ptrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9318) tst.b SRC_EX(%a1) # is src negative?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9319) bmi t_unfl # yes; underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9320) bra t_ovfl_sc # no; overflow
^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) # The source input is below 1, so we check for denormalized numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9324) # and set unfl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9325) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9326) src_small:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9327) tst.b DST_HI(%a1) # is dst denormalized?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9328) bpl.b ssmall_done # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9330) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9331) fmov.l %d0,%fpcr # no; load control bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9332) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9333) fmov.x DST(%a1),%fp0 # simply return dest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9334) bra t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9335) ssmall_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9336) mov.l (%sp)+,%d0 # load control bits into d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9337) mov.l %a1,%a0 # pass ptr to dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9338) bra t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9340) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9341) # smod(): computes the fp MOD of the input values X,Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9342) # srem(): computes the fp (IEEE) REM of the input values X,Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9343) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9344) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9345) # a0 = pointer to extended precision input X #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9346) # a1 = pointer to extended precision input Y #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9347) # d0 = round precision,mode #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9348) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9349) # The input operands X and Y can be either normalized or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9350) # denormalized. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9351) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9352) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9353) # fp0 = FREM(X,Y) or FMOD(X,Y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9354) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9355) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9356) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9357) # Step 1. Save and strip signs of X and Y: signX := sign(X), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9358) # signY := sign(Y), X := |X|, Y := |Y|, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9359) # signQ := signX EOR signY. Record whether MOD or REM #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9360) # is requested. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9361) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9362) # Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9363) # If (L < 0) then #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9364) # R := X, go to Step 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9365) # else #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9366) # R := 2^(-L)X, j := L. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9367) # endif #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9368) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9369) # Step 3. Perform MOD(X,Y) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9370) # 3.1 If R = Y, go to Step 9. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9371) # 3.2 If R > Y, then { R := R - Y, Q := Q + 1} #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9372) # 3.3 If j = 0, go to Step 4. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9373) # 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9374) # Step 3.1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9375) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9376) # Step 4. At this point, R = X - QY = MOD(X,Y). Set #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9377) # Last_Subtract := false (used in Step 7 below). If #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9378) # MOD is requested, go to Step 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9379) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9380) # Step 5. R = MOD(X,Y), but REM(X,Y) is requested. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9381) # 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 9382) # Step 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9383) # 5.2 If R > Y/2, then { set Last_Subtract := true, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9384) # Q := Q + 1, Y := signY*Y }. Go to Step 6. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9385) # 5.3 This is the tricky case of R = Y/2. If Q is odd, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9386) # then { Q := Q + 1, signX := -signX }. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9387) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9388) # Step 6. R := signX*R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9389) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9390) # Step 7. If Last_Subtract = true, R := R - Y. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9391) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9392) # Step 8. Return signQ, last 7 bits of Q, and R as required. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9393) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9394) # Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9395) # X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9396) # R := 0. Return signQ, last 7 bits of Q, and R. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9397) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9398) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9400) set Mod_Flag,L_SCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9401) set Sc_Flag,L_SCR3+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9403) set SignY,L_SCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9404) set SignX,L_SCR2+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9405) set SignQ,L_SCR3+2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9407) set Y,FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9408) set Y_Hi,Y+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9409) set Y_Lo,Y+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9411) set R,FP_SCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9412) set R_Hi,R+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9413) set R_Lo,R+8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9415) Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9416) long 0x00010000,0x80000000,0x00000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9418) global smod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9419) smod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9420) clr.b FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9421) mov.l %d0,-(%sp) # save ctrl bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9422) clr.b Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9423) bra.b Mod_Rem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9425) global srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9426) srem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9427) clr.b FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9428) mov.l %d0,-(%sp) # save ctrl bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9429) mov.b &0x1,Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9431) Mod_Rem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9432) #..Save sign of X and Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9433) movm.l &0x3f00,-(%sp) # save data registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9434) mov.w SRC_EX(%a0),%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9435) mov.w %d3,SignY(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9436) and.l &0x00007FFF,%d3 # Y := |Y|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9438) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9439) mov.l SRC_HI(%a0),%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9440) mov.l SRC_LO(%a0),%d5 # (D3,D4,D5) is |Y|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9442) tst.l %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9443) bne.b Y_Normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9445) mov.l &0x00003FFE,%d3 # $3FFD + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9446) tst.l %d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9447) bne.b HiY_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9449) HiY_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9450) mov.l %d5,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9451) clr.l %d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9452) sub.l &32,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9453) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9454) bfffo %d4{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9455) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9456) sub.l %d6,%d3 # (D3,D4,D5) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9457) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9458) bra.b Chk_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9460) HiY_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9461) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9462) bfffo %d4{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9463) sub.l %d6,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9464) lsl.l %d6,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9465) mov.l %d5,%d7 # a copy of D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9466) lsl.l %d6,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9467) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9468) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9469) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9470) or.l %d7,%d4 # (D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9471) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9472) bra.b Chk_X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9474) Y_Normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9475) add.l &0x00003FFE,%d3 # (D3,D4,D5) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9476) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9478) Chk_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9479) mov.w DST_EX(%a1),%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9480) mov.w %d0,SignX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9481) mov.w SignY(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9482) eor.l %d0,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9483) and.l &0x00008000,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9484) mov.w %d1,SignQ(%a6) # sign(Q) obtained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9485) and.l &0x00007FFF,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9486) mov.l DST_HI(%a1),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9487) mov.l DST_LO(%a1),%d2 # (D0,D1,D2) is |X|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9488) tst.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9489) bne.b X_Normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9490) mov.l &0x00003FFE,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9491) tst.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9492) bne.b HiX_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9494) HiX_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9495) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9496) clr.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9497) sub.l &32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9498) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9499) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9500) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9501) sub.l %d6,%d0 # (D0,D1,D2) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9502) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9503) bra.b Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9505) HiX_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9506) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9507) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9508) sub.l %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9509) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9510) mov.l %d2,%d7 # a copy of D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9511) lsl.l %d6,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9512) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9513) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9514) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9515) or.l %d7,%d1 # (D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9516) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9517) bra.b Init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9519) X_Normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9520) add.l &0x00003FFE,%d0 # (D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9521) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9523) Init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9524) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9525) mov.l %d3,L_SCR1(%a6) # save biased exp(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9526) mov.l %d0,-(%sp) # save biased exp(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9527) sub.l %d3,%d0 # L := expo(X)-expo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9529) clr.l %d6 # D6 := carry <- 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9530) clr.l %d3 # D3 is Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9531) mov.l &0,%a1 # A1 is k; j+k=L, Q=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9533) #..(Carry,D1,D2) is R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9534) tst.l %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9535) bge.b Mod_Loop_pre
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9537) #..expo(X) < expo(Y). Thus X = mod(X,Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9538) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9539) mov.l (%sp)+,%d0 # restore d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9540) bra.w Get_Mod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9542) Mod_Loop_pre:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9543) addq.l &0x4,%sp # erase exp(X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9544) #..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9545) Mod_Loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9546) tst.l %d6 # test carry bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9547) bgt.b R_GT_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9549) #..At this point carry = 0, R = (D1,D2), Y = (D4,D5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9550) cmp.l %d1,%d4 # compare hi(R) and hi(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9551) bne.b R_NE_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9552) cmp.l %d2,%d5 # compare lo(R) and lo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9553) bne.b R_NE_Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9555) #..At this point, R = Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9556) bra.w Rem_is_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9558) R_NE_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9559) #..use the borrow of the previous compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9560) bcs.b R_LT_Y # borrow is set iff R < Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9562) R_GT_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9563) #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9564) #..and Y < (D1,D2) < 2Y. Either way, perform R - Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9565) sub.l %d5,%d2 # lo(R) - lo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9566) subx.l %d4,%d1 # hi(R) - hi(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9567) clr.l %d6 # clear carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9568) addq.l &1,%d3 # Q := Q + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9570) R_LT_Y:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9571) #..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 9572) tst.l %d0 # see if j = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9573) beq.b PostLoop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9575) add.l %d3,%d3 # Q := 2Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9576) add.l %d2,%d2 # lo(R) = 2lo(R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9577) roxl.l &1,%d1 # hi(R) = 2hi(R) + carry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9578) scs %d6 # set Carry if 2(R) overflows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9579) addq.l &1,%a1 # k := k+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9580) subq.l &1,%d0 # j := j - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9581) #..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 9582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9583) bra.b Mod_Loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9585) PostLoop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9586) #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9588) #..normalize R.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9589) mov.l L_SCR1(%a6),%d0 # new biased expo of R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9590) tst.l %d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9591) bne.b HiR_not0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9593) HiR_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9594) mov.l %d2,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9595) clr.l %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9596) sub.l &32,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9597) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9598) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9599) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9600) sub.l %d6,%d0 # (D0,D1,D2) is normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9601) # ...with bias $7FFD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9602) bra.b Get_Mod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9604) HiR_not0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9605) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9606) bfffo %d1{&0:&32},%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9607) bmi.b Get_Mod # already normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9608) sub.l %d6,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9609) lsl.l %d6,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9610) mov.l %d2,%d7 # a copy of D2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9611) lsl.l %d6,%d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9612) neg.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9613) add.l &32,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9614) lsr.l %d6,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9615) or.l %d7,%d1 # (D0,D1,D2) normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9617) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9618) Get_Mod:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9619) cmp.l %d0,&0x000041FE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9620) bge.b No_Scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9621) Do_Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9622) mov.w %d0,R(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9623) mov.l %d1,R_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9624) mov.l %d2,R_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9625) mov.l L_SCR1(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9626) mov.w %d6,Y(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9627) mov.l %d4,Y_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9628) mov.l %d5,Y_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9629) fmov.x R(%a6),%fp0 # no exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9630) mov.b &1,Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9631) bra.b ModOrRem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9632) No_Scale:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9633) mov.l %d1,R_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9634) mov.l %d2,R_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9635) sub.l &0x3FFE,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9636) mov.w %d0,R(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9637) mov.l L_SCR1(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9638) sub.l &0x3FFE,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9639) mov.l %d6,L_SCR1(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9640) fmov.x R(%a6),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9641) mov.w %d6,Y(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9642) mov.l %d4,Y_Hi(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9643) mov.l %d5,Y_Lo(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9644) clr.b Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9646) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9647) ModOrRem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9648) tst.b Mod_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9649) beq.b Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9651) mov.l L_SCR1(%a6),%d6 # new biased expo(Y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9652) subq.l &1,%d6 # biased expo(Y/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9653) cmp.l %d0,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9654) blt.b Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9655) bgt.b Last_Sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9657) cmp.l %d1,%d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9658) bne.b Not_EQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9659) cmp.l %d2,%d5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9660) bne.b Not_EQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9661) bra.w Tie_Case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9663) Not_EQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9664) bcs.b Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9666) Last_Sub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9667) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9668) fsub.x Y(%a6),%fp0 # no exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9669) addq.l &1,%d3 # Q := Q + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9671) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9672) Fix_Sign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9673) #..Get sign of X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9674) mov.w SignX(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9675) bge.b Get_Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9676) fneg.x %fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9678) #..Get Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9679) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9680) Get_Q:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9681) clr.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9682) mov.w SignQ(%a6),%d6 # D6 is sign(Q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9683) mov.l &8,%d7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9684) lsr.l %d7,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9685) and.l &0x0000007F,%d3 # 7 bits of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9686) or.l %d6,%d3 # sign and bits of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9687) # swap %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9688) # fmov.l %fpsr,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9689) # and.l &0xFF00FFFF,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9690) # or.l %d3,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9691) # fmov.l %d6,%fpsr # put Q in fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9692) mov.b %d3,FPSR_QBYTE(%a6) # put Q in fpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9694) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9695) Restore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9696) movm.l (%sp)+,&0xfc # {%d2-%d7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9697) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9698) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9699) tst.b Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9700) beq.b Finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9701) mov.b &FMUL_OP,%d1 # last inst is MUL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9702) fmul.x Scale(%pc),%fp0 # may cause underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9703) bra t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9704) # the '040 package did this apparently to see if the dst operand for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9705) # preceding fmul was a denorm. but, it better not have been since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9706) # algorithm just got done playing with fp0 and expected no exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9707) # as a result. trust me...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9708) # bra t_avoid_unsupp # check for denorm as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9709) # ;result of the scaling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9711) Finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9712) mov.b &FMOV_OP,%d1 # last inst is MOVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9713) fmov.x %fp0,%fp0 # capture exceptions & round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9714) bra t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9716) Rem_is_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9717) #..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 9718) addq.l &1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9719) cmp.l %d0,&8 # D0 is j
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9720) bge.b Q_Big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9722) lsl.l %d0,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9723) bra.b Set_R_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9725) Q_Big:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9726) clr.l %d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9728) Set_R_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9729) fmov.s &0x00000000,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9730) clr.b Sc_Flag(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9731) bra.w Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9733) Tie_Case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9734) #..Check parity of Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9735) mov.l %d3,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9736) and.l &0x00000001,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9737) tst.l %d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9738) beq.w Fix_Sign # Q is even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9740) #..Q is odd, Q := Q + 1, signX := -signX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9741) addq.l &1,%d3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9742) mov.w SignX(%a6),%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9743) eor.l &0x00008000,%d6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9744) mov.w %d6,SignX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9745) bra.w Fix_Sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9747) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9748) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9749) # tag(): return the optype of the input ext fp number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9750) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9751) # This routine is used by the 060FPLSP. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9752) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9753) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9754) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9755) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9756) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9757) # a0 = pointer to extended precision operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9758) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9759) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9760) # d0 = value of type tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9761) # one of: NORM, INF, QNAN, SNAN, DENORM, ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9762) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9763) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9764) # Simply test the exponent, j-bit, and mantissa values to #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9765) # determine the type of operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9766) # If it's an unnormalized zero, alter the operand and force it #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9767) # to be a normal zero. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9768) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9769) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9771) global tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9772) tag:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9773) mov.w FTEMP_EX(%a0), %d0 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9774) andi.w &0x7fff, %d0 # strip off sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9775) cmpi.w %d0, &0x7fff # is (EXP == MAX)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9776) beq.b inf_or_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9777) not_inf_or_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9778) btst &0x7,FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9779) beq.b not_norm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9780) is_norm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9781) mov.b &NORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9782) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9783) not_norm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9784) tst.w %d0 # is exponent = 0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9785) bne.b is_unnorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9786) not_unnorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9787) tst.l FTEMP_HI(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9788) bne.b is_denorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9789) tst.l FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9790) bne.b is_denorm_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9791) is_zero_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9792) mov.b &ZERO, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9793) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9794) is_denorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9795) mov.b &DENORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9796) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9797) is_unnorm_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9798) bsr.l unnorm_fix # convert to norm,denorm,or zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9799) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9800) is_unnorm_reg_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9801) mov.b &UNNORM, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9802) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9803) inf_or_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9804) tst.l FTEMP_LO(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9805) bne.b is_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9806) mov.l FTEMP_HI(%a0), %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9807) and.l &0x7fffffff, %d0 # msb is a don't care!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9808) bne.b is_nan_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9809) is_inf_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9810) mov.b &INF, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9811) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9812) is_nan_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9813) mov.b &QNAN, %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9814) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9816) #############################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9818) qnan: long 0x7fff0000, 0xffffffff, 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9820) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9821) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9822) # t_dz(): Handle 060FPLSP dz exception for "flogn" emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9823) # t_dz2(): Handle 060FPLSP dz exception for "fatanh" emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9824) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9825) # These rouitnes are used by the 060FPLSP package. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9826) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9827) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9828) # None #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9829) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9830) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9831) # a0 = pointer to extended precision source operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9832) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9833) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9834) # fp0 = default DZ result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9835) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9836) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9837) # Transcendental emulation for the 060FPLSP has detected that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9838) # a DZ exception should occur for the instruction. If DZ is disabled, #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9839) # return the default result. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9840) # If DZ is enabled, the dst operand should be returned unscathed #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9841) # in fp0 while fp1 is used to create a DZ exception so that the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9842) # operating system can log that such an event occurred. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9843) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9844) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9846) global t_dz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9847) t_dz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9848) tst.b SRC_EX(%a0) # check sign for neg or pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9849) bpl.b dz_pinf # branch if pos sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9851) global t_dz2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9852) t_dz2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9853) ori.l &dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9855) btst &dz_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9856) bne.b dz_minf_ena
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9858) # dz is disabled. return a -INF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9859) fmov.s &0xff800000,%fp0 # return -INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9860) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9862) # dz is enabled. create a dz exception so the user can record it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9863) # but use fp1 instead. return the dst operand unscathed in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9864) dz_minf_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9865) fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9866) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9867) fmov.s &0xbf800000,%fp1 # load -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9868) fdiv.s &0x00000000,%fp1 # -1 / 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9869) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9871) dz_pinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9872) ori.l &dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9874) btst &dz_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9875) bne.b dz_pinf_ena
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9877) # dz is disabled. return a +INF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9878) fmov.s &0x7f800000,%fp0 # return +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9879) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9881) # dz is enabled. create a dz exception so the user can record it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9882) # but use fp1 instead. return the dst operand unscathed in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9883) dz_pinf_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9884) fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9885) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9886) fmov.s &0x3f800000,%fp1 # load +1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9887) fdiv.s &0x00000000,%fp1 # +1 / 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9888) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9890) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9891) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9892) # t_operr(): Handle 060FPLSP OPERR exception during emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9893) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9894) # This routine is used by the 060FPLSP package. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9895) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9896) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9897) # None. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9898) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9899) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9900) # fp1 = source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9901) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9902) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9903) # fp0 = default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9904) # fp1 = unchanged #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9905) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9906) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9907) # An operand error should occur as the result of transcendental #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9908) # emulation in the 060FPLSP. If OPERR is disabled, just return a NAN #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9909) # in fp0. If OPERR is enabled, return the dst operand unscathed in fp0 #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9910) # and the source operand in fp1. Use fp2 to create an OPERR exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9911) # so that the operating system can log the event. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9912) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9913) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9915) global t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9916) t_operr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9917) ori.l &opnan_mask,USER_FPSR(%a6) # set NAN/OPERR/AIOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9919) btst &operr_bit,FPCR_ENABLE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9920) bne.b operr_ena
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9922) # operr is disabled. return a QNAN in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9923) fmovm.x qnan(%pc),&0x80 # return QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9924) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9926) # operr is enabled. create an operr exception so the user can record it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9927) # but use fp2 instead. return the dst operand unscathed in fp0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9928) operr_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9929) fmovm.x EXC_FP0(%a6),&0x80 # return fp0 unscathed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9930) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9931) fmovm.x &0x04,-(%sp) # save fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9932) fmov.s &0x7f800000,%fp2 # load +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9933) fmul.s &0x00000000,%fp2 # +INF x 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9934) fmovm.x (%sp)+,&0x20 # restore fp2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9935) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9937) pls_huge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9938) long 0x7ffe0000,0xffffffff,0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9939) mns_huge:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9940) long 0xfffe0000,0xffffffff,0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9941) pls_tiny:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9942) long 0x00000000,0x80000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9943) mns_tiny:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9944) long 0x80000000,0x80000000,0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9946) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9947) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9948) # t_unfl(): Handle 060FPLSP underflow exception during emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9949) # t_unfl2(): Handle 060FPLSP underflow exception during #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9950) # emulation. result always positive. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9951) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9952) # This routine is used by the 060FPLSP package. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9953) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9954) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9955) # None. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9956) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9957) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9958) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9959) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9960) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9961) # fp0 = default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9962) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9963) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9964) # An underflow should occur as the result of transcendental #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9965) # emulation in the 060FPLSP. Create an underflow by using "fmul" #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9966) # and two very small numbers of appropriate sign so the operating #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9967) # system can log the event. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9968) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9969) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9971) global t_unfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9972) t_unfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9973) tst.b SRC_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9974) bpl.b unf_pos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9976) global t_unfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9977) t_unfl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9978) ori.l &unfinx_mask+neg_mask,USER_FPSR(%a6) # set N/UNFL/INEX2/AUNFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9980) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9981) fmovm.x mns_tiny(%pc),&0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9982) fmul.x pls_tiny(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9984) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9985) rol.l &0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9986) mov.b %d0,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9987) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9988) unf_pos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9989) ori.w &unfinx_mask,FPSR_EXCEPT(%a6) # set UNFL/INEX2/AUNFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9991) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9992) fmovm.x pls_tiny(%pc),&0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9993) fmul.x %fp0,%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9995) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9996) rol.l &0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9997) mov.b %d0,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9998) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10000) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10001) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10002) # t_ovfl(): Handle 060FPLSP overflow exception during emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10003) # (monadic) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10004) # t_ovfl2(): Handle 060FPLSP overflow exception during #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10005) # emulation. result always positive. (dyadic) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10006) # t_ovfl_sc(): Handle 060FPLSP overflow exception during #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10007) # emulation for "fscale". #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10008) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10009) # This routine is used by the 060FPLSP package. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10010) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10011) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10012) # None. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10013) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10014) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10015) # a0 = pointer to extended precision source operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10016) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10017) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10018) # fp0 = default underflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10019) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10020) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10021) # An overflow should occur as the result of transcendental #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10022) # emulation in the 060FPLSP. Create an overflow by using "fmul" #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10023) # and two very lareg numbers of appropriate sign so the operating #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10024) # system can log the event. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10025) # For t_ovfl_sc() we take special care not to lose the INEX2 bit. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10026) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10027) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10029) global t_ovfl_sc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10030) t_ovfl_sc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10031) ori.l &ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10033) mov.b %d0,%d1 # fetch rnd prec,mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10034) andi.b &0xc0,%d1 # extract prec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10035) beq.w ovfl_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10037) # dst op is a DENORM. we have to normalize the mantissa to see if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10038) # result would be inexact for the given precision. make a copy of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10039) # dst so we don't screw up the version passed to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10040) mov.w LOCAL_EX(%a0),FP_SCR0_EX(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10041) mov.l LOCAL_HI(%a0),FP_SCR0_HI(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10042) mov.l LOCAL_LO(%a0),FP_SCR0_LO(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10043) lea FP_SCR0(%a6),%a0 # pass ptr to FP_SCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10044) movm.l &0xc080,-(%sp) # save d0-d1/a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10045) bsr.l norm # normalize mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10046) movm.l (%sp)+,&0x0103 # restore d0-d1/a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10048) cmpi.b %d1,&0x40 # is precision sgl?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10049) bne.b ovfl_sc_dbl # no; dbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10050) ovfl_sc_sgl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10051) tst.l LOCAL_LO(%a0) # is lo lw of sgl set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10052) bne.b ovfl_sc_inx # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10053) tst.b 3+LOCAL_HI(%a0) # is lo byte of hi lw set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10054) bne.b ovfl_sc_inx # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10055) bra.w ovfl_work # don't set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10056) ovfl_sc_dbl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10057) mov.l LOCAL_LO(%a0),%d1 # are any of lo 11 bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10058) andi.l &0x7ff,%d1 # dbl mantissa set?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10059) beq.w ovfl_work # no; don't set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10060) ovfl_sc_inx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10061) ori.l &inex2_mask,USER_FPSR(%a6) # set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10062) bra.b ovfl_work # continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10064) global t_ovfl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10065) t_ovfl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10066) ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10067) ovfl_work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10068) tst.b SRC_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10069) bpl.b ovfl_p
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10070) ovfl_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10071) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10072) fmovm.x mns_huge(%pc),&0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10073) fmul.x pls_huge(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10075) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10076) rol.l &0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10077) ori.b &neg_mask,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10078) mov.b %d0,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10079) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10080) ovfl_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10081) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10082) fmovm.x pls_huge(%pc),&0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10083) fmul.x pls_huge(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10085) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10086) rol.l &0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10087) mov.b %d0,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10088) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10090) global t_ovfl2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10091) t_ovfl2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10092) ori.w &ovfinx_mask,FPSR_EXCEPT(%a6) # set OVFL/INEX2/AOVFL/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10093) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10094) fmovm.x pls_huge(%pc),&0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10095) fmul.x pls_huge(%pc),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10097) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10098) rol.l &0x8,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10099) mov.b %d0,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10100) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10102) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10103) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10104) # t_catch(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10105) # emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10106) # t_catch2(): Handle 060FPLSP OVFL,UNFL,or INEX2 exception during #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10107) # emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10108) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10109) # These routines are used by the 060FPLSP package. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10110) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10111) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10112) # None. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10113) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10114) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10115) # fp0 = default underflow or overflow result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10116) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10117) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10118) # fp0 = default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10119) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10120) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10121) # If an overflow or underflow occurred during the last #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10122) # instruction of transcendental 060FPLSP emulation, then it has already #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10123) # occurred and has been logged. Now we need to see if an inexact #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10124) # exception should occur. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10125) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10126) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10128) global t_catch2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10129) t_catch2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10130) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10131) or.l %d0,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10132) bra.b inx2_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10134) global t_catch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10135) t_catch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10136) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10137) or.l %d0,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10139) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10140) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10141) # t_inx2(): Handle inexact 060FPLSP exception during emulation. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10142) # t_pinx2(): Handle inexact 060FPLSP exception for "+" results. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10143) # t_minx2(): Handle inexact 060FPLSP exception for "-" results. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10144) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10145) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10146) # None. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10147) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10148) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10149) # fp0 = default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10150) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10151) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10152) # fp0 = default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10153) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10154) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10155) # The last instruction of transcendental emulation for the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10156) # 060FPLSP should be inexact. So, if inexact is enabled, then we create #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10157) # the event here by adding a large and very small number together #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10158) # so that the operating system can log the event. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10159) # Must check, too, if the result was zero, in which case we just #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10160) # set the FPSR bits and return. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10161) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10162) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10164) global t_inx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10165) t_inx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10166) fblt.w t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10167) fbeq.w inx2_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10169) global t_pinx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10170) t_pinx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10171) ori.w &inx2a_mask,FPSR_EXCEPT(%a6) # set INEX2/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10172) bra.b inx2_work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10174) global t_minx2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10175) t_minx2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10176) ori.l &inx2a_mask+neg_mask,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10178) inx2_work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10179) btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10180) bne.b inx2_work_ena # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10181) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10182) inx2_work_ena:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10183) fmov.l USER_FPCR(%a6),%fpcr # insert user's exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10184) fmov.s &0x3f800000,%fp1 # load +1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10185) fadd.x pls_tiny(%pc),%fp1 # cause exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10186) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10188) inx2_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10189) mov.b &z_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10190) ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX/AINEX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10191) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10193) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10194) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10195) # t_extdnrm(): Handle DENORM inputs in 060FPLSP. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10196) # t_resdnrm(): Handle DENORM inputs in 060FPLSP for "fscale". #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10197) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10198) # This routine is used by the 060FPLSP package. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10199) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10200) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10201) # None. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10202) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10203) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10204) # a0 = pointer to extended precision input operand #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10205) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10206) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10207) # fp0 = default result #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10208) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10209) # ALGORITHM *********************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10210) # For all functions that have a denormalized input and that #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10211) # f(x)=x, this is the entry point. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10212) # DENORM value is moved using "fmove" which triggers an exception #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10213) # if enabled so the operating system can log the event. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10214) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10215) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10217) global t_extdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10218) t_extdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10219) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10220) fmov.x SRC_EX(%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10221) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10222) ori.l &unfinx_mask,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10223) or.l %d0,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10224) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10226) global t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10227) t_resdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10228) fmov.l USER_FPCR(%a6),%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10229) fmov.x SRC_EX(%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10230) fmov.l %fpsr,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10231) or.l %d0,USER_FPSR(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10232) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10234) ##########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10236) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10237) # sto_cos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10238) # This is used by fsincos library emulation. The correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10239) # values are already in fp0 and fp1 so we do nothing here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10240) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10241) global sto_cos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10242) sto_cos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10243) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10245) ##########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10247) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10248) # dst_qnan --- force result when destination is a NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10249) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10250) global dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10251) dst_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10252) fmov.x DST(%a1),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10253) tst.b DST_EX(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10254) bmi.b dst_qnan_m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10255) dst_qnan_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10256) mov.b &nan_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10257) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10258) dst_qnan_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10259) mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10260) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10262) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10263) # src_qnan --- force result when source is a NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10264) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10265) global src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10266) src_qnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10267) fmov.x SRC(%a0),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10268) tst.b SRC_EX(%a0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10269) bmi.b src_qnan_m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10270) src_qnan_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10271) mov.b &nan_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10272) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10273) src_qnan_m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10274) mov.b &nan_bmask+neg_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10275) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10277) ##########################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10279) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10280) # Native instruction support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10281) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10282) # Some systems may need entry points even for 68060 native
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10283) # instructions. These routines are provided for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10284) # convenience.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10285) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10286) global _fadds_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10287) _fadds_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10288) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10289) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10290) fmov.s 0x8(%sp),%fp0 # load sgl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10291) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10292) fadd.s 0x8(%sp),%fp0 # fadd w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10293) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10295) global _faddd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10296) _faddd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10297) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10298) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10299) fmov.d 0x8(%sp),%fp0 # load dbl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10300) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10301) fadd.d 0xc(%sp),%fp0 # fadd w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10302) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10304) global _faddx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10305) _faddx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10306) fmovm.x 0x4(%sp),&0x80 # load ext dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10307) fadd.x 0x10(%sp),%fp0 # fadd w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10308) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10310) global _fsubs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10311) _fsubs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10312) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10313) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10314) fmov.s 0x8(%sp),%fp0 # load sgl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10315) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10316) fsub.s 0x8(%sp),%fp0 # fsub w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10317) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10319) global _fsubd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10320) _fsubd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10321) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10322) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10323) fmov.d 0x8(%sp),%fp0 # load dbl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10324) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10325) fsub.d 0xc(%sp),%fp0 # fsub w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10326) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10328) global _fsubx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10329) _fsubx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10330) fmovm.x 0x4(%sp),&0x80 # load ext dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10331) fsub.x 0x10(%sp),%fp0 # fsub w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10332) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10334) global _fmuls_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10335) _fmuls_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10336) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10337) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10338) fmov.s 0x8(%sp),%fp0 # load sgl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10339) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10340) fmul.s 0x8(%sp),%fp0 # fmul w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10341) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10343) global _fmuld_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10344) _fmuld_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10345) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10346) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10347) fmov.d 0x8(%sp),%fp0 # load dbl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10348) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10349) fmul.d 0xc(%sp),%fp0 # fmul w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10350) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10352) global _fmulx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10353) _fmulx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10354) fmovm.x 0x4(%sp),&0x80 # load ext dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10355) fmul.x 0x10(%sp),%fp0 # fmul w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10356) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10358) global _fdivs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10359) _fdivs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10360) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10361) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10362) fmov.s 0x8(%sp),%fp0 # load sgl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10363) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10364) fdiv.s 0x8(%sp),%fp0 # fdiv w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10365) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10367) global _fdivd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10368) _fdivd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10369) fmov.l %fpcr,-(%sp) # save fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10370) fmov.l &0x00000000,%fpcr # clear fpcr for load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10371) fmov.d 0x8(%sp),%fp0 # load dbl dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10372) fmov.l (%sp)+,%fpcr # restore fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10373) fdiv.d 0xc(%sp),%fp0 # fdiv w/ dbl src
^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) global _fdivx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10377) _fdivx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10378) fmovm.x 0x4(%sp),&0x80 # load ext dst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10379) fdiv.x 0x10(%sp),%fp0 # fdiv w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10380) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10382) global _fabss_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10383) _fabss_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10384) fabs.s 0x4(%sp),%fp0 # fabs w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10385) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10387) global _fabsd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10388) _fabsd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10389) fabs.d 0x4(%sp),%fp0 # fabs w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10390) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10392) global _fabsx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10393) _fabsx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10394) fabs.x 0x4(%sp),%fp0 # fabs w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10395) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10397) global _fnegs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10398) _fnegs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10399) fneg.s 0x4(%sp),%fp0 # fneg w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10400) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10402) global _fnegd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10403) _fnegd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10404) fneg.d 0x4(%sp),%fp0 # fneg w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10405) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10407) global _fnegx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10408) _fnegx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10409) fneg.x 0x4(%sp),%fp0 # fneg w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10410) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10412) global _fsqrts_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10413) _fsqrts_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10414) fsqrt.s 0x4(%sp),%fp0 # fsqrt w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10415) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10417) global _fsqrtd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10418) _fsqrtd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10419) fsqrt.d 0x4(%sp),%fp0 # fsqrt w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10420) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10422) global _fsqrtx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10423) _fsqrtx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10424) fsqrt.x 0x4(%sp),%fp0 # fsqrt w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10425) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10427) global _fints_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10428) _fints_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10429) fint.s 0x4(%sp),%fp0 # fint w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10430) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10432) global _fintd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10433) _fintd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10434) fint.d 0x4(%sp),%fp0 # fint w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10435) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10437) global _fintx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10438) _fintx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10439) fint.x 0x4(%sp),%fp0 # fint w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10440) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10442) global _fintrzs_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10443) _fintrzs_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10444) fintrz.s 0x4(%sp),%fp0 # fintrz w/ sgl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10445) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10447) global _fintrzd_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10448) _fintrzd_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10449) fintrz.d 0x4(%sp),%fp0 # fintrx w/ dbl src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10450) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10452) global _fintrzx_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10453) _fintrzx_:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10454) fintrz.x 0x4(%sp),%fp0 # fintrz w/ ext src
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10455) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10457) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10459) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10460) # src_zero(): Return signed zero according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10461) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10462) global src_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10463) src_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10464) tst.b SRC_EX(%a0) # get sign of src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10465) bmi.b ld_mzero # if neg, load neg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10467) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10468) # ld_pzero(): return a positive zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10469) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10470) global ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10471) ld_pzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10472) fmov.s &0x00000000,%fp0 # load +0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10473) mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10474) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10476) # ld_mzero(): return a negative zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10477) global ld_mzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10478) ld_mzero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10479) fmov.s &0x80000000,%fp0 # load -0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10480) mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10481) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10483) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10484) # dst_zero(): Return signed zero according to sign of dst operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10485) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10486) global dst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10487) dst_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10488) tst.b DST_EX(%a1) # get sign of dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10489) bmi.b ld_mzero # if neg, load neg zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10490) bra.b ld_pzero # load positive zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10492) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10493) # src_inf(): Return signed inf according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10494) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10495) global src_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10496) src_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10497) tst.b SRC_EX(%a0) # get sign of src operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10498) bmi.b ld_minf # if negative branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10500) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10501) # ld_pinf(): return a positive infinity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10502) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10503) global ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10504) ld_pinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10505) fmov.s &0x7f800000,%fp0 # load +INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10506) mov.b &inf_bmask,FPSR_CC(%a6) # set 'INF' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10507) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10509) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10510) # ld_minf():return a negative infinity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10511) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10512) global ld_minf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10513) ld_minf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10514) fmov.s &0xff800000,%fp0 # load -INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10515) mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10516) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10518) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10519) # dst_inf(): Return signed inf according to sign of dst operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10520) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10521) global dst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10522) dst_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10523) tst.b DST_EX(%a1) # get sign of dst operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10524) bmi.b ld_minf # if negative branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10525) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10527) global szr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10528) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10529) # szr_inf(): Return +ZERO for a negative src operand or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10530) # +INF for a positive src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10531) # Routine used for fetox, ftwotox, and ftentox. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10532) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10533) szr_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10534) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10535) bmi.b ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10536) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10538) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10539) # sopr_inf(): Return +INF for a positive src operand or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10540) # jump to operand error routine for a negative src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10541) # Routine used for flogn, flognp1, flog10, and flog2. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10542) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10543) global sopr_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10544) sopr_inf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10545) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10546) bmi.w t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10547) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10549) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10550) # setoxm1i(): Return minus one for a negative src operand or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10551) # positive infinity for a positive src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10552) # Routine used for fetoxm1. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10553) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10554) global setoxm1i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10555) setoxm1i:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10556) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10557) bmi.b ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10558) bra.b ld_pinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10560) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10561) # src_one(): Return signed one according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10562) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10563) global src_one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10564) src_one:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10565) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10566) bmi.b ld_mone
^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) # ld_pone(): return positive one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10570) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10571) global ld_pone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10572) ld_pone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10573) fmov.s &0x3f800000,%fp0 # load +1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10574) clr.b FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10575) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10577) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10578) # ld_mone(): return negative one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10579) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10580) global ld_mone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10581) ld_mone:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10582) fmov.s &0xbf800000,%fp0 # load -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10583) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10584) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10586) ppiby2: long 0x3fff0000, 0xc90fdaa2, 0x2168c235
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10587) mpiby2: long 0xbfff0000, 0xc90fdaa2, 0x2168c235
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10589) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10590) # spi_2(): Return signed PI/2 according to sign of src operand. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10591) #################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10592) global spi_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10593) spi_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10594) tst.b SRC_EX(%a0) # check sign of source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10595) bmi.b ld_mpi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10597) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10598) # ld_ppi2(): return positive PI/2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10599) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10600) global ld_ppi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10601) ld_ppi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10602) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10603) fmov.x ppiby2(%pc),%fp0 # load +pi/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10604) bra.w t_pinx2 # set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10606) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10607) # ld_mpi2(): return negative PI/2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10608) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10609) global ld_mpi2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10610) ld_mpi2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10611) fmov.l %d0,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10612) fmov.x mpiby2(%pc),%fp0 # load -pi/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10613) bra.w t_minx2 # set INEX2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10615) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10616) # The following routines give support for fsincos. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10617) ####################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10619) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10620) # ssincosz(): When the src operand is ZERO, store a one in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10621) # cosine register and return a ZERO in fp0 w/ the same sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10622) # as the src operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10623) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10624) global ssincosz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10625) ssincosz:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10626) fmov.s &0x3f800000,%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10627) tst.b SRC_EX(%a0) # test sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10628) bpl.b sincoszp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10629) fmov.s &0x80000000,%fp0 # return sin result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10630) mov.b &z_bmask+neg_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10631) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10632) sincoszp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10633) fmov.s &0x00000000,%fp0 # return sin result in fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10634) mov.b &z_bmask,FPSR_CC(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10635) rts
^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) # ssincosi(): When the src operand is INF, store a QNAN in the cosine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10639) # register and jump to the operand error routine for negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10640) # src operands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10641) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10642) global ssincosi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10643) ssincosi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10644) fmov.x qnan(%pc),%fp1 # load NAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10645) bra.w t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10647) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10648) # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10649) # register and branch to the src QNAN routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10650) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10651) global ssincosqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10652) ssincosqnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10653) fmov.x LOCAL_EX(%a0),%fp1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10654) bra.w src_qnan
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10658) global smod_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10659) global smod_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10660) smod_sdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10661) smod_snorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10662) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10663) beq.l smod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10664) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10665) beq.w smod_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10666) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10667) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10668) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10669) beq.l smod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10670) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10672) global smod_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10673) smod_szero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10674) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10675) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10676) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10677) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10678) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10679) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10680) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10681) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10682) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10684) global smod_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10685) smod_sinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10686) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10687) beq.l smod_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10688) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10689) beq.l smod_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10690) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10691) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10692) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10693) beq.l smod_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10694) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10696) smod_zro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10697) srem_zro:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10698) mov.b SRC_EX(%a0),%d1 # get src sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10699) mov.b DST_EX(%a1),%d0 # get dst sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10700) eor.b %d0,%d1 # get qbyte sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10701) andi.b &0x80,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10702) mov.b %d1,FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10703) tst.b %d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10704) bpl.w ld_pzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10705) bra.w ld_mzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10707) smod_fpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10708) srem_fpn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10709) clr.b FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10710) mov.l %d0,-(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10711) mov.b SRC_EX(%a0),%d1 # get src sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10712) mov.b DST_EX(%a1),%d0 # get dst sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10713) eor.b %d0,%d1 # get qbyte sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10714) andi.b &0x80,%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10715) mov.b %d1,FPSR_QBYTE(%a6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10716) cmpi.b DTAG(%a6),&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10717) bne.b smod_nrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10718) lea DST(%a1),%a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10719) mov.l (%sp)+,%d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10720) bra t_resdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10721) smod_nrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10722) fmov.l (%sp)+,%fpcr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10723) fmov.x DST(%a1),%fp0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10724) tst.b DST_EX(%a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10725) bmi.b smod_nrm_neg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10726) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10728) smod_nrm_neg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10729) mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10730) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10732) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10733) global srem_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10734) global srem_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10735) srem_sdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10736) srem_snorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10737) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10738) beq.l srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10739) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10740) beq.w srem_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10741) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10742) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10743) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10744) beq.l srem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10745) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10747) global srem_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10748) srem_szero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10749) mov.b DTAG(%a6),%d1
^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,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10752) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10753) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10754) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10755) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10756) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10757) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10759) global srem_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10760) srem_sinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10761) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10762) beq.w srem_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10763) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10764) beq.w srem_zro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10765) cmpi.b %d1,&INF
^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,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10768) beq.l srem_fpn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10769) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10771) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10773) global sscale_snorm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10774) global sscale_sdnrm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10775) sscale_snorm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10776) sscale_sdnrm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10777) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10778) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10779) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10780) beq.l dst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10781) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10782) beq.l dst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10783) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10784) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10785) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10787) global sscale_szero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10788) sscale_szero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10789) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10790) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10791) cmpi.b %d1,&ZERO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10792) beq.l dst_zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10793) cmpi.b %d1,&INF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10794) beq.l dst_inf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10795) cmpi.b %d1,&DENORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10796) beq.l sscale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10797) bra.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10799) global sscale_sinf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10800) sscale_sinf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10801) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10802) beq.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10803) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10804) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10805) bra.l t_operr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10807) ########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10809) global sop_sqnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10810) sop_sqnan:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10811) mov.b DTAG(%a6),%d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10812) cmpi.b %d1,&QNAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10813) beq.l dst_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10814) bra.l src_qnan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10816) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10817) # norm(): normalize the mantissa of an extended precision input. the #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10818) # input operand should not be normalized already. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10819) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10820) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10821) # norm() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10822) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10823) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10824) # none #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10825) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10826) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10827) # a0 = pointer fp extended precision operand to normalize #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10828) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10829) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10830) # d0 = number of bit positions the mantissa was shifted #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10831) # a0 = the input operand's mantissa is normalized; the exponent #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10832) # is unchanged. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10833) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10834) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10835) global norm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10836) norm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10837) mov.l %d2, -(%sp) # create some temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10838) mov.l %d3, -(%sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10840) mov.l FTEMP_HI(%a0), %d0 # load hi(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10841) mov.l FTEMP_LO(%a0), %d1 # load lo(mantissa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10843) bfffo %d0{&0:&32}, %d2 # how many places to shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10844) beq.b norm_lo # hi(man) is all zeroes!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10846) norm_hi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10847) lsl.l %d2, %d0 # left shift hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10848) bfextu %d1{&0:%d2}, %d3 # extract lo bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10850) or.l %d3, %d0 # create hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10851) lsl.l %d2, %d1 # create lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10853) mov.l %d0, FTEMP_HI(%a0) # store new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10854) mov.l %d1, FTEMP_LO(%a0) # store new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10856) mov.l %d2, %d0 # return shift amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10858) mov.l (%sp)+, %d3 # restore temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10859) mov.l (%sp)+, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10861) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10863) norm_lo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10864) bfffo %d1{&0:&32}, %d2 # how many places to shift?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10865) lsl.l %d2, %d1 # shift lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10866) add.l &32, %d2 # add 32 to shft amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10868) mov.l %d1, FTEMP_HI(%a0) # store hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10869) clr.l FTEMP_LO(%a0) # lo(man) is now zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10871) mov.l %d2, %d0 # return shift amount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10873) mov.l (%sp)+, %d3 # restore temp regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10874) mov.l (%sp)+, %d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10876) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10878) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10879) # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10880) # - returns corresponding optype tag #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10881) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10882) # XDEF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10883) # unnorm_fix() #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10884) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10885) # XREF **************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10886) # norm() - normalize the mantissa #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10887) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10888) # INPUT *************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10889) # a0 = pointer to unnormalized extended precision number #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10890) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10891) # OUTPUT ************************************************************** #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10892) # d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10893) # a0 = input operand has been converted to a norm, denorm, or #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10894) # zero; both the exponent and mantissa are changed. #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10895) # #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10896) #########################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10898) global unnorm_fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10899) unnorm_fix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10900) bfffo FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10901) bne.b unnorm_shift # hi(man) is not all zeroes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10903) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10904) # hi(man) is all zeroes so see if any bits in lo(man) are set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10905) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10906) unnorm_chk_lo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10907) bfffo FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10908) beq.w unnorm_zero # yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10910) add.w &32, %d0 # no; fix shift distance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10912) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10913) # d0 = # shifts needed for complete normalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10914) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10915) unnorm_shift:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10916) clr.l %d1 # clear top word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10917) mov.w FTEMP_EX(%a0), %d1 # extract exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10918) and.w &0x7fff, %d1 # strip off sgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10920) cmp.w %d0, %d1 # will denorm push exp < 0?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10921) bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10923) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10924) # exponent would not go < 0. therefore, number stays normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10925) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10926) sub.w %d0, %d1 # shift exponent value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10927) mov.w FTEMP_EX(%a0), %d0 # load old exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10928) and.w &0x8000, %d0 # save old sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10929) or.w %d0, %d1 # {sgn,new exp}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10930) mov.w %d1, FTEMP_EX(%a0) # insert new exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10932) bsr.l norm # normalize UNNORM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10934) mov.b &NORM, %d0 # return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10935) rts
^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) # exponent would go < 0, so only denormalize until exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10939) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10940) unnorm_nrm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10941) cmp.b %d1, &32 # is exp <= 32?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10942) bgt.b unnorm_nrm_zero_lrg # no; go handle large exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10944) bfextu FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10945) mov.l %d0, FTEMP_HI(%a0) # save new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10947) mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10948) lsl.l %d1, %d0 # extract new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10949) mov.l %d0, FTEMP_LO(%a0) # save new lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10951) and.w &0x8000, FTEMP_EX(%a0) # set exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10953) mov.b &DENORM, %d0 # return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10954) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10956) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10957) # only mantissa bits set are in lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10958) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10959) unnorm_nrm_zero_lrg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10960) sub.w &32, %d1 # adjust shft amt by 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10962) mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10963) lsl.l %d1, %d0 # left shift lo(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10965) mov.l %d0, FTEMP_HI(%a0) # store new hi(man)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10966) clr.l FTEMP_LO(%a0) # lo(man) = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10968) and.w &0x8000, FTEMP_EX(%a0) # set exp = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10970) mov.b &DENORM, %d0 # return new optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10971) rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10973) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10974) # whole mantissa is zero so this UNNORM is actually a zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10975) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10976) unnorm_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10977) and.w &0x8000, FTEMP_EX(%a0) # force exponent to zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10979) mov.b &ZERO, %d0 # fix optype tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10980) rts