1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GR 2 MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 3 M68000 Hi-Performance Microprocessor Division 3 M68000 Hi-Performance Microprocessor Division 4 M68060 Software Package 4 M68060 Software Package 5 Production Release P1.00 -- October 10, 1994 5 Production Release P1.00 -- October 10, 1994 6 6 7 M68060 Software Package Copyright © 1993, 199 7 M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved. 8 8 9 THE SOFTWARE is provided on an "AS IS" basis a 9 THE SOFTWARE is provided on an "AS IS" basis and without warranty. 10 To the maximum extent permitted by applicable 10 To the maximum extent permitted by applicable law, 11 MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPR 11 MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 12 INCLUDING IMPLIED WARRANTIES OF MERCHANTABILIT 12 INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 13 and any warranty against infringement with reg 13 and any warranty against infringement with regard to the SOFTWARE 14 (INCLUDING ANY MODIFIED VERSIONS THEREOF) and 14 (INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials. 15 15 16 To the maximum extent permitted by applicable 16 To the maximum extent permitted by applicable law, 17 IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY D 17 IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 18 (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOS 18 (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 19 BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORM 19 BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) 20 ARISING OF THE USE OR INABILITY TO USE THE SOF 20 ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. 21 Motorola assumes no responsibility for the mai 21 Motorola assumes no responsibility for the maintenance and support of the SOFTWARE. 22 22 23 You are hereby granted a copyright license to 23 You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE 24 so long as this entire notice is retained with 24 so long as this entire notice is retained without alteration in any modified and/or 25 redistributed versions, and that such modified 25 redistributed versions, and that such modified versions are clearly identified as such. 26 No licenses are granted by implication, estopp 26 No licenses are granted by implication, estoppel or otherwise under any patents 27 or trademarks of Motorola, Inc. 27 or trademarks of Motorola, Inc. 28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 29 # 29 # 30 # freal.s: 30 # freal.s: 31 # This file is appended to the top of th 31 # This file is appended to the top of the 060FPSP package 32 # and contains the entry points into the packa 32 # and contains the entry points into the package. The user, in 33 # effect, branches to one of the branch table 33 # effect, branches to one of the branch table entries located 34 # after _060FPSP_TABLE. 34 # after _060FPSP_TABLE. 35 # Also, subroutine stubs exist in this f 35 # Also, subroutine stubs exist in this file (_fpsp_done for 36 # example) that are referenced by the FPSP pac 36 # example) that are referenced by the FPSP package itself in order 37 # to call a given routine. The stub routine ac 37 # to call a given routine. The stub routine actually performs the 38 # callout. The FPSP code does a "bsr" to the s 38 # callout. The FPSP code does a "bsr" to the stub routine. This 39 # extra layer of hierarchy adds a slight perfo 39 # extra layer of hierarchy adds a slight performance penalty but 40 # it makes the FPSP code easier to read and mo 40 # it makes the FPSP code easier to read and more mainatinable. 41 # 41 # 42 42 43 set _off_bsun, 0x00 43 set _off_bsun, 0x00 44 set _off_snan, 0x04 44 set _off_snan, 0x04 45 set _off_operr, 0x08 45 set _off_operr, 0x08 46 set _off_ovfl, 0x0c 46 set _off_ovfl, 0x0c 47 set _off_unfl, 0x10 47 set _off_unfl, 0x10 48 set _off_dz, 0x14 48 set _off_dz, 0x14 49 set _off_inex, 0x18 49 set _off_inex, 0x18 50 set _off_fline, 0x1c 50 set _off_fline, 0x1c 51 set _off_fpu_dis, 0x20 51 set _off_fpu_dis, 0x20 52 set _off_trap, 0x24 52 set _off_trap, 0x24 53 set _off_trace, 0x28 53 set _off_trace, 0x28 54 set _off_access, 0x2c 54 set _off_access, 0x2c 55 set _off_done, 0x30 55 set _off_done, 0x30 56 56 57 set _off_imr, 0x40 57 set _off_imr, 0x40 58 set _off_dmr, 0x44 58 set _off_dmr, 0x44 59 set _off_dmw, 0x48 59 set _off_dmw, 0x48 60 set _off_irw, 0x4c 60 set _off_irw, 0x4c 61 set _off_irl, 0x50 61 set _off_irl, 0x50 62 set _off_drb, 0x54 62 set _off_drb, 0x54 63 set _off_drw, 0x58 63 set _off_drw, 0x58 64 set _off_drl, 0x5c 64 set _off_drl, 0x5c 65 set _off_dwb, 0x60 65 set _off_dwb, 0x60 66 set _off_dww, 0x64 66 set _off_dww, 0x64 67 set _off_dwl, 0x68 67 set _off_dwl, 0x68 68 68 69 _060FPSP_TABLE: 69 _060FPSP_TABLE: 70 70 71 ############################################## 71 ############################################################### 72 72 73 # Here's the table of ENTRY POINTS for those l 73 # Here's the table of ENTRY POINTS for those linking the package. 74 bra.l _fpsp_snan 74 bra.l _fpsp_snan 75 short 0x0000 75 short 0x0000 76 bra.l _fpsp_operr 76 bra.l _fpsp_operr 77 short 0x0000 77 short 0x0000 78 bra.l _fpsp_ovfl 78 bra.l _fpsp_ovfl 79 short 0x0000 79 short 0x0000 80 bra.l _fpsp_unfl 80 bra.l _fpsp_unfl 81 short 0x0000 81 short 0x0000 82 bra.l _fpsp_dz 82 bra.l _fpsp_dz 83 short 0x0000 83 short 0x0000 84 bra.l _fpsp_inex 84 bra.l _fpsp_inex 85 short 0x0000 85 short 0x0000 86 bra.l _fpsp_fline 86 bra.l _fpsp_fline 87 short 0x0000 87 short 0x0000 88 bra.l _fpsp_unsupp 88 bra.l _fpsp_unsupp 89 short 0x0000 89 short 0x0000 90 bra.l _fpsp_effadd 90 bra.l _fpsp_effadd 91 short 0x0000 91 short 0x0000 92 92 93 space 56 93 space 56 94 94 95 ############################################## 95 ############################################################### 96 global _fpsp_done 96 global _fpsp_done 97 _fpsp_done: 97 _fpsp_done: 98 mov.l %d0,-(%sp) 98 mov.l %d0,-(%sp) 99 mov.l (_060FPSP_TABLE-0x80+_ 99 mov.l (_060FPSP_TABLE-0x80+_off_done,%pc),%d0 100 pea.l (_060FPSP_TABLE-0x80,% 100 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 101 mov.l 0x4(%sp),%d0 101 mov.l 0x4(%sp),%d0 102 rtd &0x4 102 rtd &0x4 103 103 104 global _real_ovfl 104 global _real_ovfl 105 _real_ovfl: 105 _real_ovfl: 106 mov.l %d0,-(%sp) 106 mov.l %d0,-(%sp) 107 mov.l (_060FPSP_TABLE-0x80+_ 107 mov.l (_060FPSP_TABLE-0x80+_off_ovfl,%pc),%d0 108 pea.l (_060FPSP_TABLE-0x80,% 108 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 109 mov.l 0x4(%sp),%d0 109 mov.l 0x4(%sp),%d0 110 rtd &0x4 110 rtd &0x4 111 111 112 global _real_unfl 112 global _real_unfl 113 _real_unfl: 113 _real_unfl: 114 mov.l %d0,-(%sp) 114 mov.l %d0,-(%sp) 115 mov.l (_060FPSP_TABLE-0x80+_ 115 mov.l (_060FPSP_TABLE-0x80+_off_unfl,%pc),%d0 116 pea.l (_060FPSP_TABLE-0x80,% 116 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 117 mov.l 0x4(%sp),%d0 117 mov.l 0x4(%sp),%d0 118 rtd &0x4 118 rtd &0x4 119 119 120 global _real_inex 120 global _real_inex 121 _real_inex: 121 _real_inex: 122 mov.l %d0,-(%sp) 122 mov.l %d0,-(%sp) 123 mov.l (_060FPSP_TABLE-0x80+_ 123 mov.l (_060FPSP_TABLE-0x80+_off_inex,%pc),%d0 124 pea.l (_060FPSP_TABLE-0x80,% 124 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 125 mov.l 0x4(%sp),%d0 125 mov.l 0x4(%sp),%d0 126 rtd &0x4 126 rtd &0x4 127 127 128 global _real_bsun 128 global _real_bsun 129 _real_bsun: 129 _real_bsun: 130 mov.l %d0,-(%sp) 130 mov.l %d0,-(%sp) 131 mov.l (_060FPSP_TABLE-0x80+_ 131 mov.l (_060FPSP_TABLE-0x80+_off_bsun,%pc),%d0 132 pea.l (_060FPSP_TABLE-0x80,% 132 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 133 mov.l 0x4(%sp),%d0 133 mov.l 0x4(%sp),%d0 134 rtd &0x4 134 rtd &0x4 135 135 136 global _real_operr 136 global _real_operr 137 _real_operr: 137 _real_operr: 138 mov.l %d0,-(%sp) 138 mov.l %d0,-(%sp) 139 mov.l (_060FPSP_TABLE-0x80+_ 139 mov.l (_060FPSP_TABLE-0x80+_off_operr,%pc),%d0 140 pea.l (_060FPSP_TABLE-0x80,% 140 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 141 mov.l 0x4(%sp),%d0 141 mov.l 0x4(%sp),%d0 142 rtd &0x4 142 rtd &0x4 143 143 144 global _real_snan 144 global _real_snan 145 _real_snan: 145 _real_snan: 146 mov.l %d0,-(%sp) 146 mov.l %d0,-(%sp) 147 mov.l (_060FPSP_TABLE-0x80+_ 147 mov.l (_060FPSP_TABLE-0x80+_off_snan,%pc),%d0 148 pea.l (_060FPSP_TABLE-0x80,% 148 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 149 mov.l 0x4(%sp),%d0 149 mov.l 0x4(%sp),%d0 150 rtd &0x4 150 rtd &0x4 151 151 152 global _real_dz 152 global _real_dz 153 _real_dz: 153 _real_dz: 154 mov.l %d0,-(%sp) 154 mov.l %d0,-(%sp) 155 mov.l (_060FPSP_TABLE-0x80+_ 155 mov.l (_060FPSP_TABLE-0x80+_off_dz,%pc),%d0 156 pea.l (_060FPSP_TABLE-0x80,% 156 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 157 mov.l 0x4(%sp),%d0 157 mov.l 0x4(%sp),%d0 158 rtd &0x4 158 rtd &0x4 159 159 160 global _real_fline 160 global _real_fline 161 _real_fline: 161 _real_fline: 162 mov.l %d0,-(%sp) 162 mov.l %d0,-(%sp) 163 mov.l (_060FPSP_TABLE-0x80+_ 163 mov.l (_060FPSP_TABLE-0x80+_off_fline,%pc),%d0 164 pea.l (_060FPSP_TABLE-0x80,% 164 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 165 mov.l 0x4(%sp),%d0 165 mov.l 0x4(%sp),%d0 166 rtd &0x4 166 rtd &0x4 167 167 168 global _real_fpu_disabled 168 global _real_fpu_disabled 169 _real_fpu_disabled: 169 _real_fpu_disabled: 170 mov.l %d0,-(%sp) 170 mov.l %d0,-(%sp) 171 mov.l (_060FPSP_TABLE-0x80+_ 171 mov.l (_060FPSP_TABLE-0x80+_off_fpu_dis,%pc),%d0 172 pea.l (_060FPSP_TABLE-0x80,% 172 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 173 mov.l 0x4(%sp),%d0 173 mov.l 0x4(%sp),%d0 174 rtd &0x4 174 rtd &0x4 175 175 176 global _real_trap 176 global _real_trap 177 _real_trap: 177 _real_trap: 178 mov.l %d0,-(%sp) 178 mov.l %d0,-(%sp) 179 mov.l (_060FPSP_TABLE-0x80+_ 179 mov.l (_060FPSP_TABLE-0x80+_off_trap,%pc),%d0 180 pea.l (_060FPSP_TABLE-0x80,% 180 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 181 mov.l 0x4(%sp),%d0 181 mov.l 0x4(%sp),%d0 182 rtd &0x4 182 rtd &0x4 183 183 184 global _real_trace 184 global _real_trace 185 _real_trace: 185 _real_trace: 186 mov.l %d0,-(%sp) 186 mov.l %d0,-(%sp) 187 mov.l (_060FPSP_TABLE-0x80+_ 187 mov.l (_060FPSP_TABLE-0x80+_off_trace,%pc),%d0 188 pea.l (_060FPSP_TABLE-0x80,% 188 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 189 mov.l 0x4(%sp),%d0 189 mov.l 0x4(%sp),%d0 190 rtd &0x4 190 rtd &0x4 191 191 192 global _real_access 192 global _real_access 193 _real_access: 193 _real_access: 194 mov.l %d0,-(%sp) 194 mov.l %d0,-(%sp) 195 mov.l (_060FPSP_TABLE-0x80+_ 195 mov.l (_060FPSP_TABLE-0x80+_off_access,%pc),%d0 196 pea.l (_060FPSP_TABLE-0x80,% 196 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 197 mov.l 0x4(%sp),%d0 197 mov.l 0x4(%sp),%d0 198 rtd &0x4 198 rtd &0x4 199 199 200 ####################################### 200 ####################################### 201 201 202 global _imem_read 202 global _imem_read 203 _imem_read: 203 _imem_read: 204 mov.l %d0,-(%sp) 204 mov.l %d0,-(%sp) 205 mov.l (_060FPSP_TABLE-0x80+_ 205 mov.l (_060FPSP_TABLE-0x80+_off_imr,%pc),%d0 206 pea.l (_060FPSP_TABLE-0x80,% 206 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 207 mov.l 0x4(%sp),%d0 207 mov.l 0x4(%sp),%d0 208 rtd &0x4 208 rtd &0x4 209 209 210 global _dmem_read 210 global _dmem_read 211 _dmem_read: 211 _dmem_read: 212 mov.l %d0,-(%sp) 212 mov.l %d0,-(%sp) 213 mov.l (_060FPSP_TABLE-0x80+_ 213 mov.l (_060FPSP_TABLE-0x80+_off_dmr,%pc),%d0 214 pea.l (_060FPSP_TABLE-0x80,% 214 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 215 mov.l 0x4(%sp),%d0 215 mov.l 0x4(%sp),%d0 216 rtd &0x4 216 rtd &0x4 217 217 218 global _dmem_write 218 global _dmem_write 219 _dmem_write: 219 _dmem_write: 220 mov.l %d0,-(%sp) 220 mov.l %d0,-(%sp) 221 mov.l (_060FPSP_TABLE-0x80+_ 221 mov.l (_060FPSP_TABLE-0x80+_off_dmw,%pc),%d0 222 pea.l (_060FPSP_TABLE-0x80,% 222 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 223 mov.l 0x4(%sp),%d0 223 mov.l 0x4(%sp),%d0 224 rtd &0x4 224 rtd &0x4 225 225 226 global _imem_read_word 226 global _imem_read_word 227 _imem_read_word: 227 _imem_read_word: 228 mov.l %d0,-(%sp) 228 mov.l %d0,-(%sp) 229 mov.l (_060FPSP_TABLE-0x80+_ 229 mov.l (_060FPSP_TABLE-0x80+_off_irw,%pc),%d0 230 pea.l (_060FPSP_TABLE-0x80,% 230 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 231 mov.l 0x4(%sp),%d0 231 mov.l 0x4(%sp),%d0 232 rtd &0x4 232 rtd &0x4 233 233 234 global _imem_read_long 234 global _imem_read_long 235 _imem_read_long: 235 _imem_read_long: 236 mov.l %d0,-(%sp) 236 mov.l %d0,-(%sp) 237 mov.l (_060FPSP_TABLE-0x80+_ 237 mov.l (_060FPSP_TABLE-0x80+_off_irl,%pc),%d0 238 pea.l (_060FPSP_TABLE-0x80,% 238 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 239 mov.l 0x4(%sp),%d0 239 mov.l 0x4(%sp),%d0 240 rtd &0x4 240 rtd &0x4 241 241 242 global _dmem_read_byte 242 global _dmem_read_byte 243 _dmem_read_byte: 243 _dmem_read_byte: 244 mov.l %d0,-(%sp) 244 mov.l %d0,-(%sp) 245 mov.l (_060FPSP_TABLE-0x80+_ 245 mov.l (_060FPSP_TABLE-0x80+_off_drb,%pc),%d0 246 pea.l (_060FPSP_TABLE-0x80,% 246 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 247 mov.l 0x4(%sp),%d0 247 mov.l 0x4(%sp),%d0 248 rtd &0x4 248 rtd &0x4 249 249 250 global _dmem_read_word 250 global _dmem_read_word 251 _dmem_read_word: 251 _dmem_read_word: 252 mov.l %d0,-(%sp) 252 mov.l %d0,-(%sp) 253 mov.l (_060FPSP_TABLE-0x80+_ 253 mov.l (_060FPSP_TABLE-0x80+_off_drw,%pc),%d0 254 pea.l (_060FPSP_TABLE-0x80,% 254 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 255 mov.l 0x4(%sp),%d0 255 mov.l 0x4(%sp),%d0 256 rtd &0x4 256 rtd &0x4 257 257 258 global _dmem_read_long 258 global _dmem_read_long 259 _dmem_read_long: 259 _dmem_read_long: 260 mov.l %d0,-(%sp) 260 mov.l %d0,-(%sp) 261 mov.l (_060FPSP_TABLE-0x80+_ 261 mov.l (_060FPSP_TABLE-0x80+_off_drl,%pc),%d0 262 pea.l (_060FPSP_TABLE-0x80,% 262 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 263 mov.l 0x4(%sp),%d0 263 mov.l 0x4(%sp),%d0 264 rtd &0x4 264 rtd &0x4 265 265 266 global _dmem_write_byte 266 global _dmem_write_byte 267 _dmem_write_byte: 267 _dmem_write_byte: 268 mov.l %d0,-(%sp) 268 mov.l %d0,-(%sp) 269 mov.l (_060FPSP_TABLE-0x80+_ 269 mov.l (_060FPSP_TABLE-0x80+_off_dwb,%pc),%d0 270 pea.l (_060FPSP_TABLE-0x80,% 270 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 271 mov.l 0x4(%sp),%d0 271 mov.l 0x4(%sp),%d0 272 rtd &0x4 272 rtd &0x4 273 273 274 global _dmem_write_word 274 global _dmem_write_word 275 _dmem_write_word: 275 _dmem_write_word: 276 mov.l %d0,-(%sp) 276 mov.l %d0,-(%sp) 277 mov.l (_060FPSP_TABLE-0x80+_ 277 mov.l (_060FPSP_TABLE-0x80+_off_dww,%pc),%d0 278 pea.l (_060FPSP_TABLE-0x80,% 278 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 279 mov.l 0x4(%sp),%d0 279 mov.l 0x4(%sp),%d0 280 rtd &0x4 280 rtd &0x4 281 281 282 global _dmem_write_long 282 global _dmem_write_long 283 _dmem_write_long: 283 _dmem_write_long: 284 mov.l %d0,-(%sp) 284 mov.l %d0,-(%sp) 285 mov.l (_060FPSP_TABLE-0x80+_ 285 mov.l (_060FPSP_TABLE-0x80+_off_dwl,%pc),%d0 286 pea.l (_060FPSP_TABLE-0x80,% 286 pea.l (_060FPSP_TABLE-0x80,%pc,%d0) 287 mov.l 0x4(%sp),%d0 287 mov.l 0x4(%sp),%d0 288 rtd &0x4 288 rtd &0x4 289 289 290 # 290 # 291 # This file contains a set of define statement 291 # This file contains a set of define statements for constants 292 # in order to promote readability within the c 292 # in order to promote readability within the corecode itself. 293 # 293 # 294 294 295 set LOCAL_SIZE, 192 295 set LOCAL_SIZE, 192 # stack frame size(bytes) 296 set LV, -LOCAL_SIZE 296 set LV, -LOCAL_SIZE # stack offset 297 297 298 set EXC_SR, 0x4 298 set EXC_SR, 0x4 # stack status register 299 set EXC_PC, 0x6 299 set EXC_PC, 0x6 # stack pc 300 set EXC_VOFF, 0xa 300 set EXC_VOFF, 0xa # stacked vector offset 301 set EXC_EA, 0xc 301 set EXC_EA, 0xc # stacked <ea> 302 302 303 set EXC_FP, 0x0 303 set EXC_FP, 0x0 # frame pointer 304 304 305 set EXC_AREGS, -68 305 set EXC_AREGS, -68 # offset of all address regs 306 set EXC_DREGS, -100 306 set EXC_DREGS, -100 # offset of all data regs 307 set EXC_FPREGS, -36 307 set EXC_FPREGS, -36 # offset of all fp regs 308 308 309 set EXC_A7, EXC_AREGS+(7*4) 309 set EXC_A7, EXC_AREGS+(7*4) # offset of saved a7 310 set OLD_A7, EXC_AREGS+(6*4) 310 set OLD_A7, EXC_AREGS+(6*4) # extra copy of saved a7 311 set EXC_A6, EXC_AREGS+(6*4) 311 set EXC_A6, EXC_AREGS+(6*4) # offset of saved a6 312 set EXC_A5, EXC_AREGS+(5*4) 312 set EXC_A5, EXC_AREGS+(5*4) 313 set EXC_A4, EXC_AREGS+(4*4) 313 set EXC_A4, EXC_AREGS+(4*4) 314 set EXC_A3, EXC_AREGS+(3*4) 314 set EXC_A3, EXC_AREGS+(3*4) 315 set EXC_A2, EXC_AREGS+(2*4) 315 set EXC_A2, EXC_AREGS+(2*4) 316 set EXC_A1, EXC_AREGS+(1*4) 316 set EXC_A1, EXC_AREGS+(1*4) 317 set EXC_A0, EXC_AREGS+(0*4) 317 set EXC_A0, EXC_AREGS+(0*4) 318 set EXC_D7, EXC_DREGS+(7*4) 318 set EXC_D7, EXC_DREGS+(7*4) 319 set EXC_D6, EXC_DREGS+(6*4) 319 set EXC_D6, EXC_DREGS+(6*4) 320 set EXC_D5, EXC_DREGS+(5*4) 320 set EXC_D5, EXC_DREGS+(5*4) 321 set EXC_D4, EXC_DREGS+(4*4) 321 set EXC_D4, EXC_DREGS+(4*4) 322 set EXC_D3, EXC_DREGS+(3*4) 322 set EXC_D3, EXC_DREGS+(3*4) 323 set EXC_D2, EXC_DREGS+(2*4) 323 set EXC_D2, EXC_DREGS+(2*4) 324 set EXC_D1, EXC_DREGS+(1*4) 324 set EXC_D1, EXC_DREGS+(1*4) 325 set EXC_D0, EXC_DREGS+(0*4) 325 set EXC_D0, EXC_DREGS+(0*4) 326 326 327 set EXC_FP0, EXC_FPREGS+(0*12) 327 set EXC_FP0, EXC_FPREGS+(0*12) # offset of saved fp0 328 set EXC_FP1, EXC_FPREGS+(1*12) 328 set EXC_FP1, EXC_FPREGS+(1*12) # offset of saved fp1 329 set EXC_FP2, EXC_FPREGS+(2*12) 329 set EXC_FP2, EXC_FPREGS+(2*12) # offset of saved fp2 (not used) 330 330 331 set FP_SCR1, LV+80 331 set FP_SCR1, LV+80 # fp scratch 1 332 set FP_SCR1_EX, FP_SCR1+0 332 set FP_SCR1_EX, FP_SCR1+0 333 set FP_SCR1_SGN, FP_SCR1+2 333 set FP_SCR1_SGN, FP_SCR1+2 334 set FP_SCR1_HI, FP_SCR1+4 334 set FP_SCR1_HI, FP_SCR1+4 335 set FP_SCR1_LO, FP_SCR1+8 335 set FP_SCR1_LO, FP_SCR1+8 336 336 337 set FP_SCR0, LV+68 337 set FP_SCR0, LV+68 # fp scratch 0 338 set FP_SCR0_EX, FP_SCR0+0 338 set FP_SCR0_EX, FP_SCR0+0 339 set FP_SCR0_SGN, FP_SCR0+2 339 set FP_SCR0_SGN, FP_SCR0+2 340 set FP_SCR0_HI, FP_SCR0+4 340 set FP_SCR0_HI, FP_SCR0+4 341 set FP_SCR0_LO, FP_SCR0+8 341 set FP_SCR0_LO, FP_SCR0+8 342 342 343 set FP_DST, LV+56 343 set FP_DST, LV+56 # fp destination operand 344 set FP_DST_EX, FP_DST+0 344 set FP_DST_EX, FP_DST+0 345 set FP_DST_SGN, FP_DST+2 345 set FP_DST_SGN, FP_DST+2 346 set FP_DST_HI, FP_DST+4 346 set FP_DST_HI, FP_DST+4 347 set FP_DST_LO, FP_DST+8 347 set FP_DST_LO, FP_DST+8 348 348 349 set FP_SRC, LV+44 349 set FP_SRC, LV+44 # fp source operand 350 set FP_SRC_EX, FP_SRC+0 350 set FP_SRC_EX, FP_SRC+0 351 set FP_SRC_SGN, FP_SRC+2 351 set FP_SRC_SGN, FP_SRC+2 352 set FP_SRC_HI, FP_SRC+4 352 set FP_SRC_HI, FP_SRC+4 353 set FP_SRC_LO, FP_SRC+8 353 set FP_SRC_LO, FP_SRC+8 354 354 355 set USER_FPIAR, LV+40 355 set USER_FPIAR, LV+40 # FP instr address register 356 356 357 set USER_FPSR, LV+36 357 set USER_FPSR, LV+36 # FP status register 358 set FPSR_CC, USER_FPSR+0 358 set FPSR_CC, USER_FPSR+0 # FPSR condition codes 359 set FPSR_QBYTE, USER_FPSR+1 359 set FPSR_QBYTE, USER_FPSR+1 # FPSR qoutient byte 360 set FPSR_EXCEPT, USER_FPSR+2 360 set FPSR_EXCEPT, USER_FPSR+2 # FPSR exception status byte 361 set FPSR_AEXCEPT, USER_FPSR+3 361 set FPSR_AEXCEPT, USER_FPSR+3 # FPSR accrued exception byte 362 362 363 set USER_FPCR, LV+32 363 set USER_FPCR, LV+32 # FP control register 364 set FPCR_ENABLE, USER_FPCR+2 364 set FPCR_ENABLE, USER_FPCR+2 # FPCR exception enable 365 set FPCR_MODE, USER_FPCR+3 365 set FPCR_MODE, USER_FPCR+3 # FPCR rounding mode control 366 366 367 set L_SCR3, LV+28 367 set L_SCR3, LV+28 # integer scratch 3 368 set L_SCR2, LV+24 368 set L_SCR2, LV+24 # integer scratch 2 369 set L_SCR1, LV+20 369 set L_SCR1, LV+20 # integer scratch 1 370 370 371 set STORE_FLG, LV+19 371 set STORE_FLG, LV+19 # flag: operand store (ie. not fcmp/ftst) 372 372 373 set EXC_TEMP2, LV+24 373 set EXC_TEMP2, LV+24 # temporary space 374 set EXC_TEMP, LV+16 374 set EXC_TEMP, LV+16 # temporary space 375 375 376 set DTAG, LV+15 376 set DTAG, LV+15 # destination operand type 377 set STAG, LV+14 377 set STAG, LV+14 # source operand type 378 378 379 set SPCOND_FLG, LV+10 379 set SPCOND_FLG, LV+10 # flag: special case (see below) 380 380 381 set EXC_CC, LV+8 381 set EXC_CC, LV+8 # saved condition codes 382 set EXC_EXTWPTR, LV+4 382 set EXC_EXTWPTR, LV+4 # saved current PC (active) 383 set EXC_EXTWORD, LV+2 383 set EXC_EXTWORD, LV+2 # saved extension word 384 set EXC_CMDREG, LV+2 384 set EXC_CMDREG, LV+2 # saved extension word 385 set EXC_OPWORD, LV+0 385 set EXC_OPWORD, LV+0 # saved operation word 386 386 387 ################################ 387 ################################ 388 388 389 # Helpful macros 389 # Helpful macros 390 390 391 set FTEMP, 0 391 set FTEMP, 0 # offsets within an 392 set FTEMP_EX, 0 392 set FTEMP_EX, 0 # extended precision 393 set FTEMP_SGN, 2 393 set FTEMP_SGN, 2 # value saved in memory. 394 set FTEMP_HI, 4 394 set FTEMP_HI, 4 395 set FTEMP_LO, 8 395 set FTEMP_LO, 8 396 set FTEMP_GRS, 12 396 set FTEMP_GRS, 12 397 397 398 set LOCAL, 0 398 set LOCAL, 0 # offsets within an 399 set LOCAL_EX, 0 399 set LOCAL_EX, 0 # extended precision 400 set LOCAL_SGN, 2 400 set LOCAL_SGN, 2 # value saved in memory. 401 set LOCAL_HI, 4 401 set LOCAL_HI, 4 402 set LOCAL_LO, 8 402 set LOCAL_LO, 8 403 set LOCAL_GRS, 12 403 set LOCAL_GRS, 12 404 404 405 set DST, 0 405 set DST, 0 # offsets within an 406 set DST_EX, 0 406 set DST_EX, 0 # extended precision 407 set DST_HI, 4 407 set DST_HI, 4 # value saved in memory. 408 set DST_LO, 8 408 set DST_LO, 8 409 409 410 set SRC, 0 410 set SRC, 0 # offsets within an 411 set SRC_EX, 0 411 set SRC_EX, 0 # extended precision 412 set SRC_HI, 4 412 set SRC_HI, 4 # value saved in memory. 413 set SRC_LO, 8 413 set SRC_LO, 8 414 414 415 set SGL_LO, 0x3f81 415 set SGL_LO, 0x3f81 # min sgl prec exponent 416 set SGL_HI, 0x407e 416 set SGL_HI, 0x407e # max sgl prec exponent 417 set DBL_LO, 0x3c01 417 set DBL_LO, 0x3c01 # min dbl prec exponent 418 set DBL_HI, 0x43fe 418 set DBL_HI, 0x43fe # max dbl prec exponent 419 set EXT_LO, 0x0 419 set EXT_LO, 0x0 # min ext prec exponent 420 set EXT_HI, 0x7ffe 420 set EXT_HI, 0x7ffe # max ext prec exponent 421 421 422 set EXT_BIAS, 0x3fff 422 set EXT_BIAS, 0x3fff # extended precision bias 423 set SGL_BIAS, 0x007f 423 set SGL_BIAS, 0x007f # single precision bias 424 set DBL_BIAS, 0x03ff 424 set DBL_BIAS, 0x03ff # double precision bias 425 425 426 set NORM, 0x00 426 set NORM, 0x00 # operand type for STAG/DTAG 427 set ZERO, 0x01 427 set ZERO, 0x01 # operand type for STAG/DTAG 428 set INF, 0x02 428 set INF, 0x02 # operand type for STAG/DTAG 429 set QNAN, 0x03 429 set QNAN, 0x03 # operand type for STAG/DTAG 430 set DENORM, 0x04 430 set DENORM, 0x04 # operand type for STAG/DTAG 431 set SNAN, 0x05 431 set SNAN, 0x05 # operand type for STAG/DTAG 432 set UNNORM, 0x06 432 set UNNORM, 0x06 # operand type for STAG/DTAG 433 433 434 ################## 434 ################## 435 # FPSR/FPCR bits # 435 # FPSR/FPCR bits # 436 ################## 436 ################## 437 set neg_bit, 0x3 437 set neg_bit, 0x3 # negative result 438 set z_bit, 0x2 438 set z_bit, 0x2 # zero result 439 set inf_bit, 0x1 439 set inf_bit, 0x1 # infinite result 440 set nan_bit, 0x0 440 set nan_bit, 0x0 # NAN result 441 441 442 set q_sn_bit, 0x7 442 set q_sn_bit, 0x7 # sign bit of quotient byte 443 443 444 set bsun_bit, 7 444 set bsun_bit, 7 # branch on unordered 445 set snan_bit, 6 445 set snan_bit, 6 # signalling NAN 446 set operr_bit, 5 446 set operr_bit, 5 # operand error 447 set ovfl_bit, 4 447 set ovfl_bit, 4 # overflow 448 set unfl_bit, 3 448 set unfl_bit, 3 # underflow 449 set dz_bit, 2 449 set dz_bit, 2 # divide by zero 450 set inex2_bit, 1 450 set inex2_bit, 1 # inexact result 2 451 set inex1_bit, 0 451 set inex1_bit, 0 # inexact result 1 452 452 453 set aiop_bit, 7 453 set aiop_bit, 7 # accrued inexact operation bit 454 set aovfl_bit, 6 454 set aovfl_bit, 6 # accrued overflow bit 455 set aunfl_bit, 5 455 set aunfl_bit, 5 # accrued underflow bit 456 set adz_bit, 4 456 set adz_bit, 4 # accrued dz bit 457 set ainex_bit, 3 457 set ainex_bit, 3 # accrued inexact bit 458 458 459 ############################# 459 ############################# 460 # FPSR individual bit masks # 460 # FPSR individual bit masks # 461 ############################# 461 ############################# 462 set neg_mask, 0x08000000 462 set neg_mask, 0x08000000 # negative bit mask (lw) 463 set inf_mask, 0x02000000 463 set inf_mask, 0x02000000 # infinity bit mask (lw) 464 set z_mask, 0x04000000 464 set z_mask, 0x04000000 # zero bit mask (lw) 465 set nan_mask, 0x01000000 465 set nan_mask, 0x01000000 # nan bit mask (lw) 466 466 467 set neg_bmask, 0x08 467 set neg_bmask, 0x08 # negative bit mask (byte) 468 set inf_bmask, 0x02 468 set inf_bmask, 0x02 # infinity bit mask (byte) 469 set z_bmask, 0x04 469 set z_bmask, 0x04 # zero bit mask (byte) 470 set nan_bmask, 0x01 470 set nan_bmask, 0x01 # nan bit mask (byte) 471 471 472 set bsun_mask, 0x00008000 472 set bsun_mask, 0x00008000 # bsun exception mask 473 set snan_mask, 0x00004000 473 set snan_mask, 0x00004000 # snan exception mask 474 set operr_mask, 0x00002000 474 set operr_mask, 0x00002000 # operr exception mask 475 set ovfl_mask, 0x00001000 475 set ovfl_mask, 0x00001000 # overflow exception mask 476 set unfl_mask, 0x00000800 476 set unfl_mask, 0x00000800 # underflow exception mask 477 set dz_mask, 0x00000400 477 set dz_mask, 0x00000400 # dz exception mask 478 set inex2_mask, 0x00000200 478 set inex2_mask, 0x00000200 # inex2 exception mask 479 set inex1_mask, 0x00000100 479 set inex1_mask, 0x00000100 # inex1 exception mask 480 480 481 set aiop_mask, 0x00000080 481 set aiop_mask, 0x00000080 # accrued illegal operation 482 set aovfl_mask, 0x00000040 482 set aovfl_mask, 0x00000040 # accrued overflow 483 set aunfl_mask, 0x00000020 483 set aunfl_mask, 0x00000020 # accrued underflow 484 set adz_mask, 0x00000010 484 set adz_mask, 0x00000010 # accrued divide by zero 485 set ainex_mask, 0x00000008 485 set ainex_mask, 0x00000008 # accrued inexact 486 486 487 ###################################### 487 ###################################### 488 # FPSR combinations used in the FPSP # 488 # FPSR combinations used in the FPSP # 489 ###################################### 489 ###################################### 490 set dzinf_mask, inf_mask+dz_mask+adz_m 490 set dzinf_mask, inf_mask+dz_mask+adz_mask 491 set opnan_mask, nan_mask+operr_mask+ai 491 set opnan_mask, nan_mask+operr_mask+aiop_mask 492 set nzi_mask, 0x01ffffff 492 set nzi_mask, 0x01ffffff #clears N, Z, and I 493 set unfinx_mask, unfl_mask+inex2_mask+a 493 set unfinx_mask, unfl_mask+inex2_mask+aunfl_mask+ainex_mask 494 set unf2inx_mask, unfl_mask+inex2_mask+a 494 set unf2inx_mask, unfl_mask+inex2_mask+ainex_mask 495 set ovfinx_mask, ovfl_mask+inex2_mask+a 495 set ovfinx_mask, ovfl_mask+inex2_mask+aovfl_mask+ainex_mask 496 set inx1a_mask, inex1_mask+ainex_mask 496 set inx1a_mask, inex1_mask+ainex_mask 497 set inx2a_mask, inex2_mask+ainex_mask 497 set inx2a_mask, inex2_mask+ainex_mask 498 set snaniop_mask, nan_mask+snan_mask+aio 498 set snaniop_mask, nan_mask+snan_mask+aiop_mask 499 set snaniop2_mask, snan_mask+aiop_mask 499 set snaniop2_mask, snan_mask+aiop_mask 500 set naniop_mask, nan_mask+aiop_mask 500 set naniop_mask, nan_mask+aiop_mask 501 set neginf_mask, neg_mask+inf_mask 501 set neginf_mask, neg_mask+inf_mask 502 set infaiop_mask, inf_mask+aiop_mask 502 set infaiop_mask, inf_mask+aiop_mask 503 set negz_mask, neg_mask+z_mask 503 set negz_mask, neg_mask+z_mask 504 set opaop_mask, operr_mask+aiop_mask 504 set opaop_mask, operr_mask+aiop_mask 505 set unfl_inx_mask, unfl_mask+aunfl_mask+a 505 set unfl_inx_mask, unfl_mask+aunfl_mask+ainex_mask 506 set ovfl_inx_mask, ovfl_mask+aovfl_mask+a 506 set ovfl_inx_mask, ovfl_mask+aovfl_mask+ainex_mask 507 507 508 ######### 508 ######### 509 # misc. # 509 # misc. # 510 ######### 510 ######### 511 set rnd_stky_bit, 29 511 set rnd_stky_bit, 29 # stky bit pos in longword 512 512 513 set sign_bit, 0x7 513 set sign_bit, 0x7 # sign bit 514 set signan_bit, 0x6 514 set signan_bit, 0x6 # signalling nan bit 515 515 516 set sgl_thresh, 0x3f81 516 set sgl_thresh, 0x3f81 # minimum sgl exponent 517 set dbl_thresh, 0x3c01 517 set dbl_thresh, 0x3c01 # minimum dbl exponent 518 518 519 set x_mode, 0x0 519 set x_mode, 0x0 # extended precision 520 set s_mode, 0x4 520 set s_mode, 0x4 # single precision 521 set d_mode, 0x8 521 set d_mode, 0x8 # double precision 522 522 523 set rn_mode, 0x0 523 set rn_mode, 0x0 # round-to-nearest 524 set rz_mode, 0x1 524 set rz_mode, 0x1 # round-to-zero 525 set rm_mode, 0x2 525 set rm_mode, 0x2 # round-tp-minus-infinity 526 set rp_mode, 0x3 526 set rp_mode, 0x3 # round-to-plus-infinity 527 527 528 set mantissalen, 64 528 set mantissalen, 64 # length of mantissa in bits 529 529 530 set BYTE, 1 530 set BYTE, 1 # len(byte) == 1 byte 531 set WORD, 2 531 set WORD, 2 # len(word) == 2 bytes 532 set LONG, 4 532 set LONG, 4 # len(longword) == 2 bytes 533 533 534 set BSUN_VEC, 0xc0 534 set BSUN_VEC, 0xc0 # bsun vector offset 535 set INEX_VEC, 0xc4 535 set INEX_VEC, 0xc4 # inexact vector offset 536 set DZ_VEC, 0xc8 536 set DZ_VEC, 0xc8 # dz vector offset 537 set UNFL_VEC, 0xcc 537 set UNFL_VEC, 0xcc # unfl vector offset 538 set OPERR_VEC, 0xd0 538 set OPERR_VEC, 0xd0 # operr vector offset 539 set OVFL_VEC, 0xd4 539 set OVFL_VEC, 0xd4 # ovfl vector offset 540 set SNAN_VEC, 0xd8 540 set SNAN_VEC, 0xd8 # snan vector offset 541 541 542 ########################### 542 ########################### 543 # SPecial CONDition FLaGs # 543 # SPecial CONDition FLaGs # 544 ########################### 544 ########################### 545 set ftrapcc_flg, 0x01 545 set ftrapcc_flg, 0x01 # flag bit: ftrapcc exception 546 set fbsun_flg, 0x02 546 set fbsun_flg, 0x02 # flag bit: bsun exception 547 set mia7_flg, 0x04 547 set mia7_flg, 0x04 # flag bit: (a7)+ <ea> 548 set mda7_flg, 0x08 548 set mda7_flg, 0x08 # flag bit: -(a7) <ea> 549 set fmovm_flg, 0x40 549 set fmovm_flg, 0x40 # flag bit: fmovm instruction 550 set immed_flg, 0x80 550 set immed_flg, 0x80 # flag bit: &<data> <ea> 551 551 552 set ftrapcc_bit, 0x0 552 set ftrapcc_bit, 0x0 553 set fbsun_bit, 0x1 553 set fbsun_bit, 0x1 554 set mia7_bit, 0x2 554 set mia7_bit, 0x2 555 set mda7_bit, 0x3 555 set mda7_bit, 0x3 556 set immed_bit, 0x7 556 set immed_bit, 0x7 557 557 558 ################################## 558 ################################## 559 # TRANSCENDENTAL "LAST-OP" FLAGS # 559 # TRANSCENDENTAL "LAST-OP" FLAGS # 560 ################################## 560 ################################## 561 set FMUL_OP, 0x0 561 set FMUL_OP, 0x0 # fmul instr performed last 562 set FDIV_OP, 0x1 562 set FDIV_OP, 0x1 # fdiv performed last 563 set FADD_OP, 0x2 563 set FADD_OP, 0x2 # fadd performed last 564 set FMOV_OP, 0x3 564 set FMOV_OP, 0x3 # fmov performed last 565 565 566 ############# 566 ############# 567 # CONSTANTS # 567 # CONSTANTS # 568 ############# 568 ############# 569 T1: long 0x40C62D38,0xD3D64634 569 T1: long 0x40C62D38,0xD3D64634 # 16381 LOG2 LEAD 570 T2: long 0x3D6F90AE,0xB1E75CC7 570 T2: long 0x3D6F90AE,0xB1E75CC7 # 16381 LOG2 TRAIL 571 571 572 PI: long 0x40000000,0xC90FDAA2, 572 PI: long 0x40000000,0xC90FDAA2,0x2168C235,0x00000000 573 PIBY2: long 0x3FFF0000,0xC90FDAA2, 573 PIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 574 574 575 TWOBYPI: 575 TWOBYPI: 576 long 0x3FE45F30,0x6DC9C883 576 long 0x3FE45F30,0x6DC9C883 577 577 578 ############################################## 578 ######################################################################### 579 # XDEF *************************************** 579 # XDEF **************************************************************** # 580 # _fpsp_ovfl(): 060FPSP entry point for 580 # _fpsp_ovfl(): 060FPSP entry point for FP Overflow exception. # 581 # 581 # # 582 # This handler should be the first code 582 # This handler should be the first code executed upon taking the # 583 # FP Overflow exception in an operating 583 # FP Overflow exception in an operating system. # 584 # 584 # # 585 # XREF *************************************** 585 # XREF **************************************************************** # 586 # _imem_read_long() - read instruction l 586 # _imem_read_long() - read instruction longword # 587 # fix_skewed_ops() - adjust src operand 587 # fix_skewed_ops() - adjust src operand in fsave frame # 588 # set_tag_x() - determine optype of src/ 588 # set_tag_x() - determine optype of src/dst operands # 589 # store_fpreg() - store opclass 0 or 2 r 589 # store_fpreg() - store opclass 0 or 2 result to FP regfile # 590 # unnorm_fix() - change UNNORM operands 590 # unnorm_fix() - change UNNORM operands to NORM or ZERO # 591 # load_fpn2() - load dst operand from FP 591 # load_fpn2() - load dst operand from FP regfile # 592 # fout() - emulate an opclass 3 instruct 592 # fout() - emulate an opclass 3 instruction # 593 # tbl_unsupp - add of table of emulation 593 # tbl_unsupp - add of table of emulation routines for opclass 0,2 # 594 # _fpsp_done() - "callout" for 060FPSP e 594 # _fpsp_done() - "callout" for 060FPSP exit (all work done!) # 595 # _real_ovfl() - "callout" for Overflow 595 # _real_ovfl() - "callout" for Overflow exception enabled code # 596 # _real_inex() - "callout" for Inexact e 596 # _real_inex() - "callout" for Inexact exception enabled code # 597 # _real_trace() - "callout" for Trace ex 597 # _real_trace() - "callout" for Trace exception code # 598 # 598 # # 599 # INPUT ************************************** 599 # INPUT *************************************************************** # 600 # - The system stack contains the FP Ovf 600 # - The system stack contains the FP Ovfl exception stack frame # 601 # - The fsave frame contains the source 601 # - The fsave frame contains the source operand # 602 # 602 # # 603 # OUTPUT ************************************* 603 # OUTPUT ************************************************************** # 604 # Overflow Exception enabled: 604 # Overflow Exception enabled: # 605 # - The system stack is unchanged 605 # - The system stack is unchanged # 606 # - The fsave frame contains the adjuste 606 # - The fsave frame contains the adjusted src op for opclass 0,2 # 607 # Overflow Exception disabled: 607 # Overflow Exception disabled: # 608 # - The system stack is unchanged 608 # - The system stack is unchanged # 609 # - The "exception present" flag in the 609 # - The "exception present" flag in the fsave frame is cleared # 610 # 610 # # 611 # ALGORITHM ********************************** 611 # ALGORITHM *********************************************************** # 612 # On the 060, if an FP overflow is prese 612 # On the 060, if an FP overflow is present as the result of any # 613 # instruction, the 060 will take an overflow e 613 # instruction, the 060 will take an overflow exception whether the # 614 # exception is enabled or disabled in the FPCR 614 # exception is enabled or disabled in the FPCR. For the disabled case, # 615 # This handler emulates the instruction to det 615 # This handler emulates the instruction to determine what the correct # 616 # default result should be for the operation. 616 # default result should be for the operation. This default result is # 617 # then stored in either the FP regfile, data r 617 # then stored in either the FP regfile, data regfile, or memory. # 618 # Finally, the handler exits through the "call 618 # Finally, the handler exits through the "callout" _fpsp_done() # 619 # denoting that no exceptional conditions exis 619 # denoting that no exceptional conditions exist within the machine. # 620 # If the exception is enabled, then this 620 # If the exception is enabled, then this handler must create the # 621 # exceptional operand and plave it in the fsav 621 # exceptional operand and plave it in the fsave state frame, and store # 622 # the default result (only if the instruction 622 # the default result (only if the instruction is opclass 3). For # 623 # exceptions enabled, this handler must exit t 623 # exceptions enabled, this handler must exit through the "callout" # 624 # _real_ovfl() so that the operating system en 624 # _real_ovfl() so that the operating system enabled overflow handler # 625 # can handle this case. 625 # can handle this case. # 626 # Two other conditions exist. First, if 626 # Two other conditions exist. First, if overflow was disabled # 627 # but the inexact exception was enabled, this 627 # but the inexact exception was enabled, this handler must exit # 628 # through the "callout" _real_inex() regardles 628 # through the "callout" _real_inex() regardless of whether the result # 629 # was inexact. 629 # was inexact. # 630 # Also, in the case of an opclass three 630 # Also, in the case of an opclass three instruction where # 631 # overflow was disabled and the trace exceptio 631 # overflow was disabled and the trace exception was enabled, this # 632 # handler must exit through the "callout" _rea 632 # handler must exit through the "callout" _real_trace(). # 633 # 633 # # 634 ############################################## 634 ######################################################################### 635 635 636 global _fpsp_ovfl 636 global _fpsp_ovfl 637 _fpsp_ovfl: 637 _fpsp_ovfl: 638 638 639 #$# sub.l &24,%sp 639 #$# sub.l &24,%sp # make room for src/dst 640 640 641 link.w %a6,&-LOCAL_SIZE 641 link.w %a6,&-LOCAL_SIZE # init stack frame 642 642 643 fsave FP_SRC(%a6) 643 fsave FP_SRC(%a6) # grab the "busy" frame 644 644 645 movm.l &0x0303,EXC_DREGS(%a6) 645 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 646 fmovm.l %fpcr,%fpsr,%fpiar,USE 646 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 647 fmovm.x &0xc0,EXC_FPREGS(%a6) 647 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 648 648 649 # the FPIAR holds the "current PC" of the faul 649 # the FPIAR holds the "current PC" of the faulting instruction 650 mov.l USER_FPIAR(%a6),EXC_EX 650 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 651 mov.l EXC_EXTWPTR(%a6),%a0 651 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 652 addq.l &0x4,EXC_EXTWPTR(%a6) 652 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 653 bsr.l _imem_read_long 653 bsr.l _imem_read_long # fetch the instruction words 654 mov.l %d0,EXC_OPWORD(%a6) 654 mov.l %d0,EXC_OPWORD(%a6) 655 655 656 ############################################## 656 ############################################################################## 657 657 658 btst &0x5,EXC_CMDREG(%a6) 658 btst &0x5,EXC_CMDREG(%a6) # is instr an fmove out? 659 bne.w fovfl_out 659 bne.w fovfl_out 660 660 661 661 662 lea FP_SRC(%a6),%a0 662 lea FP_SRC(%a6),%a0 # pass: ptr to src op 663 bsr.l fix_skewed_ops 663 bsr.l fix_skewed_ops # fix src op 664 664 665 # since, I believe, only NORMs and DENORMs can 665 # since, I believe, only NORMs and DENORMs can come through here, 666 # maybe we can avoid the subroutine call. 666 # maybe we can avoid the subroutine call. 667 lea FP_SRC(%a6),%a0 667 lea FP_SRC(%a6),%a0 # pass: ptr to src op 668 bsr.l set_tag_x 668 bsr.l set_tag_x # tag the operand type 669 mov.b %d0,STAG(%a6) 669 mov.b %d0,STAG(%a6) # maybe NORM,DENORM 670 670 671 # bit five of the fp extension word separates 671 # bit five of the fp extension word separates the monadic and dyadic operations 672 # that can pass through fpsp_ovfl(). remember 672 # that can pass through fpsp_ovfl(). remember that fcmp, ftst, and fsincos 673 # will never take this exception. 673 # will never take this exception. 674 btst &0x5,1+EXC_CMDREG(%a6) 674 btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic? 675 beq.b fovfl_extract 675 beq.b fovfl_extract # monadic 676 676 677 bfextu EXC_CMDREG(%a6){&6:&3} 677 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg 678 bsr.l load_fpn2 678 bsr.l load_fpn2 # load dst into FP_DST 679 679 680 lea FP_DST(%a6),%a0 680 lea FP_DST(%a6),%a0 # pass: ptr to dst op 681 bsr.l set_tag_x 681 bsr.l set_tag_x # tag the operand type 682 cmpi.b %d0,&UNNORM 682 cmpi.b %d0,&UNNORM # is operand an UNNORM? 683 bne.b fovfl_op2_done 683 bne.b fovfl_op2_done # no 684 bsr.l unnorm_fix 684 bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO 685 fovfl_op2_done: 685 fovfl_op2_done: 686 mov.b %d0,DTAG(%a6) 686 mov.b %d0,DTAG(%a6) # save dst optype tag 687 687 688 fovfl_extract: 688 fovfl_extract: 689 689 690 #$# mov.l FP_SRC_EX(%a6),TRAP_SR 690 #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6) 691 #$# mov.l FP_SRC_HI(%a6),TRAP_SR 691 #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6) 692 #$# mov.l FP_SRC_LO(%a6),TRAP_SR 692 #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6) 693 #$# mov.l FP_DST_EX(%a6),TRAP_DS 693 #$# mov.l FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6) 694 #$# mov.l FP_DST_HI(%a6),TRAP_DS 694 #$# mov.l FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6) 695 #$# mov.l FP_DST_LO(%a6),TRAP_DS 695 #$# mov.l FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6) 696 696 697 clr.l %d0 697 clr.l %d0 698 mov.b FPCR_MODE(%a6),%d0 698 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode 699 699 700 mov.b 1+EXC_CMDREG(%a6),%d1 700 mov.b 1+EXC_CMDREG(%a6),%d1 701 andi.w &0x007f,%d1 701 andi.w &0x007f,%d1 # extract extension 702 702 703 andi.l &0x00ff01ff,USER_FPSR( 703 andi.l &0x00ff01ff,USER_FPSR(%a6) # zero all but accured field 704 704 705 fmov.l &0x0,%fpcr 705 fmov.l &0x0,%fpcr # zero current control regs 706 fmov.l &0x0,%fpsr 706 fmov.l &0x0,%fpsr 707 707 708 lea FP_SRC(%a6),%a0 708 lea FP_SRC(%a6),%a0 709 lea FP_DST(%a6),%a1 709 lea FP_DST(%a6),%a1 710 710 711 # maybe we can make these entry points ONLY th 711 # maybe we can make these entry points ONLY the OVFL entry points of each routine. 712 mov.l (tbl_unsupp.l,%pc,%d1. 712 mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr 713 jsr (tbl_unsupp.l,%pc,%d1. 713 jsr (tbl_unsupp.l,%pc,%d1.l*1) 714 714 715 # the operation has been emulated. the result 715 # the operation has been emulated. the result is in fp0. 716 # the EXOP, if an exception occurred, is in fp 716 # the EXOP, if an exception occurred, is in fp1. 717 # we must save the default result regardless o 717 # we must save the default result regardless of whether 718 # traps are enabled or disabled. 718 # traps are enabled or disabled. 719 bfextu EXC_CMDREG(%a6){&6:&3} 719 bfextu EXC_CMDREG(%a6){&6:&3},%d0 720 bsr.l store_fpreg 720 bsr.l store_fpreg 721 721 722 # the exceptional possibilities we have left o 722 # the exceptional possibilities we have left ourselves with are ONLY overflow 723 # and inexact. and, the inexact is such that o 723 # and inexact. and, the inexact is such that overflow occurred and was disabled 724 # but inexact was enabled. 724 # but inexact was enabled. 725 btst &ovfl_bit,FPCR_ENABLE( 725 btst &ovfl_bit,FPCR_ENABLE(%a6) 726 bne.b fovfl_ovfl_on 726 bne.b fovfl_ovfl_on 727 727 728 btst &inex2_bit,FPCR_ENABLE 728 btst &inex2_bit,FPCR_ENABLE(%a6) 729 bne.b fovfl_inex_on 729 bne.b fovfl_inex_on 730 730 731 fmovm.x EXC_FPREGS(%a6),&0xc0 731 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 732 fmovm.l USER_FPCR(%a6),%fpcr,% 732 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 733 movm.l EXC_DREGS(%a6),&0x0303 733 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 734 734 735 unlk %a6 735 unlk %a6 736 #$# add.l &24,%sp 736 #$# add.l &24,%sp 737 bra.l _fpsp_done 737 bra.l _fpsp_done 738 738 739 # overflow is enabled AND overflow, of course, 739 # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP 740 # in fp1. now, simply jump to _real_ovfl()! 740 # in fp1. now, simply jump to _real_ovfl()! 741 fovfl_ovfl_on: 741 fovfl_ovfl_on: 742 fmovm.x &0x40,FP_SRC(%a6) 742 fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack 743 743 744 mov.w &0xe005,2+FP_SRC(%a6) 744 mov.w &0xe005,2+FP_SRC(%a6) # save exc status 745 745 746 fmovm.x EXC_FPREGS(%a6),&0xc0 746 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 747 fmovm.l USER_FPCR(%a6),%fpcr,% 747 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 748 movm.l EXC_DREGS(%a6),&0x0303 748 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 749 749 750 frestore FP_SRC(%a6) 750 frestore FP_SRC(%a6) # do this after fmovm,other f<op>s! 751 751 752 unlk %a6 752 unlk %a6 753 753 754 bra.l _real_ovfl 754 bra.l _real_ovfl 755 755 756 # overflow occurred but is disabled. meanwhile 756 # overflow occurred but is disabled. meanwhile, inexact is enabled. Therefore, 757 # we must jump to real_inex(). 757 # we must jump to real_inex(). 758 fovfl_inex_on: 758 fovfl_inex_on: 759 759 760 fmovm.x &0x40,FP_SRC(%a6) 760 fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack 761 761 762 mov.b &0xc4,1+EXC_VOFF(%a6) 762 mov.b &0xc4,1+EXC_VOFF(%a6) # vector offset = 0xc4 763 mov.w &0xe001,2+FP_SRC(%a6) 763 mov.w &0xe001,2+FP_SRC(%a6) # save exc status 764 764 765 fmovm.x EXC_FPREGS(%a6),&0xc0 765 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 766 fmovm.l USER_FPCR(%a6),%fpcr,% 766 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 767 movm.l EXC_DREGS(%a6),&0x0303 767 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 768 768 769 frestore FP_SRC(%a6) 769 frestore FP_SRC(%a6) # do this after fmovm,other f<op>s! 770 770 771 unlk %a6 771 unlk %a6 772 772 773 bra.l _real_inex 773 bra.l _real_inex 774 774 775 ############################################## 775 ######################################################################## 776 fovfl_out: 776 fovfl_out: 777 777 778 778 779 #$# mov.l FP_SRC_EX(%a6),TRAP_SR 779 #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6) 780 #$# mov.l FP_SRC_HI(%a6),TRAP_SR 780 #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6) 781 #$# mov.l FP_SRC_LO(%a6),TRAP_SR 781 #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6) 782 782 783 # the src operand is definitely a NORM(!), so 783 # the src operand is definitely a NORM(!), so tag it as such 784 mov.b &NORM,STAG(%a6) 784 mov.b &NORM,STAG(%a6) # set src optype tag 785 785 786 clr.l %d0 786 clr.l %d0 787 mov.b FPCR_MODE(%a6),%d0 787 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode 788 788 789 and.l &0xffff00ff,USER_FPSR( 789 and.l &0xffff00ff,USER_FPSR(%a6) # zero all but accured field 790 790 791 fmov.l &0x0,%fpcr 791 fmov.l &0x0,%fpcr # zero current control regs 792 fmov.l &0x0,%fpsr 792 fmov.l &0x0,%fpsr 793 793 794 lea FP_SRC(%a6),%a0 794 lea FP_SRC(%a6),%a0 # pass ptr to src operand 795 795 796 bsr.l fout 796 bsr.l fout 797 797 798 btst &ovfl_bit,FPCR_ENABLE( 798 btst &ovfl_bit,FPCR_ENABLE(%a6) 799 bne.w fovfl_ovfl_on 799 bne.w fovfl_ovfl_on 800 800 801 btst &inex2_bit,FPCR_ENABLE 801 btst &inex2_bit,FPCR_ENABLE(%a6) 802 bne.w fovfl_inex_on 802 bne.w fovfl_inex_on 803 803 804 fmovm.x EXC_FPREGS(%a6),&0xc0 804 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 805 fmovm.l USER_FPCR(%a6),%fpcr,% 805 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 806 movm.l EXC_DREGS(%a6),&0x0303 806 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 807 807 808 unlk %a6 808 unlk %a6 809 #$# add.l &24,%sp 809 #$# add.l &24,%sp 810 810 811 btst &0x7,(%sp) 811 btst &0x7,(%sp) # is trace on? 812 beq.l _fpsp_done 812 beq.l _fpsp_done # no 813 813 814 fmov.l %fpiar,0x8(%sp) 814 fmov.l %fpiar,0x8(%sp) # "Current PC" is in FPIAR 815 mov.w &0x2024,0x6(%sp) 815 mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x024 816 bra.l _real_trace 816 bra.l _real_trace 817 817 818 ############################################## 818 ######################################################################### 819 # XDEF *************************************** 819 # XDEF **************************************************************** # 820 # _fpsp_unfl(): 060FPSP entry point for 820 # _fpsp_unfl(): 060FPSP entry point for FP Underflow exception. # 821 # 821 # # 822 # This handler should be the first code 822 # This handler should be the first code executed upon taking the # 823 # FP Underflow exception in an operating 823 # FP Underflow exception in an operating system. # 824 # 824 # # 825 # XREF *************************************** 825 # XREF **************************************************************** # 826 # _imem_read_long() - read instruction l 826 # _imem_read_long() - read instruction longword # 827 # fix_skewed_ops() - adjust src operand 827 # fix_skewed_ops() - adjust src operand in fsave frame # 828 # set_tag_x() - determine optype of src/ 828 # set_tag_x() - determine optype of src/dst operands # 829 # store_fpreg() - store opclass 0 or 2 r 829 # store_fpreg() - store opclass 0 or 2 result to FP regfile # 830 # unnorm_fix() - change UNNORM operands 830 # unnorm_fix() - change UNNORM operands to NORM or ZERO # 831 # load_fpn2() - load dst operand from FP 831 # load_fpn2() - load dst operand from FP regfile # 832 # fout() - emulate an opclass 3 instruct 832 # fout() - emulate an opclass 3 instruction # 833 # tbl_unsupp - add of table of emulation 833 # tbl_unsupp - add of table of emulation routines for opclass 0,2 # 834 # _fpsp_done() - "callout" for 060FPSP e 834 # _fpsp_done() - "callout" for 060FPSP exit (all work done!) # 835 # _real_ovfl() - "callout" for Overflow 835 # _real_ovfl() - "callout" for Overflow exception enabled code # 836 # _real_inex() - "callout" for Inexact e 836 # _real_inex() - "callout" for Inexact exception enabled code # 837 # _real_trace() - "callout" for Trace ex 837 # _real_trace() - "callout" for Trace exception code # 838 # 838 # # 839 # INPUT ************************************** 839 # INPUT *************************************************************** # 840 # - The system stack contains the FP Unf 840 # - The system stack contains the FP Unfl exception stack frame # 841 # - The fsave frame contains the source 841 # - The fsave frame contains the source operand # 842 # 842 # # 843 # OUTPUT ************************************* 843 # OUTPUT ************************************************************** # 844 # Underflow Exception enabled: 844 # Underflow Exception enabled: # 845 # - The system stack is unchanged 845 # - The system stack is unchanged # 846 # - The fsave frame contains the adjuste 846 # - The fsave frame contains the adjusted src op for opclass 0,2 # 847 # Underflow Exception disabled: 847 # Underflow Exception disabled: # 848 # - The system stack is unchanged 848 # - The system stack is unchanged # 849 # - The "exception present" flag in the 849 # - The "exception present" flag in the fsave frame is cleared # 850 # 850 # # 851 # ALGORITHM ********************************** 851 # ALGORITHM *********************************************************** # 852 # On the 060, if an FP underflow is pres 852 # On the 060, if an FP underflow is present as the result of any # 853 # instruction, the 060 will take an underflow 853 # instruction, the 060 will take an underflow exception whether the # 854 # exception is enabled or disabled in the FPCR 854 # exception is enabled or disabled in the FPCR. For the disabled case, # 855 # This handler emulates the instruction to det 855 # This handler emulates the instruction to determine what the correct # 856 # default result should be for the operation. 856 # default result should be for the operation. This default result is # 857 # then stored in either the FP regfile, data r 857 # then stored in either the FP regfile, data regfile, or memory. # 858 # Finally, the handler exits through the "call 858 # Finally, the handler exits through the "callout" _fpsp_done() # 859 # denoting that no exceptional conditions exis 859 # denoting that no exceptional conditions exist within the machine. # 860 # If the exception is enabled, then this 860 # If the exception is enabled, then this handler must create the # 861 # exceptional operand and plave it in the fsav 861 # exceptional operand and plave it in the fsave state frame, and store # 862 # the default result (only if the instruction 862 # the default result (only if the instruction is opclass 3). For # 863 # exceptions enabled, this handler must exit t 863 # exceptions enabled, this handler must exit through the "callout" # 864 # _real_unfl() so that the operating system en 864 # _real_unfl() so that the operating system enabled overflow handler # 865 # can handle this case. 865 # can handle this case. # 866 # Two other conditions exist. First, if 866 # Two other conditions exist. First, if underflow was disabled # 867 # but the inexact exception was enabled and th 867 # but the inexact exception was enabled and the result was inexact, # 868 # this handler must exit through the "callout" 868 # this handler must exit through the "callout" _real_inex(). # 869 # was inexact. 869 # was inexact. # 870 # Also, in the case of an opclass three 870 # Also, in the case of an opclass three instruction where # 871 # underflow was disabled and the trace excepti 871 # underflow was disabled and the trace exception was enabled, this # 872 # handler must exit through the "callout" _rea 872 # handler must exit through the "callout" _real_trace(). # 873 # 873 # # 874 ############################################## 874 ######################################################################### 875 875 876 global _fpsp_unfl 876 global _fpsp_unfl 877 _fpsp_unfl: 877 _fpsp_unfl: 878 878 879 #$# sub.l &24,%sp 879 #$# sub.l &24,%sp # make room for src/dst 880 880 881 link.w %a6,&-LOCAL_SIZE 881 link.w %a6,&-LOCAL_SIZE # init stack frame 882 882 883 fsave FP_SRC(%a6) 883 fsave FP_SRC(%a6) # grab the "busy" frame 884 884 885 movm.l &0x0303,EXC_DREGS(%a6) 885 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 886 fmovm.l %fpcr,%fpsr,%fpiar,USE 886 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 887 fmovm.x &0xc0,EXC_FPREGS(%a6) 887 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 888 888 889 # the FPIAR holds the "current PC" of the faul 889 # the FPIAR holds the "current PC" of the faulting instruction 890 mov.l USER_FPIAR(%a6),EXC_EX 890 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 891 mov.l EXC_EXTWPTR(%a6),%a0 891 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 892 addq.l &0x4,EXC_EXTWPTR(%a6) 892 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 893 bsr.l _imem_read_long 893 bsr.l _imem_read_long # fetch the instruction words 894 mov.l %d0,EXC_OPWORD(%a6) 894 mov.l %d0,EXC_OPWORD(%a6) 895 895 896 ############################################## 896 ############################################################################## 897 897 898 btst &0x5,EXC_CMDREG(%a6) 898 btst &0x5,EXC_CMDREG(%a6) # is instr an fmove out? 899 bne.w funfl_out 899 bne.w funfl_out 900 900 901 901 902 lea FP_SRC(%a6),%a0 902 lea FP_SRC(%a6),%a0 # pass: ptr to src op 903 bsr.l fix_skewed_ops 903 bsr.l fix_skewed_ops # fix src op 904 904 905 lea FP_SRC(%a6),%a0 905 lea FP_SRC(%a6),%a0 # pass: ptr to src op 906 bsr.l set_tag_x 906 bsr.l set_tag_x # tag the operand type 907 mov.b %d0,STAG(%a6) 907 mov.b %d0,STAG(%a6) # maybe NORM,DENORM 908 908 909 # bit five of the fp ext word separates the mo 909 # bit five of the fp ext word separates the monadic and dyadic operations 910 # that can pass through fpsp_unfl(). remember 910 # that can pass through fpsp_unfl(). remember that fcmp, and ftst 911 # will never take this exception. 911 # will never take this exception. 912 btst &0x5,1+EXC_CMDREG(%a6) 912 btst &0x5,1+EXC_CMDREG(%a6) # is op monadic or dyadic? 913 beq.b funfl_extract 913 beq.b funfl_extract # monadic 914 914 915 # now, what's left that's not dyadic is fsinco 915 # now, what's left that's not dyadic is fsincos. we can distinguish it 916 # from all dyadics by the '0110xxx pattern 916 # from all dyadics by the '0110xxx pattern 917 btst &0x4,1+EXC_CMDREG(%a6) 917 btst &0x4,1+EXC_CMDREG(%a6) # is op an fsincos? 918 bne.b funfl_extract 918 bne.b funfl_extract # yes 919 919 920 bfextu EXC_CMDREG(%a6){&6:&3} 920 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg 921 bsr.l load_fpn2 921 bsr.l load_fpn2 # load dst into FP_DST 922 922 923 lea FP_DST(%a6),%a0 923 lea FP_DST(%a6),%a0 # pass: ptr to dst op 924 bsr.l set_tag_x 924 bsr.l set_tag_x # tag the operand type 925 cmpi.b %d0,&UNNORM 925 cmpi.b %d0,&UNNORM # is operand an UNNORM? 926 bne.b funfl_op2_done 926 bne.b funfl_op2_done # no 927 bsr.l unnorm_fix 927 bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO 928 funfl_op2_done: 928 funfl_op2_done: 929 mov.b %d0,DTAG(%a6) 929 mov.b %d0,DTAG(%a6) # save dst optype tag 930 930 931 funfl_extract: 931 funfl_extract: 932 932 933 #$# mov.l FP_SRC_EX(%a6),TRAP_SR 933 #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6) 934 #$# mov.l FP_SRC_HI(%a6),TRAP_SR 934 #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6) 935 #$# mov.l FP_SRC_LO(%a6),TRAP_SR 935 #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6) 936 #$# mov.l FP_DST_EX(%a6),TRAP_DS 936 #$# mov.l FP_DST_EX(%a6),TRAP_DSTOP_EX(%a6) 937 #$# mov.l FP_DST_HI(%a6),TRAP_DS 937 #$# mov.l FP_DST_HI(%a6),TRAP_DSTOP_HI(%a6) 938 #$# mov.l FP_DST_LO(%a6),TRAP_DS 938 #$# mov.l FP_DST_LO(%a6),TRAP_DSTOP_LO(%a6) 939 939 940 clr.l %d0 940 clr.l %d0 941 mov.b FPCR_MODE(%a6),%d0 941 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode 942 942 943 mov.b 1+EXC_CMDREG(%a6),%d1 943 mov.b 1+EXC_CMDREG(%a6),%d1 944 andi.w &0x007f,%d1 944 andi.w &0x007f,%d1 # extract extension 945 945 946 andi.l &0x00ff01ff,USER_FPSR( 946 andi.l &0x00ff01ff,USER_FPSR(%a6) 947 947 948 fmov.l &0x0,%fpcr 948 fmov.l &0x0,%fpcr # zero current control regs 949 fmov.l &0x0,%fpsr 949 fmov.l &0x0,%fpsr 950 950 951 lea FP_SRC(%a6),%a0 951 lea FP_SRC(%a6),%a0 952 lea FP_DST(%a6),%a1 952 lea FP_DST(%a6),%a1 953 953 954 # maybe we can make these entry points ONLY th 954 # maybe we can make these entry points ONLY the OVFL entry points of each routine. 955 mov.l (tbl_unsupp.l,%pc,%d1. 955 mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr 956 jsr (tbl_unsupp.l,%pc,%d1. 956 jsr (tbl_unsupp.l,%pc,%d1.l*1) 957 957 958 bfextu EXC_CMDREG(%a6){&6:&3} 958 bfextu EXC_CMDREG(%a6){&6:&3},%d0 959 bsr.l store_fpreg 959 bsr.l store_fpreg 960 960 961 # The `060 FPU multiplier hardware is such tha 961 # The `060 FPU multiplier hardware is such that if the result of a 962 # multiply operation is the smallest possible 962 # multiply operation is the smallest possible normalized number 963 # (0x00000000_80000000_00000000), then the mac 963 # (0x00000000_80000000_00000000), then the machine will take an 964 # underflow exception. Since this is incorrect 964 # underflow exception. Since this is incorrect, we need to check 965 # if our emulation, after re-doing the operati 965 # if our emulation, after re-doing the operation, decided that 966 # no underflow was called for. We do these che 966 # no underflow was called for. We do these checks only in 967 # funfl_{unfl,inex}_on() because w/ both excep 967 # funfl_{unfl,inex}_on() because w/ both exceptions disabled, this 968 # special case will simply exit gracefully wit 968 # special case will simply exit gracefully with the correct result. 969 969 970 # the exceptional possibilities we have left o 970 # the exceptional possibilities we have left ourselves with are ONLY overflow 971 # and inexact. and, the inexact is such that o 971 # and inexact. and, the inexact is such that overflow occurred and was disabled 972 # but inexact was enabled. 972 # but inexact was enabled. 973 btst &unfl_bit,FPCR_ENABLE( 973 btst &unfl_bit,FPCR_ENABLE(%a6) 974 bne.b funfl_unfl_on 974 bne.b funfl_unfl_on 975 975 976 funfl_chkinex: 976 funfl_chkinex: 977 btst &inex2_bit,FPCR_ENABLE 977 btst &inex2_bit,FPCR_ENABLE(%a6) 978 bne.b funfl_inex_on 978 bne.b funfl_inex_on 979 979 980 funfl_exit: 980 funfl_exit: 981 fmovm.x EXC_FPREGS(%a6),&0xc0 981 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 982 fmovm.l USER_FPCR(%a6),%fpcr,% 982 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 983 movm.l EXC_DREGS(%a6),&0x0303 983 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 984 984 985 unlk %a6 985 unlk %a6 986 #$# add.l &24,%sp 986 #$# add.l &24,%sp 987 bra.l _fpsp_done 987 bra.l _fpsp_done 988 988 989 # overflow is enabled AND overflow, of course, 989 # overflow is enabled AND overflow, of course, occurred. so, we have the EXOP 990 # in fp1 (don't forget to save fp0). what to d 990 # in fp1 (don't forget to save fp0). what to do now? 991 # well, we simply have to get to go to _real_u 991 # well, we simply have to get to go to _real_unfl()! 992 funfl_unfl_on: 992 funfl_unfl_on: 993 993 994 # The `060 FPU multiplier hardware is such tha 994 # The `060 FPU multiplier hardware is such that if the result of a 995 # multiply operation is the smallest possible 995 # multiply operation is the smallest possible normalized number 996 # (0x00000000_80000000_00000000), then the mac 996 # (0x00000000_80000000_00000000), then the machine will take an 997 # underflow exception. Since this is incorrect 997 # underflow exception. Since this is incorrect, we check here to see 998 # if our emulation, after re-doing the operati 998 # if our emulation, after re-doing the operation, decided that 999 # no underflow was called for. 999 # no underflow was called for. 1000 btst &unfl_bit,FPSR_EXCEPT 1000 btst &unfl_bit,FPSR_EXCEPT(%a6) 1001 beq.w funfl_chkinex 1001 beq.w funfl_chkinex 1002 1002 1003 funfl_unfl_on2: 1003 funfl_unfl_on2: 1004 fmovm.x &0x40,FP_SRC(%a6) 1004 fmovm.x &0x40,FP_SRC(%a6) # save EXOP (fp1) to stack 1005 1005 1006 mov.w &0xe003,2+FP_SRC(%a6) 1006 mov.w &0xe003,2+FP_SRC(%a6) # save exc status 1007 1007 1008 fmovm.x EXC_FPREGS(%a6),&0xc0 1008 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 1009 fmovm.l USER_FPCR(%a6),%fpcr, 1009 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1010 movm.l EXC_DREGS(%a6),&0x030 1010 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1011 1011 1012 frestore FP_SRC(%a6) 1012 frestore FP_SRC(%a6) # do this after fmovm,other f<op>s! 1013 1013 1014 unlk %a6 1014 unlk %a6 1015 1015 1016 bra.l _real_unfl 1016 bra.l _real_unfl 1017 1017 1018 # underflow occurred but is disabled. meanwhi 1018 # underflow occurred but is disabled. meanwhile, inexact is enabled. Therefore, 1019 # we must jump to real_inex(). 1019 # we must jump to real_inex(). 1020 funfl_inex_on: 1020 funfl_inex_on: 1021 1021 1022 # The `060 FPU multiplier hardware is such th 1022 # The `060 FPU multiplier hardware is such that if the result of a 1023 # multiply operation is the smallest possible 1023 # multiply operation is the smallest possible normalized number 1024 # (0x00000000_80000000_00000000), then the ma 1024 # (0x00000000_80000000_00000000), then the machine will take an 1025 # underflow exception. 1025 # underflow exception. 1026 # But, whether bogus or not, if inexact is en 1026 # But, whether bogus or not, if inexact is enabled AND it occurred, 1027 # then we have to branch to real_inex. 1027 # then we have to branch to real_inex. 1028 1028 1029 btst &inex2_bit,FPSR_EXCEP 1029 btst &inex2_bit,FPSR_EXCEPT(%a6) 1030 beq.w funfl_exit 1030 beq.w funfl_exit 1031 1031 1032 funfl_inex_on2: 1032 funfl_inex_on2: 1033 1033 1034 fmovm.x &0x40,FP_SRC(%a6) 1034 fmovm.x &0x40,FP_SRC(%a6) # save EXOP to stack 1035 1035 1036 mov.b &0xc4,1+EXC_VOFF(%a6) 1036 mov.b &0xc4,1+EXC_VOFF(%a6) # vector offset = 0xc4 1037 mov.w &0xe001,2+FP_SRC(%a6) 1037 mov.w &0xe001,2+FP_SRC(%a6) # save exc status 1038 1038 1039 fmovm.x EXC_FPREGS(%a6),&0xc0 1039 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 1040 fmovm.l USER_FPCR(%a6),%fpcr, 1040 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1041 movm.l EXC_DREGS(%a6),&0x030 1041 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1042 1042 1043 frestore FP_SRC(%a6) 1043 frestore FP_SRC(%a6) # do this after fmovm,other f<op>s! 1044 1044 1045 unlk %a6 1045 unlk %a6 1046 1046 1047 bra.l _real_inex 1047 bra.l _real_inex 1048 1048 1049 ############################################# 1049 ####################################################################### 1050 funfl_out: 1050 funfl_out: 1051 1051 1052 1052 1053 #$# mov.l FP_SRC_EX(%a6),TRAP_S 1053 #$# mov.l FP_SRC_EX(%a6),TRAP_SRCOP_EX(%a6) 1054 #$# mov.l FP_SRC_HI(%a6),TRAP_S 1054 #$# mov.l FP_SRC_HI(%a6),TRAP_SRCOP_HI(%a6) 1055 #$# mov.l FP_SRC_LO(%a6),TRAP_S 1055 #$# mov.l FP_SRC_LO(%a6),TRAP_SRCOP_LO(%a6) 1056 1056 1057 # the src operand is definitely a NORM(!), so 1057 # the src operand is definitely a NORM(!), so tag it as such 1058 mov.b &NORM,STAG(%a6) 1058 mov.b &NORM,STAG(%a6) # set src optype tag 1059 1059 1060 clr.l %d0 1060 clr.l %d0 1061 mov.b FPCR_MODE(%a6),%d0 1061 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode 1062 1062 1063 and.l &0xffff00ff,USER_FPSR 1063 and.l &0xffff00ff,USER_FPSR(%a6) # zero all but accured field 1064 1064 1065 fmov.l &0x0,%fpcr 1065 fmov.l &0x0,%fpcr # zero current control regs 1066 fmov.l &0x0,%fpsr 1066 fmov.l &0x0,%fpsr 1067 1067 1068 lea FP_SRC(%a6),%a0 1068 lea FP_SRC(%a6),%a0 # pass ptr to src operand 1069 1069 1070 bsr.l fout 1070 bsr.l fout 1071 1071 1072 btst &unfl_bit,FPCR_ENABLE 1072 btst &unfl_bit,FPCR_ENABLE(%a6) 1073 bne.w funfl_unfl_on2 1073 bne.w funfl_unfl_on2 1074 1074 1075 btst &inex2_bit,FPCR_ENABL 1075 btst &inex2_bit,FPCR_ENABLE(%a6) 1076 bne.w funfl_inex_on2 1076 bne.w funfl_inex_on2 1077 1077 1078 fmovm.x EXC_FPREGS(%a6),&0xc0 1078 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 1079 fmovm.l USER_FPCR(%a6),%fpcr, 1079 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1080 movm.l EXC_DREGS(%a6),&0x030 1080 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1081 1081 1082 unlk %a6 1082 unlk %a6 1083 #$# add.l &24,%sp 1083 #$# add.l &24,%sp 1084 1084 1085 btst &0x7,(%sp) 1085 btst &0x7,(%sp) # is trace on? 1086 beq.l _fpsp_done 1086 beq.l _fpsp_done # no 1087 1087 1088 fmov.l %fpiar,0x8(%sp) 1088 fmov.l %fpiar,0x8(%sp) # "Current PC" is in FPIAR 1089 mov.w &0x2024,0x6(%sp) 1089 mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x024 1090 bra.l _real_trace 1090 bra.l _real_trace 1091 1091 1092 ############################################# 1092 ######################################################################### 1093 # XDEF ************************************** 1093 # XDEF **************************************************************** # 1094 # _fpsp_unsupp(): 060FPSP entry point f 1094 # _fpsp_unsupp(): 060FPSP entry point for FP "Unimplemented # 1095 # Data Type" exception. 1095 # Data Type" exception. # 1096 # 1096 # # 1097 # This handler should be the first code 1097 # This handler should be the first code executed upon taking the # 1098 # FP Unimplemented Data Type exception 1098 # FP Unimplemented Data Type exception in an operating system. # 1099 # 1099 # # 1100 # XREF ************************************** 1100 # XREF **************************************************************** # 1101 # _imem_read_{word,long}() - read instr 1101 # _imem_read_{word,long}() - read instruction word/longword # 1102 # fix_skewed_ops() - adjust src operand 1102 # fix_skewed_ops() - adjust src operand in fsave frame # 1103 # set_tag_x() - determine optype of src 1103 # set_tag_x() - determine optype of src/dst operands # 1104 # store_fpreg() - store opclass 0 or 2 1104 # store_fpreg() - store opclass 0 or 2 result to FP regfile # 1105 # unnorm_fix() - change UNNORM operands 1105 # unnorm_fix() - change UNNORM operands to NORM or ZERO # 1106 # load_fpn2() - load dst operand from F 1106 # load_fpn2() - load dst operand from FP regfile # 1107 # load_fpn1() - load src operand from F 1107 # load_fpn1() - load src operand from FP regfile # 1108 # fout() - emulate an opclass 3 instruc 1108 # fout() - emulate an opclass 3 instruction # 1109 # tbl_unsupp - add of table of emulatio 1109 # tbl_unsupp - add of table of emulation routines for opclass 0,2 # 1110 # _real_inex() - "callout" to operating 1110 # _real_inex() - "callout" to operating system inexact handler # 1111 # _fpsp_done() - "callout" for exit; wo 1111 # _fpsp_done() - "callout" for exit; work all done # 1112 # _real_trace() - "callout" for Trace e 1112 # _real_trace() - "callout" for Trace enabled exception # 1113 # funimp_skew() - adjust fsave src ops 1113 # funimp_skew() - adjust fsave src ops to "incorrect" value # 1114 # _real_snan() - "callout" for SNAN exc 1114 # _real_snan() - "callout" for SNAN exception # 1115 # _real_operr() - "callout" for OPERR e 1115 # _real_operr() - "callout" for OPERR exception # 1116 # _real_ovfl() - "callout" for OVFL exc 1116 # _real_ovfl() - "callout" for OVFL exception # 1117 # _real_unfl() - "callout" for UNFL exc 1117 # _real_unfl() - "callout" for UNFL exception # 1118 # get_packed() - fetch packed operand f 1118 # get_packed() - fetch packed operand from memory # 1119 # 1119 # # 1120 # INPUT ************************************* 1120 # INPUT *************************************************************** # 1121 # - The system stack contains the "Unim 1121 # - The system stack contains the "Unimp Data Type" stk frame # 1122 # - The fsave frame contains the ssrc o 1122 # - The fsave frame contains the ssrc op (for UNNORM/DENORM) # 1123 # 1123 # # 1124 # OUTPUT ************************************ 1124 # OUTPUT ************************************************************** # 1125 # If Inexact exception (opclass 3): 1125 # If Inexact exception (opclass 3): # 1126 # - The system stack is changed to an I 1126 # - The system stack is changed to an Inexact exception stk frame # 1127 # If SNAN exception (opclass 3): 1127 # If SNAN exception (opclass 3): # 1128 # - The system stack is changed to an S 1128 # - The system stack is changed to an SNAN exception stk frame # 1129 # If OPERR exception (opclass 3): 1129 # If OPERR exception (opclass 3): # 1130 # - The system stack is changed to an O 1130 # - The system stack is changed to an OPERR exception stk frame # 1131 # If OVFL exception (opclass 3): 1131 # If OVFL exception (opclass 3): # 1132 # - The system stack is changed to an O 1132 # - The system stack is changed to an OVFL exception stk frame # 1133 # If UNFL exception (opclass 3): 1133 # If UNFL exception (opclass 3): # 1134 # - The system stack is changed to an U 1134 # - The system stack is changed to an UNFL exception stack frame # 1135 # If Trace exception enabled: 1135 # If Trace exception enabled: # 1136 # - The system stack is changed to a Tr 1136 # - The system stack is changed to a Trace exception stack frame # 1137 # Else: (normal case) 1137 # Else: (normal case) # 1138 # - Correct result has been stored as a 1138 # - Correct result has been stored as appropriate # 1139 # 1139 # # 1140 # ALGORITHM ********************************* 1140 # ALGORITHM *********************************************************** # 1141 # Two main instruction types can enter 1141 # Two main instruction types can enter here: (1) DENORM or UNNORM # 1142 # unimplemented data types. These can be eith 1142 # unimplemented data types. These can be either opclass 0,2 or 3 # 1143 # instructions, and (2) PACKED unimplemented 1143 # instructions, and (2) PACKED unimplemented data format instructions # 1144 # also of opclasses 0,2, or 3. 1144 # also of opclasses 0,2, or 3. # 1145 # For UNNORM/DENORM opclass 0 and 2, th 1145 # For UNNORM/DENORM opclass 0 and 2, the handler fetches the src # 1146 # operand from the fsave state frame and the 1146 # operand from the fsave state frame and the dst operand (if dyadic) # 1147 # from the FP register file. The instruction 1147 # from the FP register file. The instruction is then emulated by # 1148 # choosing an emulation routine from a table 1148 # choosing an emulation routine from a table of routines indexed by # 1149 # instruction type. Once the instruction has 1149 # instruction type. Once the instruction has been emulated and result # 1150 # saved, then we check to see if any enabled 1150 # saved, then we check to see if any enabled exceptions resulted from # 1151 # instruction emulation. If none, then we exi 1151 # instruction emulation. If none, then we exit through the "callout" # 1152 # _fpsp_done(). If there is an enabled FP exc 1152 # _fpsp_done(). If there is an enabled FP exception, then we insert # 1153 # this exception into the FPU in the fsave st 1153 # this exception into the FPU in the fsave state frame and then exit # 1154 # through _fpsp_done(). 1154 # through _fpsp_done(). # 1155 # PACKED opclass 0 and 2 is similar in 1155 # PACKED opclass 0 and 2 is similar in how the instruction is # 1156 # emulated and exceptions handled. The differ 1156 # emulated and exceptions handled. The differences occur in how the # 1157 # handler loads the packed op (by calling get 1157 # handler loads the packed op (by calling get_packed() routine) and # 1158 # by the fact that a Trace exception could be 1158 # by the fact that a Trace exception could be pending for PACKED ops. # 1159 # If a Trace exception is pending, then the c 1159 # If a Trace exception is pending, then the current exception stack # 1160 # frame is changed to a Trace exception stack 1160 # frame is changed to a Trace exception stack frame and an exit is # 1161 # made through _real_trace(). 1161 # made through _real_trace(). # 1162 # For UNNORM/DENORM opclass 3, the actu 1162 # For UNNORM/DENORM opclass 3, the actual move out to memory is # 1163 # performed by calling the routine fout(). If 1163 # performed by calling the routine fout(). If no exception should occur # 1164 # as the result of emulation, then an exit ei 1164 # as the result of emulation, then an exit either occurs through # 1165 # _fpsp_done() or through _real_trace() if a 1165 # _fpsp_done() or through _real_trace() if a Trace exception is pending # 1166 # (a Trace stack frame must be created here, 1166 # (a Trace stack frame must be created here, too). If an FP exception # 1167 # should occur, then we must create an except 1167 # should occur, then we must create an exception stack frame of that # 1168 # type and jump to either _real_snan(), _real 1168 # type and jump to either _real_snan(), _real_operr(), _real_inex(), # 1169 # _real_unfl(), or _real_ovfl() as appropriat 1169 # _real_unfl(), or _real_ovfl() as appropriate. PACKED opclass 3 # 1170 # emulation is performed in a similar manner. 1170 # emulation is performed in a similar manner. # 1171 # 1171 # # 1172 ############################################# 1172 ######################################################################### 1173 1173 1174 # 1174 # 1175 # (1) DENORM and UNNORM (unimplemented) data 1175 # (1) DENORM and UNNORM (unimplemented) data types: 1176 # 1176 # 1177 # post-instruct 1177 # post-instruction 1178 # ************* 1178 # ***************** 1179 # * EA 1179 # * EA * 1180 # pre-instruction * 1180 # pre-instruction * * 1181 # ***************** ************* 1181 # ***************** ***************** 1182 # * 0x0 * 0x0dc * * 0x3 * 0x0d 1182 # * 0x0 * 0x0dc * * 0x3 * 0x0dc * 1183 # ***************** ************* 1183 # ***************** ***************** 1184 # * Next * * Next 1184 # * Next * * Next * 1185 # * PC * * PC 1185 # * PC * * PC * 1186 # ***************** ************* 1186 # ***************** ***************** 1187 # * SR * * SR 1187 # * SR * * SR * 1188 # ***************** ************* 1188 # ***************** ***************** 1189 # 1189 # 1190 # (2) PACKED format (unsupported) opclasses t 1190 # (2) PACKED format (unsupported) opclasses two and three: 1191 # ***************** 1191 # ***************** 1192 # * EA * 1192 # * EA * 1193 # * * 1193 # * * 1194 # ***************** 1194 # ***************** 1195 # * 0x2 * 0x0dc * 1195 # * 0x2 * 0x0dc * 1196 # ***************** 1196 # ***************** 1197 # * Next * 1197 # * Next * 1198 # * PC * 1198 # * PC * 1199 # ***************** 1199 # ***************** 1200 # * SR * 1200 # * SR * 1201 # ***************** 1201 # ***************** 1202 # 1202 # 1203 global _fpsp_unsupp 1203 global _fpsp_unsupp 1204 _fpsp_unsupp: 1204 _fpsp_unsupp: 1205 1205 1206 link.w %a6,&-LOCAL_SIZE 1206 link.w %a6,&-LOCAL_SIZE # init stack frame 1207 1207 1208 fsave FP_SRC(%a6) 1208 fsave FP_SRC(%a6) # save fp state 1209 1209 1210 movm.l &0x0303,EXC_DREGS(%a6 1210 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 1211 fmovm.l %fpcr,%fpsr,%fpiar,US 1211 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 1212 fmovm.x &0xc0,EXC_FPREGS(%a6) 1212 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 1213 1213 1214 btst &0x5,EXC_SR(%a6) 1214 btst &0x5,EXC_SR(%a6) # user or supervisor mode? 1215 bne.b fu_s 1215 bne.b fu_s 1216 fu_u: 1216 fu_u: 1217 mov.l %usp,%a0 1217 mov.l %usp,%a0 # fetch user stack pointer 1218 mov.l %a0,EXC_A7(%a6) 1218 mov.l %a0,EXC_A7(%a6) # save on stack 1219 bra.b fu_cont 1219 bra.b fu_cont 1220 # if the exception is an opclass zero or two 1220 # if the exception is an opclass zero or two unimplemented data type 1221 # exception, then the a7' calculated here is 1221 # exception, then the a7' calculated here is wrong since it doesn't 1222 # stack an ea. however, we don't need an a7' 1222 # stack an ea. however, we don't need an a7' for this case anyways. 1223 fu_s: 1223 fu_s: 1224 lea 0x4+EXC_EA(%a6),%a0 1224 lea 0x4+EXC_EA(%a6),%a0 # load old a7' 1225 mov.l %a0,EXC_A7(%a6) 1225 mov.l %a0,EXC_A7(%a6) # save on stack 1226 1226 1227 fu_cont: 1227 fu_cont: 1228 1228 1229 # the FPIAR holds the "current PC" of the fau 1229 # the FPIAR holds the "current PC" of the faulting instruction 1230 # the FPIAR should be set correctly for ALL e 1230 # the FPIAR should be set correctly for ALL exceptions passing through 1231 # this point. 1231 # this point. 1232 mov.l USER_FPIAR(%a6),EXC_E 1232 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 1233 mov.l EXC_EXTWPTR(%a6),%a0 1233 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 1234 addq.l &0x4,EXC_EXTWPTR(%a6) 1234 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 1235 bsr.l _imem_read_long 1235 bsr.l _imem_read_long # fetch the instruction words 1236 mov.l %d0,EXC_OPWORD(%a6) 1236 mov.l %d0,EXC_OPWORD(%a6) # store OPWORD and EXTWORD 1237 1237 1238 ############################ 1238 ############################ 1239 1239 1240 clr.b SPCOND_FLG(%a6) 1240 clr.b SPCOND_FLG(%a6) # clear special condition flag 1241 1241 1242 # Separate opclass three (fpn-to-mem) ops sin 1242 # Separate opclass three (fpn-to-mem) ops since they have a different 1243 # stack frame and protocol. 1243 # stack frame and protocol. 1244 btst &0x5,EXC_CMDREG(%a6) 1244 btst &0x5,EXC_CMDREG(%a6) # is it an fmove out? 1245 bne.w fu_out 1245 bne.w fu_out # yes 1246 1246 1247 # Separate packed opclass two instructions. 1247 # Separate packed opclass two instructions. 1248 bfextu EXC_CMDREG(%a6){&0:&6 1248 bfextu EXC_CMDREG(%a6){&0:&6},%d0 1249 cmpi.b %d0,&0x13 1249 cmpi.b %d0,&0x13 1250 beq.w fu_in_pack 1250 beq.w fu_in_pack 1251 1251 1252 1252 1253 # I'm not sure at this point what FPSR bits a 1253 # I'm not sure at this point what FPSR bits are valid for this instruction. 1254 # so, since the emulation routines re-create 1254 # so, since the emulation routines re-create them anyways, zero exception field 1255 andi.l &0x00ff00ff,USER_FPSR 1255 andi.l &0x00ff00ff,USER_FPSR(%a6) # zero exception field 1256 1256 1257 fmov.l &0x0,%fpcr 1257 fmov.l &0x0,%fpcr # zero current control regs 1258 fmov.l &0x0,%fpsr 1258 fmov.l &0x0,%fpsr 1259 1259 1260 # Opclass two w/ memory-to-fpn operation will 1260 # Opclass two w/ memory-to-fpn operation will have an incorrect extended 1261 # precision format if the src format was sing 1261 # precision format if the src format was single or double and the 1262 # source data type was an INF, NAN, DENORM, o 1262 # source data type was an INF, NAN, DENORM, or UNNORM 1263 lea FP_SRC(%a6),%a0 1263 lea FP_SRC(%a6),%a0 # pass ptr to input 1264 bsr.l fix_skewed_ops 1264 bsr.l fix_skewed_ops 1265 1265 1266 # we don't know whether the src operand or th 1266 # we don't know whether the src operand or the dst operand (or both) is the 1267 # UNNORM or DENORM. call the function that ta 1267 # UNNORM or DENORM. call the function that tags the operand type. if the 1268 # input is an UNNORM, then convert it to a NO 1268 # input is an UNNORM, then convert it to a NORM, DENORM, or ZERO. 1269 lea FP_SRC(%a6),%a0 1269 lea FP_SRC(%a6),%a0 # pass: ptr to src op 1270 bsr.l set_tag_x 1270 bsr.l set_tag_x # tag the operand type 1271 cmpi.b %d0,&UNNORM 1271 cmpi.b %d0,&UNNORM # is operand an UNNORM? 1272 bne.b fu_op2 1272 bne.b fu_op2 # no 1273 bsr.l unnorm_fix 1273 bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO 1274 1274 1275 fu_op2: 1275 fu_op2: 1276 mov.b %d0,STAG(%a6) 1276 mov.b %d0,STAG(%a6) # save src optype tag 1277 1277 1278 bfextu EXC_CMDREG(%a6){&6:&3 1278 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg 1279 1279 1280 # bit five of the fp extension word separates 1280 # bit five of the fp extension word separates the monadic and dyadic operations 1281 # at this point 1281 # at this point 1282 btst &0x5,1+EXC_CMDREG(%a6 1282 btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic? 1283 beq.b fu_extract 1283 beq.b fu_extract # monadic 1284 cmpi.b 1+EXC_CMDREG(%a6),&0x 1284 cmpi.b 1+EXC_CMDREG(%a6),&0x3a # is operation an ftst? 1285 beq.b fu_extract 1285 beq.b fu_extract # yes, so it's monadic, too 1286 1286 1287 bsr.l load_fpn2 1287 bsr.l load_fpn2 # load dst into FP_DST 1288 1288 1289 lea FP_DST(%a6),%a0 1289 lea FP_DST(%a6),%a0 # pass: ptr to dst op 1290 bsr.l set_tag_x 1290 bsr.l set_tag_x # tag the operand type 1291 cmpi.b %d0,&UNNORM 1291 cmpi.b %d0,&UNNORM # is operand an UNNORM? 1292 bne.b fu_op2_done 1292 bne.b fu_op2_done # no 1293 bsr.l unnorm_fix 1293 bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO 1294 fu_op2_done: 1294 fu_op2_done: 1295 mov.b %d0,DTAG(%a6) 1295 mov.b %d0,DTAG(%a6) # save dst optype tag 1296 1296 1297 fu_extract: 1297 fu_extract: 1298 clr.l %d0 1298 clr.l %d0 1299 mov.b FPCR_MODE(%a6),%d0 1299 mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec 1300 1300 1301 bfextu 1+EXC_CMDREG(%a6){&1: 1301 bfextu 1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension 1302 1302 1303 lea FP_SRC(%a6),%a0 1303 lea FP_SRC(%a6),%a0 1304 lea FP_DST(%a6),%a1 1304 lea FP_DST(%a6),%a1 1305 1305 1306 mov.l (tbl_unsupp.l,%pc,%d1 1306 mov.l (tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr 1307 jsr (tbl_unsupp.l,%pc,%d1 1307 jsr (tbl_unsupp.l,%pc,%d1.l*1) 1308 1308 1309 # 1309 # 1310 # Exceptions in order of precedence: 1310 # Exceptions in order of precedence: 1311 # BSUN : none 1311 # BSUN : none 1312 # SNAN : all dyadic ops 1312 # SNAN : all dyadic ops 1313 # OPERR : fsqrt(-NORM) 1313 # OPERR : fsqrt(-NORM) 1314 # OVFL : all except ftst,fcmp 1314 # OVFL : all except ftst,fcmp 1315 # UNFL : all except ftst,fcmp 1315 # UNFL : all except ftst,fcmp 1316 # DZ : fdiv 1316 # DZ : fdiv 1317 # INEX2 : all except ftst,fcmp 1317 # INEX2 : all except ftst,fcmp 1318 # INEX1 : none (packed doesn't go thr 1318 # INEX1 : none (packed doesn't go through here) 1319 # 1319 # 1320 1320 1321 # we determine the highest priority exception 1321 # we determine the highest priority exception(if any) set by the 1322 # emulation routine that has also been enable 1322 # emulation routine that has also been enabled by the user. 1323 mov.b FPCR_ENABLE(%a6),%d0 1323 mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions set 1324 bne.b fu_in_ena 1324 bne.b fu_in_ena # some are enabled 1325 1325 1326 fu_in_cont: 1326 fu_in_cont: 1327 # fcmp and ftst do not store any result. 1327 # fcmp and ftst do not store any result. 1328 mov.b 1+EXC_CMDREG(%a6),%d0 1328 mov.b 1+EXC_CMDREG(%a6),%d0 # fetch extension 1329 andi.b &0x38,%d0 1329 andi.b &0x38,%d0 # extract bits 3-5 1330 cmpi.b %d0,&0x38 1330 cmpi.b %d0,&0x38 # is instr fcmp or ftst? 1331 beq.b fu_in_exit 1331 beq.b fu_in_exit # yes 1332 1332 1333 bfextu EXC_CMDREG(%a6){&6:&3 1333 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg 1334 bsr.l store_fpreg 1334 bsr.l store_fpreg # store the result 1335 1335 1336 fu_in_exit: 1336 fu_in_exit: 1337 1337 1338 fmovm.x EXC_FPREGS(%a6),&0xc0 1338 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1339 fmovm.l USER_FPCR(%a6),%fpcr, 1339 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1340 movm.l EXC_DREGS(%a6),&0x030 1340 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1341 1341 1342 unlk %a6 1342 unlk %a6 1343 1343 1344 bra.l _fpsp_done 1344 bra.l _fpsp_done 1345 1345 1346 fu_in_ena: 1346 fu_in_ena: 1347 and.b FPSR_EXCEPT(%a6),%d0 1347 and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled 1348 bfffo %d0{&24:&8},%d0 1348 bfffo %d0{&24:&8},%d0 # find highest priority exception 1349 bne.b fu_in_exc 1349 bne.b fu_in_exc # there is at least one set 1350 1350 1351 # 1351 # 1352 # No exceptions occurred that were also enabl 1352 # No exceptions occurred that were also enabled. Now: 1353 # 1353 # 1354 # if (OVFL && ovfl_disabled && inexact_ 1354 # if (OVFL && ovfl_disabled && inexact_enabled) { 1355 # branch to _real_inex() (even if t 1355 # branch to _real_inex() (even if the result was exact!); 1356 # } else { 1356 # } else { 1357 # save the result in the proper fp 1357 # save the result in the proper fp reg (unless the op is fcmp or ftst); 1358 # return; 1358 # return; 1359 # } 1359 # } 1360 # 1360 # 1361 btst &ovfl_bit,FPSR_EXCEPT 1361 btst &ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set? 1362 beq.b fu_in_cont 1362 beq.b fu_in_cont # no 1363 1363 1364 fu_in_ovflchk: 1364 fu_in_ovflchk: 1365 btst &inex2_bit,FPCR_ENABL 1365 btst &inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled? 1366 beq.b fu_in_cont 1366 beq.b fu_in_cont # no 1367 bra.w fu_in_exc_ovfl 1367 bra.w fu_in_exc_ovfl # go insert overflow frame 1368 1368 1369 # 1369 # 1370 # An exception occurred and that exception wa 1370 # An exception occurred and that exception was enabled: 1371 # 1371 # 1372 # shift enabled exception field into lo 1372 # shift enabled exception field into lo byte of d0; 1373 # if (((INEX2 || INEX1) && inex_enabled 1373 # if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) || 1374 # ((INEX2 || INEX1) && inex_enabled 1374 # ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) { 1375 # /* 1375 # /* 1376 # * this is the case where we 1376 # * this is the case where we must call _real_inex() now or else 1377 # * there will be no other way 1377 # * there will be no other way to pass it the exceptional operand 1378 # */ 1378 # */ 1379 # call _real_inex(); 1379 # call _real_inex(); 1380 # } else { 1380 # } else { 1381 # restore exc state (SNAN||OPER 1381 # restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU; 1382 # } 1382 # } 1383 # 1383 # 1384 fu_in_exc: 1384 fu_in_exc: 1385 subi.l &24,%d0 1385 subi.l &24,%d0 # fix offset to be 0-8 1386 cmpi.b %d0,&0x6 1386 cmpi.b %d0,&0x6 # is exception INEX? (6) 1387 bne.b fu_in_exc_exit 1387 bne.b fu_in_exc_exit # no 1388 1388 1389 # the enabled exception was inexact 1389 # the enabled exception was inexact 1390 btst &unfl_bit,FPSR_EXCEPT 1390 btst &unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur? 1391 bne.w fu_in_exc_unfl 1391 bne.w fu_in_exc_unfl # yes 1392 btst &ovfl_bit,FPSR_EXCEPT 1392 btst &ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur? 1393 bne.w fu_in_exc_ovfl 1393 bne.w fu_in_exc_ovfl # yes 1394 1394 1395 # here, we insert the correct fsave status va 1395 # here, we insert the correct fsave status value into the fsave frame for the 1396 # corresponding exception. the operand in the 1396 # corresponding exception. the operand in the fsave frame should be the original 1397 # src operand. 1397 # src operand. 1398 fu_in_exc_exit: 1398 fu_in_exc_exit: 1399 mov.l %d0,-(%sp) 1399 mov.l %d0,-(%sp) # save d0 1400 bsr.l funimp_skew 1400 bsr.l funimp_skew # skew sgl or dbl inputs 1401 mov.l (%sp)+,%d0 1401 mov.l (%sp)+,%d0 # restore d0 1402 1402 1403 mov.w (tbl_except.b,%pc,%d0 1403 mov.w (tbl_except.b,%pc,%d0.w*2),2+FP_SRC(%a6) # create exc status 1404 1404 1405 fmovm.x EXC_FPREGS(%a6),&0xc0 1405 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1406 fmovm.l USER_FPCR(%a6),%fpcr, 1406 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1407 movm.l EXC_DREGS(%a6),&0x030 1407 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1408 1408 1409 frestore FP_SRC(%a6) 1409 frestore FP_SRC(%a6) # restore src op 1410 1410 1411 unlk %a6 1411 unlk %a6 1412 1412 1413 bra.l _fpsp_done 1413 bra.l _fpsp_done 1414 1414 1415 tbl_except: 1415 tbl_except: 1416 short 0xe000,0xe006,0xe004, 1416 short 0xe000,0xe006,0xe004,0xe005 1417 short 0xe003,0xe002,0xe001, 1417 short 0xe003,0xe002,0xe001,0xe001 1418 1418 1419 fu_in_exc_unfl: 1419 fu_in_exc_unfl: 1420 mov.w &0x4,%d0 1420 mov.w &0x4,%d0 1421 bra.b fu_in_exc_exit 1421 bra.b fu_in_exc_exit 1422 fu_in_exc_ovfl: 1422 fu_in_exc_ovfl: 1423 mov.w &0x03,%d0 1423 mov.w &0x03,%d0 1424 bra.b fu_in_exc_exit 1424 bra.b fu_in_exc_exit 1425 1425 1426 # If the input operand to this operation was 1426 # If the input operand to this operation was opclass two and a single 1427 # or double precision denorm, inf, or nan, th 1427 # or double precision denorm, inf, or nan, the operand needs to be 1428 # "corrected" in order to have the proper equ 1428 # "corrected" in order to have the proper equivalent extended precision 1429 # number. 1429 # number. 1430 global fix_skewed_ops 1430 global fix_skewed_ops 1431 fix_skewed_ops: 1431 fix_skewed_ops: 1432 bfextu EXC_CMDREG(%a6){&0:&6 1432 bfextu EXC_CMDREG(%a6){&0:&6},%d0 # extract opclass,src fmt 1433 cmpi.b %d0,&0x11 1433 cmpi.b %d0,&0x11 # is class = 2 & fmt = sgl? 1434 beq.b fso_sgl 1434 beq.b fso_sgl # yes 1435 cmpi.b %d0,&0x15 1435 cmpi.b %d0,&0x15 # is class = 2 & fmt = dbl? 1436 beq.b fso_dbl 1436 beq.b fso_dbl # yes 1437 rts 1437 rts # no 1438 1438 1439 fso_sgl: 1439 fso_sgl: 1440 mov.w LOCAL_EX(%a0),%d0 1440 mov.w LOCAL_EX(%a0),%d0 # fetch src exponent 1441 andi.w &0x7fff,%d0 1441 andi.w &0x7fff,%d0 # strip sign 1442 cmpi.w %d0,&0x3f80 1442 cmpi.w %d0,&0x3f80 # is |exp| == $3f80? 1443 beq.b fso_sgl_dnrm_zero 1443 beq.b fso_sgl_dnrm_zero # yes 1444 cmpi.w %d0,&0x407f 1444 cmpi.w %d0,&0x407f # no; is |exp| == $407f? 1445 beq.b fso_infnan 1445 beq.b fso_infnan # yes 1446 rts 1446 rts # no 1447 1447 1448 fso_sgl_dnrm_zero: 1448 fso_sgl_dnrm_zero: 1449 andi.l &0x7fffffff,LOCAL_HI( 1449 andi.l &0x7fffffff,LOCAL_HI(%a0) # clear j-bit 1450 beq.b fso_zero 1450 beq.b fso_zero # it's a skewed zero 1451 fso_sgl_dnrm: 1451 fso_sgl_dnrm: 1452 # here, we count on norm not to alter a0... 1452 # here, we count on norm not to alter a0... 1453 bsr.l norm 1453 bsr.l norm # normalize mantissa 1454 neg.w %d0 1454 neg.w %d0 # -shft amt 1455 addi.w &0x3f81,%d0 1455 addi.w &0x3f81,%d0 # adjust new exponent 1456 andi.w &0x8000,LOCAL_EX(%a0) 1456 andi.w &0x8000,LOCAL_EX(%a0) # clear old exponent 1457 or.w %d0,LOCAL_EX(%a0) 1457 or.w %d0,LOCAL_EX(%a0) # insert new exponent 1458 rts 1458 rts 1459 1459 1460 fso_zero: 1460 fso_zero: 1461 andi.w &0x8000,LOCAL_EX(%a0) 1461 andi.w &0x8000,LOCAL_EX(%a0) # clear bogus exponent 1462 rts 1462 rts 1463 1463 1464 fso_infnan: 1464 fso_infnan: 1465 andi.b &0x7f,LOCAL_HI(%a0) 1465 andi.b &0x7f,LOCAL_HI(%a0) # clear j-bit 1466 ori.w &0x7fff,LOCAL_EX(%a0) 1466 ori.w &0x7fff,LOCAL_EX(%a0) # make exponent = $7fff 1467 rts 1467 rts 1468 1468 1469 fso_dbl: 1469 fso_dbl: 1470 mov.w LOCAL_EX(%a0),%d0 1470 mov.w LOCAL_EX(%a0),%d0 # fetch src exponent 1471 andi.w &0x7fff,%d0 1471 andi.w &0x7fff,%d0 # strip sign 1472 cmpi.w %d0,&0x3c00 1472 cmpi.w %d0,&0x3c00 # is |exp| == $3c00? 1473 beq.b fso_dbl_dnrm_zero 1473 beq.b fso_dbl_dnrm_zero # yes 1474 cmpi.w %d0,&0x43ff 1474 cmpi.w %d0,&0x43ff # no; is |exp| == $43ff? 1475 beq.b fso_infnan 1475 beq.b fso_infnan # yes 1476 rts 1476 rts # no 1477 1477 1478 fso_dbl_dnrm_zero: 1478 fso_dbl_dnrm_zero: 1479 andi.l &0x7fffffff,LOCAL_HI( 1479 andi.l &0x7fffffff,LOCAL_HI(%a0) # clear j-bit 1480 bne.b fso_dbl_dnrm 1480 bne.b fso_dbl_dnrm # it's a skewed denorm 1481 tst.l LOCAL_LO(%a0) 1481 tst.l LOCAL_LO(%a0) # is it a zero? 1482 beq.b fso_zero 1482 beq.b fso_zero # yes 1483 fso_dbl_dnrm: 1483 fso_dbl_dnrm: 1484 # here, we count on norm not to alter a0... 1484 # here, we count on norm not to alter a0... 1485 bsr.l norm 1485 bsr.l norm # normalize mantissa 1486 neg.w %d0 1486 neg.w %d0 # -shft amt 1487 addi.w &0x3c01,%d0 1487 addi.w &0x3c01,%d0 # adjust new exponent 1488 andi.w &0x8000,LOCAL_EX(%a0) 1488 andi.w &0x8000,LOCAL_EX(%a0) # clear old exponent 1489 or.w %d0,LOCAL_EX(%a0) 1489 or.w %d0,LOCAL_EX(%a0) # insert new exponent 1490 rts 1490 rts 1491 1491 1492 ############################################# 1492 ################################################################# 1493 1493 1494 # fmove out took an unimplemented data type e 1494 # fmove out took an unimplemented data type exception. 1495 # the src operand is in FP_SRC. Call _fout() 1495 # the src operand is in FP_SRC. Call _fout() to write out the result and 1496 # to determine which exceptions, if any, to t 1496 # to determine which exceptions, if any, to take. 1497 fu_out: 1497 fu_out: 1498 1498 1499 # Separate packed move outs from the UNNORM a 1499 # Separate packed move outs from the UNNORM and DENORM move outs. 1500 bfextu EXC_CMDREG(%a6){&3:&3 1500 bfextu EXC_CMDREG(%a6){&3:&3},%d0 1501 cmpi.b %d0,&0x3 1501 cmpi.b %d0,&0x3 1502 beq.w fu_out_pack 1502 beq.w fu_out_pack 1503 cmpi.b %d0,&0x7 1503 cmpi.b %d0,&0x7 1504 beq.w fu_out_pack 1504 beq.w fu_out_pack 1505 1505 1506 1506 1507 # I'm not sure at this point what FPSR bits a 1507 # I'm not sure at this point what FPSR bits are valid for this instruction. 1508 # so, since the emulation routines re-create 1508 # so, since the emulation routines re-create them anyways, zero exception field. 1509 # fmove out doesn't affect ccodes. 1509 # fmove out doesn't affect ccodes. 1510 and.l &0xffff00ff,USER_FPSR 1510 and.l &0xffff00ff,USER_FPSR(%a6) # zero exception field 1511 1511 1512 fmov.l &0x0,%fpcr 1512 fmov.l &0x0,%fpcr # zero current control regs 1513 fmov.l &0x0,%fpsr 1513 fmov.l &0x0,%fpsr 1514 1514 1515 # the src can ONLY be a DENORM or an UNNORM! 1515 # the src can ONLY be a DENORM or an UNNORM! so, don't make any big subroutine 1516 # call here. just figure out what it is... 1516 # call here. just figure out what it is... 1517 mov.w FP_SRC_EX(%a6),%d0 1517 mov.w FP_SRC_EX(%a6),%d0 # get exponent 1518 andi.w &0x7fff,%d0 1518 andi.w &0x7fff,%d0 # strip sign 1519 beq.b fu_out_denorm 1519 beq.b fu_out_denorm # it's a DENORM 1520 1520 1521 lea FP_SRC(%a6),%a0 1521 lea FP_SRC(%a6),%a0 1522 bsr.l unnorm_fix 1522 bsr.l unnorm_fix # yes; fix it 1523 1523 1524 mov.b %d0,STAG(%a6) 1524 mov.b %d0,STAG(%a6) 1525 1525 1526 bra.b fu_out_cont 1526 bra.b fu_out_cont 1527 fu_out_denorm: 1527 fu_out_denorm: 1528 mov.b &DENORM,STAG(%a6) 1528 mov.b &DENORM,STAG(%a6) 1529 fu_out_cont: 1529 fu_out_cont: 1530 1530 1531 clr.l %d0 1531 clr.l %d0 1532 mov.b FPCR_MODE(%a6),%d0 1532 mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec 1533 1533 1534 lea FP_SRC(%a6),%a0 1534 lea FP_SRC(%a6),%a0 # pass ptr to src operand 1535 1535 1536 mov.l (%a6),EXC_A6(%a6) 1536 mov.l (%a6),EXC_A6(%a6) # in case a6 changes 1537 bsr.l fout 1537 bsr.l fout # call fmove out routine 1538 1538 1539 # Exceptions in order of precedence: 1539 # Exceptions in order of precedence: 1540 # BSUN : none 1540 # BSUN : none 1541 # SNAN : none 1541 # SNAN : none 1542 # OPERR : fmove.{b,w,l} out of large 1542 # OPERR : fmove.{b,w,l} out of large UNNORM 1543 # OVFL : fmove.{s,d} 1543 # OVFL : fmove.{s,d} 1544 # UNFL : fmove.{s,d,x} 1544 # UNFL : fmove.{s,d,x} 1545 # DZ : none 1545 # DZ : none 1546 # INEX2 : all 1546 # INEX2 : all 1547 # INEX1 : none (packed doesn't travel 1547 # INEX1 : none (packed doesn't travel through here) 1548 1548 1549 # determine the highest priority exception(if 1549 # determine the highest priority exception(if any) set by the 1550 # emulation routine that has also been enable 1550 # emulation routine that has also been enabled by the user. 1551 mov.b FPCR_ENABLE(%a6),%d0 1551 mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled 1552 bne.w fu_out_ena 1552 bne.w fu_out_ena # some are enabled 1553 1553 1554 fu_out_done: 1554 fu_out_done: 1555 1555 1556 mov.l EXC_A6(%a6),(%a6) 1556 mov.l EXC_A6(%a6),(%a6) # in case a6 changed 1557 1557 1558 # on extended precision opclass three instruc 1558 # on extended precision opclass three instructions using pre-decrement or 1559 # post-increment addressing mode, the address 1559 # post-increment addressing mode, the address register is not updated. is the 1560 # address register was the stack pointer used 1560 # address register was the stack pointer used from user mode, then let's update 1561 # it here. if it was used from supervisor mod 1561 # it here. if it was used from supervisor mode, then we have to handle this 1562 # as a special case. 1562 # as a special case. 1563 btst &0x5,EXC_SR(%a6) 1563 btst &0x5,EXC_SR(%a6) 1564 bne.b fu_out_done_s 1564 bne.b fu_out_done_s 1565 1565 1566 mov.l EXC_A7(%a6),%a0 1566 mov.l EXC_A7(%a6),%a0 # restore a7 1567 mov.l %a0,%usp 1567 mov.l %a0,%usp 1568 1568 1569 fu_out_done_cont: 1569 fu_out_done_cont: 1570 fmovm.x EXC_FPREGS(%a6),&0xc0 1570 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1571 fmovm.l USER_FPCR(%a6),%fpcr, 1571 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1572 movm.l EXC_DREGS(%a6),&0x030 1572 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1573 1573 1574 unlk %a6 1574 unlk %a6 1575 1575 1576 btst &0x7,(%sp) 1576 btst &0x7,(%sp) # is trace on? 1577 bne.b fu_out_trace 1577 bne.b fu_out_trace # yes 1578 1578 1579 bra.l _fpsp_done 1579 bra.l _fpsp_done 1580 1580 1581 # is the ea mode pre-decrement of the stack p 1581 # is the ea mode pre-decrement of the stack pointer from supervisor mode? 1582 # ("fmov.x fpm,-(a7)") if so, 1582 # ("fmov.x fpm,-(a7)") if so, 1583 fu_out_done_s: 1583 fu_out_done_s: 1584 cmpi.b SPCOND_FLG(%a6),&mda7 1584 cmpi.b SPCOND_FLG(%a6),&mda7_flg 1585 bne.b fu_out_done_cont 1585 bne.b fu_out_done_cont 1586 1586 1587 # the extended precision result is still in f 1587 # the extended precision result is still in fp0. but, we need to save it 1588 # somewhere on the stack until we can copy it 1588 # somewhere on the stack until we can copy it to its final resting place. 1589 # here, we're counting on the top of the stac 1589 # here, we're counting on the top of the stack to be the old place-holders 1590 # for fp0/fp1 which have already been restore 1590 # for fp0/fp1 which have already been restored. that way, we can write 1591 # over those destinations with the shifted st 1591 # over those destinations with the shifted stack frame. 1592 fmovm.x &0x80,FP_SRC(%a6) 1592 fmovm.x &0x80,FP_SRC(%a6) # put answer on stack 1593 1593 1594 fmovm.x EXC_FPREGS(%a6),&0xc0 1594 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1595 fmovm.l USER_FPCR(%a6),%fpcr, 1595 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1596 movm.l EXC_DREGS(%a6),&0x030 1596 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1597 1597 1598 mov.l (%a6),%a6 1598 mov.l (%a6),%a6 # restore frame pointer 1599 1599 1600 mov.l LOCAL_SIZE+EXC_SR(%sp 1600 mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp) 1601 mov.l LOCAL_SIZE+2+EXC_PC(% 1601 mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp) 1602 1602 1603 # now, copy the result to the proper place on 1603 # now, copy the result to the proper place on the stack 1604 mov.l LOCAL_SIZE+FP_SRC_EX( 1604 mov.l LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp) 1605 mov.l LOCAL_SIZE+FP_SRC_HI( 1605 mov.l LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp) 1606 mov.l LOCAL_SIZE+FP_SRC_LO( 1606 mov.l LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp) 1607 1607 1608 add.l &LOCAL_SIZE-0x8,%sp 1608 add.l &LOCAL_SIZE-0x8,%sp 1609 1609 1610 btst &0x7,(%sp) 1610 btst &0x7,(%sp) 1611 bne.b fu_out_trace 1611 bne.b fu_out_trace 1612 1612 1613 bra.l _fpsp_done 1613 bra.l _fpsp_done 1614 1614 1615 fu_out_ena: 1615 fu_out_ena: 1616 and.b FPSR_EXCEPT(%a6),%d0 1616 and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled 1617 bfffo %d0{&24:&8},%d0 1617 bfffo %d0{&24:&8},%d0 # find highest priority exception 1618 bne.b fu_out_exc 1618 bne.b fu_out_exc # there is at least one set 1619 1619 1620 # no exceptions were set. 1620 # no exceptions were set. 1621 # if a disabled overflow occurred and inexact 1621 # if a disabled overflow occurred and inexact was enabled but the result 1622 # was exact, then a branch to _real_inex() is 1622 # was exact, then a branch to _real_inex() is made. 1623 btst &ovfl_bit,FPSR_EXCEPT 1623 btst &ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set? 1624 beq.w fu_out_done 1624 beq.w fu_out_done # no 1625 1625 1626 fu_out_ovflchk: 1626 fu_out_ovflchk: 1627 btst &inex2_bit,FPCR_ENABL 1627 btst &inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled? 1628 beq.w fu_out_done 1628 beq.w fu_out_done # no 1629 bra.w fu_inex 1629 bra.w fu_inex # yes 1630 1630 1631 # 1631 # 1632 # The fp move out that took the "Unimplemente 1632 # The fp move out that took the "Unimplemented Data Type" exception was 1633 # being traced. Since the stack frames are si 1633 # being traced. Since the stack frames are similar, get the "current" PC 1634 # from FPIAR and put it in the trace stack fr 1634 # from FPIAR and put it in the trace stack frame then jump to _real_trace(). 1635 # 1635 # 1636 # UNSUPP FRAME TR 1636 # UNSUPP FRAME TRACE FRAME 1637 # ***************** ***** 1637 # ***************** ***************** 1638 # * EA * * 1638 # * EA * * Current * 1639 # * * * 1639 # * * * PC * 1640 # ***************** ***** 1640 # ***************** ***************** 1641 # * 0x3 * 0x0dc * * 0x2 1641 # * 0x3 * 0x0dc * * 0x2 * 0x024 * 1642 # ***************** ***** 1642 # ***************** ***************** 1643 # * Next * * 1643 # * Next * * Next * 1644 # * PC * * 1644 # * PC * * PC * 1645 # ***************** ***** 1645 # ***************** ***************** 1646 # * SR * * 1646 # * SR * * SR * 1647 # ***************** ***** 1647 # ***************** ***************** 1648 # 1648 # 1649 fu_out_trace: 1649 fu_out_trace: 1650 mov.w &0x2024,0x6(%sp) 1650 mov.w &0x2024,0x6(%sp) 1651 fmov.l %fpiar,0x8(%sp) 1651 fmov.l %fpiar,0x8(%sp) 1652 bra.l _real_trace 1652 bra.l _real_trace 1653 1653 1654 # an exception occurred and that exception wa 1654 # an exception occurred and that exception was enabled. 1655 fu_out_exc: 1655 fu_out_exc: 1656 subi.l &24,%d0 1656 subi.l &24,%d0 # fix offset to be 0-8 1657 1657 1658 # we don't mess with the existing fsave frame 1658 # we don't mess with the existing fsave frame. just re-insert it and 1659 # jump to the "_real_{}()" handler... 1659 # jump to the "_real_{}()" handler... 1660 mov.w (tbl_fu_out.b,%pc,%d0 1660 mov.w (tbl_fu_out.b,%pc,%d0.w*2),%d0 1661 jmp (tbl_fu_out.b,%pc,%d0 1661 jmp (tbl_fu_out.b,%pc,%d0.w*1) 1662 1662 1663 swbeg &0x8 1663 swbeg &0x8 1664 tbl_fu_out: 1664 tbl_fu_out: 1665 short tbl_fu_out - tbl 1665 short tbl_fu_out - tbl_fu_out # BSUN can't happen 1666 short tbl_fu_out - tbl 1666 short tbl_fu_out - tbl_fu_out # SNAN can't happen 1667 short fu_operr - tbl 1667 short fu_operr - tbl_fu_out # OPERR 1668 short fu_ovfl - tbl 1668 short fu_ovfl - tbl_fu_out # OVFL 1669 short fu_unfl - tbl 1669 short fu_unfl - tbl_fu_out # UNFL 1670 short tbl_fu_out - tbl 1670 short tbl_fu_out - tbl_fu_out # DZ can't happen 1671 short fu_inex - tbl 1671 short fu_inex - tbl_fu_out # INEX2 1672 short tbl_fu_out - tbl 1672 short tbl_fu_out - tbl_fu_out # INEX1 won't make it here 1673 1673 1674 # for snan,operr,ovfl,unfl, src op is still i 1674 # for snan,operr,ovfl,unfl, src op is still in FP_SRC so just 1675 # frestore it. 1675 # frestore it. 1676 fu_snan: 1676 fu_snan: 1677 fmovm.x EXC_FPREGS(%a6),&0xc0 1677 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1678 fmovm.l USER_FPCR(%a6),%fpcr, 1678 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1679 movm.l EXC_DREGS(%a6),&0x030 1679 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1680 1680 1681 mov.w &0x30d8,EXC_VOFF(%a6) 1681 mov.w &0x30d8,EXC_VOFF(%a6) # vector offset = 0xd8 1682 mov.w &0xe006,2+FP_SRC(%a6) 1682 mov.w &0xe006,2+FP_SRC(%a6) 1683 1683 1684 frestore FP_SRC(%a6) 1684 frestore FP_SRC(%a6) 1685 1685 1686 unlk %a6 1686 unlk %a6 1687 1687 1688 1688 1689 bra.l _real_snan 1689 bra.l _real_snan 1690 1690 1691 fu_operr: 1691 fu_operr: 1692 fmovm.x EXC_FPREGS(%a6),&0xc0 1692 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1693 fmovm.l USER_FPCR(%a6),%fpcr, 1693 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1694 movm.l EXC_DREGS(%a6),&0x030 1694 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1695 1695 1696 mov.w &0x30d0,EXC_VOFF(%a6) 1696 mov.w &0x30d0,EXC_VOFF(%a6) # vector offset = 0xd0 1697 mov.w &0xe004,2+FP_SRC(%a6) 1697 mov.w &0xe004,2+FP_SRC(%a6) 1698 1698 1699 frestore FP_SRC(%a6) 1699 frestore FP_SRC(%a6) 1700 1700 1701 unlk %a6 1701 unlk %a6 1702 1702 1703 1703 1704 bra.l _real_operr 1704 bra.l _real_operr 1705 1705 1706 fu_ovfl: 1706 fu_ovfl: 1707 fmovm.x &0x40,FP_SRC(%a6) 1707 fmovm.x &0x40,FP_SRC(%a6) # save EXOP to the stack 1708 1708 1709 fmovm.x EXC_FPREGS(%a6),&0xc0 1709 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1710 fmovm.l USER_FPCR(%a6),%fpcr, 1710 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1711 movm.l EXC_DREGS(%a6),&0x030 1711 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1712 1712 1713 mov.w &0x30d4,EXC_VOFF(%a6) 1713 mov.w &0x30d4,EXC_VOFF(%a6) # vector offset = 0xd4 1714 mov.w &0xe005,2+FP_SRC(%a6) 1714 mov.w &0xe005,2+FP_SRC(%a6) 1715 1715 1716 frestore FP_SRC(%a6) 1716 frestore FP_SRC(%a6) # restore EXOP 1717 1717 1718 unlk %a6 1718 unlk %a6 1719 1719 1720 bra.l _real_ovfl 1720 bra.l _real_ovfl 1721 1721 1722 # underflow can happen for extended precision 1722 # underflow can happen for extended precision. extended precision opclass 1723 # three instruction exceptions don't update t 1723 # three instruction exceptions don't update the stack pointer. so, if the 1724 # exception occurred from user mode, then sim 1724 # exception occurred from user mode, then simply update a7 and exit normally. 1725 # if the exception occurred from supervisor m 1725 # if the exception occurred from supervisor mode, check if 1726 fu_unfl: 1726 fu_unfl: 1727 mov.l EXC_A6(%a6),(%a6) 1727 mov.l EXC_A6(%a6),(%a6) # restore a6 1728 1728 1729 btst &0x5,EXC_SR(%a6) 1729 btst &0x5,EXC_SR(%a6) 1730 bne.w fu_unfl_s 1730 bne.w fu_unfl_s 1731 1731 1732 mov.l EXC_A7(%a6),%a0 1732 mov.l EXC_A7(%a6),%a0 # restore a7 whether we need 1733 mov.l %a0,%usp 1733 mov.l %a0,%usp # to or not... 1734 1734 1735 fu_unfl_cont: 1735 fu_unfl_cont: 1736 fmovm.x &0x40,FP_SRC(%a6) 1736 fmovm.x &0x40,FP_SRC(%a6) # save EXOP to the stack 1737 1737 1738 fmovm.x EXC_FPREGS(%a6),&0xc0 1738 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1739 fmovm.l USER_FPCR(%a6),%fpcr, 1739 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1740 movm.l EXC_DREGS(%a6),&0x030 1740 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1741 1741 1742 mov.w &0x30cc,EXC_VOFF(%a6) 1742 mov.w &0x30cc,EXC_VOFF(%a6) # vector offset = 0xcc 1743 mov.w &0xe003,2+FP_SRC(%a6) 1743 mov.w &0xe003,2+FP_SRC(%a6) 1744 1744 1745 frestore FP_SRC(%a6) 1745 frestore FP_SRC(%a6) # restore EXOP 1746 1746 1747 unlk %a6 1747 unlk %a6 1748 1748 1749 bra.l _real_unfl 1749 bra.l _real_unfl 1750 1750 1751 fu_unfl_s: 1751 fu_unfl_s: 1752 cmpi.b SPCOND_FLG(%a6),&mda7 1752 cmpi.b SPCOND_FLG(%a6),&mda7_flg # was the <ea> mode -(sp)? 1753 bne.b fu_unfl_cont 1753 bne.b fu_unfl_cont 1754 1754 1755 # the extended precision result is still in f 1755 # the extended precision result is still in fp0. but, we need to save it 1756 # somewhere on the stack until we can copy it 1756 # somewhere on the stack until we can copy it to its final resting place 1757 # (where the exc frame is currently). make su 1757 # (where the exc frame is currently). make sure it's not at the top of the 1758 # frame or it will get overwritten when the e 1758 # frame or it will get overwritten when the exc stack frame is shifted "down". 1759 fmovm.x &0x80,FP_SRC(%a6) 1759 fmovm.x &0x80,FP_SRC(%a6) # put answer on stack 1760 fmovm.x &0x40,FP_DST(%a6) 1760 fmovm.x &0x40,FP_DST(%a6) # put EXOP on stack 1761 1761 1762 fmovm.x EXC_FPREGS(%a6),&0xc0 1762 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1763 fmovm.l USER_FPCR(%a6),%fpcr, 1763 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1764 movm.l EXC_DREGS(%a6),&0x030 1764 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1765 1765 1766 mov.w &0x30cc,EXC_VOFF(%a6) 1766 mov.w &0x30cc,EXC_VOFF(%a6) # vector offset = 0xcc 1767 mov.w &0xe003,2+FP_DST(%a6) 1767 mov.w &0xe003,2+FP_DST(%a6) 1768 1768 1769 frestore FP_DST(%a6) 1769 frestore FP_DST(%a6) # restore EXOP 1770 1770 1771 mov.l (%a6),%a6 1771 mov.l (%a6),%a6 # restore frame pointer 1772 1772 1773 mov.l LOCAL_SIZE+EXC_SR(%sp 1773 mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp) 1774 mov.l LOCAL_SIZE+2+EXC_PC(% 1774 mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp) 1775 mov.l LOCAL_SIZE+EXC_EA(%sp 1775 mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp) 1776 1776 1777 # now, copy the result to the proper place on 1777 # now, copy the result to the proper place on the stack 1778 mov.l LOCAL_SIZE+FP_SRC_EX( 1778 mov.l LOCAL_SIZE+FP_SRC_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp) 1779 mov.l LOCAL_SIZE+FP_SRC_HI( 1779 mov.l LOCAL_SIZE+FP_SRC_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp) 1780 mov.l LOCAL_SIZE+FP_SRC_LO( 1780 mov.l LOCAL_SIZE+FP_SRC_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp) 1781 1781 1782 add.l &LOCAL_SIZE-0x8,%sp 1782 add.l &LOCAL_SIZE-0x8,%sp 1783 1783 1784 bra.l _real_unfl 1784 bra.l _real_unfl 1785 1785 1786 # fmove in and out enter here. 1786 # fmove in and out enter here. 1787 fu_inex: 1787 fu_inex: 1788 fmovm.x &0x40,FP_SRC(%a6) 1788 fmovm.x &0x40,FP_SRC(%a6) # save EXOP to the stack 1789 1789 1790 fmovm.x EXC_FPREGS(%a6),&0xc0 1790 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1791 fmovm.l USER_FPCR(%a6),%fpcr, 1791 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1792 movm.l EXC_DREGS(%a6),&0x030 1792 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1793 1793 1794 mov.w &0x30c4,EXC_VOFF(%a6) 1794 mov.w &0x30c4,EXC_VOFF(%a6) # vector offset = 0xc4 1795 mov.w &0xe001,2+FP_SRC(%a6) 1795 mov.w &0xe001,2+FP_SRC(%a6) 1796 1796 1797 frestore FP_SRC(%a6) 1797 frestore FP_SRC(%a6) # restore EXOP 1798 1798 1799 unlk %a6 1799 unlk %a6 1800 1800 1801 1801 1802 bra.l _real_inex 1802 bra.l _real_inex 1803 1803 1804 ############################################# 1804 ######################################################################### 1805 ############################################# 1805 ######################################################################### 1806 fu_in_pack: 1806 fu_in_pack: 1807 1807 1808 1808 1809 # I'm not sure at this point what FPSR bits a 1809 # I'm not sure at this point what FPSR bits are valid for this instruction. 1810 # so, since the emulation routines re-create 1810 # so, since the emulation routines re-create them anyways, zero exception field 1811 andi.l &0x0ff00ff,USER_FPSR( 1811 andi.l &0x0ff00ff,USER_FPSR(%a6) # zero exception field 1812 1812 1813 fmov.l &0x0,%fpcr 1813 fmov.l &0x0,%fpcr # zero current control regs 1814 fmov.l &0x0,%fpsr 1814 fmov.l &0x0,%fpsr 1815 1815 1816 bsr.l get_packed 1816 bsr.l get_packed # fetch packed src operand 1817 1817 1818 lea FP_SRC(%a6),%a0 1818 lea FP_SRC(%a6),%a0 # pass ptr to src 1819 bsr.l set_tag_x 1819 bsr.l set_tag_x # set src optype tag 1820 1820 1821 mov.b %d0,STAG(%a6) 1821 mov.b %d0,STAG(%a6) # save src optype tag 1822 1822 1823 bfextu EXC_CMDREG(%a6){&6:&3 1823 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg 1824 1824 1825 # bit five of the fp extension word separates 1825 # bit five of the fp extension word separates the monadic and dyadic operations 1826 # at this point 1826 # at this point 1827 btst &0x5,1+EXC_CMDREG(%a6 1827 btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic? 1828 beq.b fu_extract_p 1828 beq.b fu_extract_p # monadic 1829 cmpi.b 1+EXC_CMDREG(%a6),&0x 1829 cmpi.b 1+EXC_CMDREG(%a6),&0x3a # is operation an ftst? 1830 beq.b fu_extract_p 1830 beq.b fu_extract_p # yes, so it's monadic, too 1831 1831 1832 bsr.l load_fpn2 1832 bsr.l load_fpn2 # load dst into FP_DST 1833 1833 1834 lea FP_DST(%a6),%a0 1834 lea FP_DST(%a6),%a0 # pass: ptr to dst op 1835 bsr.l set_tag_x 1835 bsr.l set_tag_x # tag the operand type 1836 cmpi.b %d0,&UNNORM 1836 cmpi.b %d0,&UNNORM # is operand an UNNORM? 1837 bne.b fu_op2_done_p 1837 bne.b fu_op2_done_p # no 1838 bsr.l unnorm_fix 1838 bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO 1839 fu_op2_done_p: 1839 fu_op2_done_p: 1840 mov.b %d0,DTAG(%a6) 1840 mov.b %d0,DTAG(%a6) # save dst optype tag 1841 1841 1842 fu_extract_p: 1842 fu_extract_p: 1843 clr.l %d0 1843 clr.l %d0 1844 mov.b FPCR_MODE(%a6),%d0 1844 mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec 1845 1845 1846 bfextu 1+EXC_CMDREG(%a6){&1: 1846 bfextu 1+EXC_CMDREG(%a6){&1:&7},%d1 # extract extension 1847 1847 1848 lea FP_SRC(%a6),%a0 1848 lea FP_SRC(%a6),%a0 1849 lea FP_DST(%a6),%a1 1849 lea FP_DST(%a6),%a1 1850 1850 1851 mov.l (tbl_unsupp.l,%pc,%d1 1851 mov.l (tbl_unsupp.l,%pc,%d1.l*4),%d1 # fetch routine addr 1852 jsr (tbl_unsupp.l,%pc,%d1 1852 jsr (tbl_unsupp.l,%pc,%d1.l*1) 1853 1853 1854 # 1854 # 1855 # Exceptions in order of precedence: 1855 # Exceptions in order of precedence: 1856 # BSUN : none 1856 # BSUN : none 1857 # SNAN : all dyadic ops 1857 # SNAN : all dyadic ops 1858 # OPERR : fsqrt(-NORM) 1858 # OPERR : fsqrt(-NORM) 1859 # OVFL : all except ftst,fcmp 1859 # OVFL : all except ftst,fcmp 1860 # UNFL : all except ftst,fcmp 1860 # UNFL : all except ftst,fcmp 1861 # DZ : fdiv 1861 # DZ : fdiv 1862 # INEX2 : all except ftst,fcmp 1862 # INEX2 : all except ftst,fcmp 1863 # INEX1 : all 1863 # INEX1 : all 1864 # 1864 # 1865 1865 1866 # we determine the highest priority exception 1866 # we determine the highest priority exception(if any) set by the 1867 # emulation routine that has also been enable 1867 # emulation routine that has also been enabled by the user. 1868 mov.b FPCR_ENABLE(%a6),%d0 1868 mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled 1869 bne.w fu_in_ena_p 1869 bne.w fu_in_ena_p # some are enabled 1870 1870 1871 fu_in_cont_p: 1871 fu_in_cont_p: 1872 # fcmp and ftst do not store any result. 1872 # fcmp and ftst do not store any result. 1873 mov.b 1+EXC_CMDREG(%a6),%d0 1873 mov.b 1+EXC_CMDREG(%a6),%d0 # fetch extension 1874 andi.b &0x38,%d0 1874 andi.b &0x38,%d0 # extract bits 3-5 1875 cmpi.b %d0,&0x38 1875 cmpi.b %d0,&0x38 # is instr fcmp or ftst? 1876 beq.b fu_in_exit_p 1876 beq.b fu_in_exit_p # yes 1877 1877 1878 bfextu EXC_CMDREG(%a6){&6:&3 1878 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg 1879 bsr.l store_fpreg 1879 bsr.l store_fpreg # store the result 1880 1880 1881 fu_in_exit_p: 1881 fu_in_exit_p: 1882 1882 1883 btst &0x5,EXC_SR(%a6) 1883 btst &0x5,EXC_SR(%a6) # user or supervisor? 1884 bne.w fu_in_exit_s_p 1884 bne.w fu_in_exit_s_p # supervisor 1885 1885 1886 mov.l EXC_A7(%a6),%a0 1886 mov.l EXC_A7(%a6),%a0 # update user a7 1887 mov.l %a0,%usp 1887 mov.l %a0,%usp 1888 1888 1889 fu_in_exit_cont_p: 1889 fu_in_exit_cont_p: 1890 fmovm.x EXC_FPREGS(%a6),&0xc0 1890 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1891 fmovm.l USER_FPCR(%a6),%fpcr, 1891 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1892 movm.l EXC_DREGS(%a6),&0x030 1892 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1893 1893 1894 unlk %a6 1894 unlk %a6 # unravel stack frame 1895 1895 1896 btst &0x7,(%sp) 1896 btst &0x7,(%sp) # is trace on? 1897 bne.w fu_trace_p 1897 bne.w fu_trace_p # yes 1898 1898 1899 bra.l _fpsp_done 1899 bra.l _fpsp_done # exit to os 1900 1900 1901 # the exception occurred in supervisor mode. 1901 # the exception occurred in supervisor mode. check to see if the 1902 # addressing mode was (a7)+. if so, we'll nee 1902 # addressing mode was (a7)+. if so, we'll need to shift the 1903 # stack frame "up". 1903 # stack frame "up". 1904 fu_in_exit_s_p: 1904 fu_in_exit_s_p: 1905 btst &mia7_bit,SPCOND_FLG( 1905 btst &mia7_bit,SPCOND_FLG(%a6) # was ea mode (a7)+ 1906 beq.b fu_in_exit_cont_p 1906 beq.b fu_in_exit_cont_p # no 1907 1907 1908 fmovm.x EXC_FPREGS(%a6),&0xc0 1908 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1909 fmovm.l USER_FPCR(%a6),%fpcr, 1909 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1910 movm.l EXC_DREGS(%a6),&0x030 1910 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1911 1911 1912 unlk %a6 1912 unlk %a6 # unravel stack frame 1913 1913 1914 # shift the stack frame "up". we don't really 1914 # shift the stack frame "up". we don't really care about the <ea> field. 1915 mov.l 0x4(%sp),0x10(%sp) 1915 mov.l 0x4(%sp),0x10(%sp) 1916 mov.l 0x0(%sp),0xc(%sp) 1916 mov.l 0x0(%sp),0xc(%sp) 1917 add.l &0xc,%sp 1917 add.l &0xc,%sp 1918 1918 1919 btst &0x7,(%sp) 1919 btst &0x7,(%sp) # is trace on? 1920 bne.w fu_trace_p 1920 bne.w fu_trace_p # yes 1921 1921 1922 bra.l _fpsp_done 1922 bra.l _fpsp_done # exit to os 1923 1923 1924 fu_in_ena_p: 1924 fu_in_ena_p: 1925 and.b FPSR_EXCEPT(%a6),%d0 1925 and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled & set 1926 bfffo %d0{&24:&8},%d0 1926 bfffo %d0{&24:&8},%d0 # find highest priority exception 1927 bne.b fu_in_exc_p 1927 bne.b fu_in_exc_p # at least one was set 1928 1928 1929 # 1929 # 1930 # No exceptions occurred that were also enabl 1930 # No exceptions occurred that were also enabled. Now: 1931 # 1931 # 1932 # if (OVFL && ovfl_disabled && inexact_ 1932 # if (OVFL && ovfl_disabled && inexact_enabled) { 1933 # branch to _real_inex() (even if t 1933 # branch to _real_inex() (even if the result was exact!); 1934 # } else { 1934 # } else { 1935 # save the result in the proper fp 1935 # save the result in the proper fp reg (unless the op is fcmp or ftst); 1936 # return; 1936 # return; 1937 # } 1937 # } 1938 # 1938 # 1939 btst &ovfl_bit,FPSR_EXCEPT 1939 btst &ovfl_bit,FPSR_EXCEPT(%a6) # was overflow set? 1940 beq.w fu_in_cont_p 1940 beq.w fu_in_cont_p # no 1941 1941 1942 fu_in_ovflchk_p: 1942 fu_in_ovflchk_p: 1943 btst &inex2_bit,FPCR_ENABL 1943 btst &inex2_bit,FPCR_ENABLE(%a6) # was inexact enabled? 1944 beq.w fu_in_cont_p 1944 beq.w fu_in_cont_p # no 1945 bra.w fu_in_exc_ovfl_p 1945 bra.w fu_in_exc_ovfl_p # do _real_inex() now 1946 1946 1947 # 1947 # 1948 # An exception occurred and that exception wa 1948 # An exception occurred and that exception was enabled: 1949 # 1949 # 1950 # shift enabled exception field into lo 1950 # shift enabled exception field into lo byte of d0; 1951 # if (((INEX2 || INEX1) && inex_enabled 1951 # if (((INEX2 || INEX1) && inex_enabled && OVFL && ovfl_disabled) || 1952 # ((INEX2 || INEX1) && inex_enabled 1952 # ((INEX2 || INEX1) && inex_enabled && UNFL && unfl_disabled)) { 1953 # /* 1953 # /* 1954 # * this is the case where we 1954 # * this is the case where we must call _real_inex() now or else 1955 # * there will be no other way 1955 # * there will be no other way to pass it the exceptional operand 1956 # */ 1956 # */ 1957 # call _real_inex(); 1957 # call _real_inex(); 1958 # } else { 1958 # } else { 1959 # restore exc state (SNAN||OPER 1959 # restore exc state (SNAN||OPERR||OVFL||UNFL||DZ||INEX) into the FPU; 1960 # } 1960 # } 1961 # 1961 # 1962 fu_in_exc_p: 1962 fu_in_exc_p: 1963 subi.l &24,%d0 1963 subi.l &24,%d0 # fix offset to be 0-8 1964 cmpi.b %d0,&0x6 1964 cmpi.b %d0,&0x6 # is exception INEX? (6 or 7) 1965 blt.b fu_in_exc_exit_p 1965 blt.b fu_in_exc_exit_p # no 1966 1966 1967 # the enabled exception was inexact 1967 # the enabled exception was inexact 1968 btst &unfl_bit,FPSR_EXCEPT 1968 btst &unfl_bit,FPSR_EXCEPT(%a6) # did disabled underflow occur? 1969 bne.w fu_in_exc_unfl_p 1969 bne.w fu_in_exc_unfl_p # yes 1970 btst &ovfl_bit,FPSR_EXCEPT 1970 btst &ovfl_bit,FPSR_EXCEPT(%a6) # did disabled overflow occur? 1971 bne.w fu_in_exc_ovfl_p 1971 bne.w fu_in_exc_ovfl_p # yes 1972 1972 1973 # here, we insert the correct fsave status va 1973 # here, we insert the correct fsave status value into the fsave frame for the 1974 # corresponding exception. the operand in the 1974 # corresponding exception. the operand in the fsave frame should be the original 1975 # src operand. 1975 # src operand. 1976 # as a reminder for future predicted pain and 1976 # as a reminder for future predicted pain and agony, we are passing in fsave the 1977 # "non-skewed" operand for cases of sgl and d 1977 # "non-skewed" operand for cases of sgl and dbl src INFs,NANs, and DENORMs. 1978 # this is INCORRECT for enabled SNAN which wo 1978 # this is INCORRECT for enabled SNAN which would give to the user the skewed SNAN!!! 1979 fu_in_exc_exit_p: 1979 fu_in_exc_exit_p: 1980 btst &0x5,EXC_SR(%a6) 1980 btst &0x5,EXC_SR(%a6) # user or supervisor? 1981 bne.w fu_in_exc_exit_s_p 1981 bne.w fu_in_exc_exit_s_p # supervisor 1982 1982 1983 mov.l EXC_A7(%a6),%a0 1983 mov.l EXC_A7(%a6),%a0 # update user a7 1984 mov.l %a0,%usp 1984 mov.l %a0,%usp 1985 1985 1986 fu_in_exc_exit_cont_p: 1986 fu_in_exc_exit_cont_p: 1987 mov.w (tbl_except_p.b,%pc,% 1987 mov.w (tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6) 1988 1988 1989 fmovm.x EXC_FPREGS(%a6),&0xc0 1989 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 1990 fmovm.l USER_FPCR(%a6),%fpcr, 1990 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 1991 movm.l EXC_DREGS(%a6),&0x030 1991 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 1992 1992 1993 frestore FP_SRC(%a6) 1993 frestore FP_SRC(%a6) # restore src op 1994 1994 1995 unlk %a6 1995 unlk %a6 1996 1996 1997 btst &0x7,(%sp) 1997 btst &0x7,(%sp) # is trace enabled? 1998 bne.w fu_trace_p 1998 bne.w fu_trace_p # yes 1999 1999 2000 bra.l _fpsp_done 2000 bra.l _fpsp_done 2001 2001 2002 tbl_except_p: 2002 tbl_except_p: 2003 short 0xe000,0xe006,0xe004, 2003 short 0xe000,0xe006,0xe004,0xe005 2004 short 0xe003,0xe002,0xe001, 2004 short 0xe003,0xe002,0xe001,0xe001 2005 2005 2006 fu_in_exc_ovfl_p: 2006 fu_in_exc_ovfl_p: 2007 mov.w &0x3,%d0 2007 mov.w &0x3,%d0 2008 bra.w fu_in_exc_exit_p 2008 bra.w fu_in_exc_exit_p 2009 2009 2010 fu_in_exc_unfl_p: 2010 fu_in_exc_unfl_p: 2011 mov.w &0x4,%d0 2011 mov.w &0x4,%d0 2012 bra.w fu_in_exc_exit_p 2012 bra.w fu_in_exc_exit_p 2013 2013 2014 fu_in_exc_exit_s_p: 2014 fu_in_exc_exit_s_p: 2015 btst &mia7_bit,SPCOND_FLG( 2015 btst &mia7_bit,SPCOND_FLG(%a6) 2016 beq.b fu_in_exc_exit_cont_p 2016 beq.b fu_in_exc_exit_cont_p 2017 2017 2018 mov.w (tbl_except_p.b,%pc,% 2018 mov.w (tbl_except_p.b,%pc,%d0.w*2),2+FP_SRC(%a6) 2019 2019 2020 fmovm.x EXC_FPREGS(%a6),&0xc0 2020 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 2021 fmovm.l USER_FPCR(%a6),%fpcr, 2021 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2022 movm.l EXC_DREGS(%a6),&0x030 2022 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2023 2023 2024 frestore FP_SRC(%a6) 2024 frestore FP_SRC(%a6) # restore src op 2025 2025 2026 unlk %a6 2026 unlk %a6 # unravel stack frame 2027 2027 2028 # shift stack frame "up". who cares about <ea 2028 # shift stack frame "up". who cares about <ea> field. 2029 mov.l 0x4(%sp),0x10(%sp) 2029 mov.l 0x4(%sp),0x10(%sp) 2030 mov.l 0x0(%sp),0xc(%sp) 2030 mov.l 0x0(%sp),0xc(%sp) 2031 add.l &0xc,%sp 2031 add.l &0xc,%sp 2032 2032 2033 btst &0x7,(%sp) 2033 btst &0x7,(%sp) # is trace on? 2034 bne.b fu_trace_p 2034 bne.b fu_trace_p # yes 2035 2035 2036 bra.l _fpsp_done 2036 bra.l _fpsp_done # exit to os 2037 2037 2038 # 2038 # 2039 # The opclass two PACKED instruction that too 2039 # The opclass two PACKED instruction that took an "Unimplemented Data Type" 2040 # exception was being traced. Make the "curre 2040 # exception was being traced. Make the "current" PC the FPIAR and put it in the 2041 # trace stack frame then jump to _real_trace( 2041 # trace stack frame then jump to _real_trace(). 2042 # 2042 # 2043 # UNSUPP FRAME TR 2043 # UNSUPP FRAME TRACE FRAME 2044 # ***************** ***** 2044 # ***************** ***************** 2045 # * EA * * 2045 # * EA * * Current * 2046 # * * * 2046 # * * * PC * 2047 # ***************** ***** 2047 # ***************** ***************** 2048 # * 0x2 * 0x0dc * * 0x2 2048 # * 0x2 * 0x0dc * * 0x2 * 0x024 * 2049 # ***************** ***** 2049 # ***************** ***************** 2050 # * Next * * 2050 # * Next * * Next * 2051 # * PC * * 2051 # * PC * * PC * 2052 # ***************** ***** 2052 # ***************** ***************** 2053 # * SR * * 2053 # * SR * * SR * 2054 # ***************** ***** 2054 # ***************** ***************** 2055 fu_trace_p: 2055 fu_trace_p: 2056 mov.w &0x2024,0x6(%sp) 2056 mov.w &0x2024,0x6(%sp) 2057 fmov.l %fpiar,0x8(%sp) 2057 fmov.l %fpiar,0x8(%sp) 2058 2058 2059 bra.l _real_trace 2059 bra.l _real_trace 2060 2060 2061 ############################################# 2061 ######################################################### 2062 ############################################# 2062 ######################################################### 2063 fu_out_pack: 2063 fu_out_pack: 2064 2064 2065 2065 2066 # I'm not sure at this point what FPSR bits a 2066 # I'm not sure at this point what FPSR bits are valid for this instruction. 2067 # so, since the emulation routines re-create 2067 # so, since the emulation routines re-create them anyways, zero exception field. 2068 # fmove out doesn't affect ccodes. 2068 # fmove out doesn't affect ccodes. 2069 and.l &0xffff00ff,USER_FPSR 2069 and.l &0xffff00ff,USER_FPSR(%a6) # zero exception field 2070 2070 2071 fmov.l &0x0,%fpcr 2071 fmov.l &0x0,%fpcr # zero current control regs 2072 fmov.l &0x0,%fpsr 2072 fmov.l &0x0,%fpsr 2073 2073 2074 bfextu EXC_CMDREG(%a6){&6:&3 2074 bfextu EXC_CMDREG(%a6){&6:&3},%d0 2075 bsr.l load_fpn1 2075 bsr.l load_fpn1 2076 2076 2077 # unlike other opclass 3, unimplemented data 2077 # unlike other opclass 3, unimplemented data type exceptions, packed must be 2078 # able to detect all operand types. 2078 # able to detect all operand types. 2079 lea FP_SRC(%a6),%a0 2079 lea FP_SRC(%a6),%a0 2080 bsr.l set_tag_x 2080 bsr.l set_tag_x # tag the operand type 2081 cmpi.b %d0,&UNNORM 2081 cmpi.b %d0,&UNNORM # is operand an UNNORM? 2082 bne.b fu_op2_p 2082 bne.b fu_op2_p # no 2083 bsr.l unnorm_fix 2083 bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO 2084 2084 2085 fu_op2_p: 2085 fu_op2_p: 2086 mov.b %d0,STAG(%a6) 2086 mov.b %d0,STAG(%a6) # save src optype tag 2087 2087 2088 clr.l %d0 2088 clr.l %d0 2089 mov.b FPCR_MODE(%a6),%d0 2089 mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode/prec 2090 2090 2091 lea FP_SRC(%a6),%a0 2091 lea FP_SRC(%a6),%a0 # pass ptr to src operand 2092 2092 2093 mov.l (%a6),EXC_A6(%a6) 2093 mov.l (%a6),EXC_A6(%a6) # in case a6 changes 2094 bsr.l fout 2094 bsr.l fout # call fmove out routine 2095 2095 2096 # Exceptions in order of precedence: 2096 # Exceptions in order of precedence: 2097 # BSUN : no 2097 # BSUN : no 2098 # SNAN : yes 2098 # SNAN : yes 2099 # OPERR : if ((k_factor > +17) || (de 2099 # OPERR : if ((k_factor > +17) || (dec. exp exceeds 3 digits)) 2100 # OVFL : no 2100 # OVFL : no 2101 # UNFL : no 2101 # UNFL : no 2102 # DZ : no 2102 # DZ : no 2103 # INEX2 : yes 2103 # INEX2 : yes 2104 # INEX1 : no 2104 # INEX1 : no 2105 2105 2106 # determine the highest priority exception(if 2106 # determine the highest priority exception(if any) set by the 2107 # emulation routine that has also been enable 2107 # emulation routine that has also been enabled by the user. 2108 mov.b FPCR_ENABLE(%a6),%d0 2108 mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled 2109 bne.w fu_out_ena_p 2109 bne.w fu_out_ena_p # some are enabled 2110 2110 2111 fu_out_exit_p: 2111 fu_out_exit_p: 2112 mov.l EXC_A6(%a6),(%a6) 2112 mov.l EXC_A6(%a6),(%a6) # restore a6 2113 2113 2114 btst &0x5,EXC_SR(%a6) 2114 btst &0x5,EXC_SR(%a6) # user or supervisor? 2115 bne.b fu_out_exit_s_p 2115 bne.b fu_out_exit_s_p # supervisor 2116 2116 2117 mov.l EXC_A7(%a6),%a0 2117 mov.l EXC_A7(%a6),%a0 # update user a7 2118 mov.l %a0,%usp 2118 mov.l %a0,%usp 2119 2119 2120 fu_out_exit_cont_p: 2120 fu_out_exit_cont_p: 2121 fmovm.x EXC_FPREGS(%a6),&0xc0 2121 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 2122 fmovm.l USER_FPCR(%a6),%fpcr, 2122 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2123 movm.l EXC_DREGS(%a6),&0x030 2123 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2124 2124 2125 unlk %a6 2125 unlk %a6 # unravel stack frame 2126 2126 2127 btst &0x7,(%sp) 2127 btst &0x7,(%sp) # is trace on? 2128 bne.w fu_trace_p 2128 bne.w fu_trace_p # yes 2129 2129 2130 bra.l _fpsp_done 2130 bra.l _fpsp_done # exit to os 2131 2131 2132 # the exception occurred in supervisor mode. 2132 # the exception occurred in supervisor mode. check to see if the 2133 # addressing mode was -(a7). if so, we'll nee 2133 # addressing mode was -(a7). if so, we'll need to shift the 2134 # stack frame "down". 2134 # stack frame "down". 2135 fu_out_exit_s_p: 2135 fu_out_exit_s_p: 2136 btst &mda7_bit,SPCOND_FLG( 2136 btst &mda7_bit,SPCOND_FLG(%a6) # was ea mode -(a7) 2137 beq.b fu_out_exit_cont_p 2137 beq.b fu_out_exit_cont_p # no 2138 2138 2139 fmovm.x EXC_FPREGS(%a6),&0xc0 2139 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 2140 fmovm.l USER_FPCR(%a6),%fpcr, 2140 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2141 movm.l EXC_DREGS(%a6),&0x030 2141 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2142 2142 2143 mov.l (%a6),%a6 2143 mov.l (%a6),%a6 # restore frame pointer 2144 2144 2145 mov.l LOCAL_SIZE+EXC_SR(%sp 2145 mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp) 2146 mov.l LOCAL_SIZE+2+EXC_PC(% 2146 mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp) 2147 2147 2148 # now, copy the result to the proper place on 2148 # now, copy the result to the proper place on the stack 2149 mov.l LOCAL_SIZE+FP_DST_EX( 2149 mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+EXC_SR+0x0(%sp) 2150 mov.l LOCAL_SIZE+FP_DST_HI( 2150 mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+EXC_SR+0x4(%sp) 2151 mov.l LOCAL_SIZE+FP_DST_LO( 2151 mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+EXC_SR+0x8(%sp) 2152 2152 2153 add.l &LOCAL_SIZE-0x8,%sp 2153 add.l &LOCAL_SIZE-0x8,%sp 2154 2154 2155 btst &0x7,(%sp) 2155 btst &0x7,(%sp) 2156 bne.w fu_trace_p 2156 bne.w fu_trace_p 2157 2157 2158 bra.l _fpsp_done 2158 bra.l _fpsp_done 2159 2159 2160 fu_out_ena_p: 2160 fu_out_ena_p: 2161 and.b FPSR_EXCEPT(%a6),%d0 2161 and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled 2162 bfffo %d0{&24:&8},%d0 2162 bfffo %d0{&24:&8},%d0 # find highest priority exception 2163 beq.w fu_out_exit_p 2163 beq.w fu_out_exit_p 2164 2164 2165 mov.l EXC_A6(%a6),(%a6) 2165 mov.l EXC_A6(%a6),(%a6) # restore a6 2166 2166 2167 # an exception occurred and that exception wa 2167 # an exception occurred and that exception was enabled. 2168 # the only exception possible on packed move 2168 # the only exception possible on packed move out are INEX, OPERR, and SNAN. 2169 fu_out_exc_p: 2169 fu_out_exc_p: 2170 cmpi.b %d0,&0x1a 2170 cmpi.b %d0,&0x1a 2171 bgt.w fu_inex_p2 2171 bgt.w fu_inex_p2 2172 beq.w fu_operr_p 2172 beq.w fu_operr_p 2173 2173 2174 fu_snan_p: 2174 fu_snan_p: 2175 btst &0x5,EXC_SR(%a6) 2175 btst &0x5,EXC_SR(%a6) 2176 bne.b fu_snan_s_p 2176 bne.b fu_snan_s_p 2177 2177 2178 mov.l EXC_A7(%a6),%a0 2178 mov.l EXC_A7(%a6),%a0 2179 mov.l %a0,%usp 2179 mov.l %a0,%usp 2180 bra.w fu_snan 2180 bra.w fu_snan 2181 2181 2182 fu_snan_s_p: 2182 fu_snan_s_p: 2183 cmpi.b SPCOND_FLG(%a6),&mda7 2183 cmpi.b SPCOND_FLG(%a6),&mda7_flg 2184 bne.w fu_snan 2184 bne.w fu_snan 2185 2185 2186 # the instruction was "fmove.p fpn,-(a7)" fro 2186 # the instruction was "fmove.p fpn,-(a7)" from supervisor mode. 2187 # the strategy is to move the exception frame 2187 # the strategy is to move the exception frame "down" 12 bytes. then, we 2188 # can store the default result where the exce 2188 # can store the default result where the exception frame was. 2189 fmovm.x EXC_FPREGS(%a6),&0xc0 2189 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 2190 fmovm.l USER_FPCR(%a6),%fpcr, 2190 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2191 movm.l EXC_DREGS(%a6),&0x030 2191 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2192 2192 2193 mov.w &0x30d8,EXC_VOFF(%a6) 2193 mov.w &0x30d8,EXC_VOFF(%a6) # vector offset = 0xd0 2194 mov.w &0xe006,2+FP_SRC(%a6) 2194 mov.w &0xe006,2+FP_SRC(%a6) # set fsave status 2195 2195 2196 frestore FP_SRC(%a6) 2196 frestore FP_SRC(%a6) # restore src operand 2197 2197 2198 mov.l (%a6),%a6 2198 mov.l (%a6),%a6 # restore frame pointer 2199 2199 2200 mov.l LOCAL_SIZE+EXC_SR(%sp 2200 mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp) 2201 mov.l LOCAL_SIZE+2+EXC_PC(% 2201 mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp) 2202 mov.l LOCAL_SIZE+EXC_EA(%sp 2202 mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp) 2203 2203 2204 # now, we copy the default result to its prop 2204 # now, we copy the default result to its proper location 2205 mov.l LOCAL_SIZE+FP_DST_EX( 2205 mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp) 2206 mov.l LOCAL_SIZE+FP_DST_HI( 2206 mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp) 2207 mov.l LOCAL_SIZE+FP_DST_LO( 2207 mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp) 2208 2208 2209 add.l &LOCAL_SIZE-0x8,%sp 2209 add.l &LOCAL_SIZE-0x8,%sp 2210 2210 2211 2211 2212 bra.l _real_snan 2212 bra.l _real_snan 2213 2213 2214 fu_operr_p: 2214 fu_operr_p: 2215 btst &0x5,EXC_SR(%a6) 2215 btst &0x5,EXC_SR(%a6) 2216 bne.w fu_operr_p_s 2216 bne.w fu_operr_p_s 2217 2217 2218 mov.l EXC_A7(%a6),%a0 2218 mov.l EXC_A7(%a6),%a0 2219 mov.l %a0,%usp 2219 mov.l %a0,%usp 2220 bra.w fu_operr 2220 bra.w fu_operr 2221 2221 2222 fu_operr_p_s: 2222 fu_operr_p_s: 2223 cmpi.b SPCOND_FLG(%a6),&mda7 2223 cmpi.b SPCOND_FLG(%a6),&mda7_flg 2224 bne.w fu_operr 2224 bne.w fu_operr 2225 2225 2226 # the instruction was "fmove.p fpn,-(a7)" fro 2226 # the instruction was "fmove.p fpn,-(a7)" from supervisor mode. 2227 # the strategy is to move the exception frame 2227 # the strategy is to move the exception frame "down" 12 bytes. then, we 2228 # can store the default result where the exce 2228 # can store the default result where the exception frame was. 2229 fmovm.x EXC_FPREGS(%a6),&0xc0 2229 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 2230 fmovm.l USER_FPCR(%a6),%fpcr, 2230 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2231 movm.l EXC_DREGS(%a6),&0x030 2231 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2232 2232 2233 mov.w &0x30d0,EXC_VOFF(%a6) 2233 mov.w &0x30d0,EXC_VOFF(%a6) # vector offset = 0xd0 2234 mov.w &0xe004,2+FP_SRC(%a6) 2234 mov.w &0xe004,2+FP_SRC(%a6) # set fsave status 2235 2235 2236 frestore FP_SRC(%a6) 2236 frestore FP_SRC(%a6) # restore src operand 2237 2237 2238 mov.l (%a6),%a6 2238 mov.l (%a6),%a6 # restore frame pointer 2239 2239 2240 mov.l LOCAL_SIZE+EXC_SR(%sp 2240 mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp) 2241 mov.l LOCAL_SIZE+2+EXC_PC(% 2241 mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp) 2242 mov.l LOCAL_SIZE+EXC_EA(%sp 2242 mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp) 2243 2243 2244 # now, we copy the default result to its prop 2244 # now, we copy the default result to its proper location 2245 mov.l LOCAL_SIZE+FP_DST_EX( 2245 mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp) 2246 mov.l LOCAL_SIZE+FP_DST_HI( 2246 mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp) 2247 mov.l LOCAL_SIZE+FP_DST_LO( 2247 mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp) 2248 2248 2249 add.l &LOCAL_SIZE-0x8,%sp 2249 add.l &LOCAL_SIZE-0x8,%sp 2250 2250 2251 2251 2252 bra.l _real_operr 2252 bra.l _real_operr 2253 2253 2254 fu_inex_p2: 2254 fu_inex_p2: 2255 btst &0x5,EXC_SR(%a6) 2255 btst &0x5,EXC_SR(%a6) 2256 bne.w fu_inex_s_p2 2256 bne.w fu_inex_s_p2 2257 2257 2258 mov.l EXC_A7(%a6),%a0 2258 mov.l EXC_A7(%a6),%a0 2259 mov.l %a0,%usp 2259 mov.l %a0,%usp 2260 bra.w fu_inex 2260 bra.w fu_inex 2261 2261 2262 fu_inex_s_p2: 2262 fu_inex_s_p2: 2263 cmpi.b SPCOND_FLG(%a6),&mda7 2263 cmpi.b SPCOND_FLG(%a6),&mda7_flg 2264 bne.w fu_inex 2264 bne.w fu_inex 2265 2265 2266 # the instruction was "fmove.p fpn,-(a7)" fro 2266 # the instruction was "fmove.p fpn,-(a7)" from supervisor mode. 2267 # the strategy is to move the exception frame 2267 # the strategy is to move the exception frame "down" 12 bytes. then, we 2268 # can store the default result where the exce 2268 # can store the default result where the exception frame was. 2269 fmovm.x EXC_FPREGS(%a6),&0xc0 2269 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0/fp1 2270 fmovm.l USER_FPCR(%a6),%fpcr, 2270 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2271 movm.l EXC_DREGS(%a6),&0x030 2271 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2272 2272 2273 mov.w &0x30c4,EXC_VOFF(%a6) 2273 mov.w &0x30c4,EXC_VOFF(%a6) # vector offset = 0xc4 2274 mov.w &0xe001,2+FP_SRC(%a6) 2274 mov.w &0xe001,2+FP_SRC(%a6) # set fsave status 2275 2275 2276 frestore FP_SRC(%a6) 2276 frestore FP_SRC(%a6) # restore src operand 2277 2277 2278 mov.l (%a6),%a6 2278 mov.l (%a6),%a6 # restore frame pointer 2279 2279 2280 mov.l LOCAL_SIZE+EXC_SR(%sp 2280 mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp) 2281 mov.l LOCAL_SIZE+2+EXC_PC(% 2281 mov.l LOCAL_SIZE+2+EXC_PC(%sp),LOCAL_SIZE+2+EXC_PC-0xc(%sp) 2282 mov.l LOCAL_SIZE+EXC_EA(%sp 2282 mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp) 2283 2283 2284 # now, we copy the default result to its prop 2284 # now, we copy the default result to its proper location 2285 mov.l LOCAL_SIZE+FP_DST_EX( 2285 mov.l LOCAL_SIZE+FP_DST_EX(%sp),LOCAL_SIZE+0x4(%sp) 2286 mov.l LOCAL_SIZE+FP_DST_HI( 2286 mov.l LOCAL_SIZE+FP_DST_HI(%sp),LOCAL_SIZE+0x8(%sp) 2287 mov.l LOCAL_SIZE+FP_DST_LO( 2287 mov.l LOCAL_SIZE+FP_DST_LO(%sp),LOCAL_SIZE+0xc(%sp) 2288 2288 2289 add.l &LOCAL_SIZE-0x8,%sp 2289 add.l &LOCAL_SIZE-0x8,%sp 2290 2290 2291 2291 2292 bra.l _real_inex 2292 bra.l _real_inex 2293 2293 2294 ############################################# 2294 ######################################################################### 2295 2295 2296 # 2296 # 2297 # if we're stuffing a source operand back int 2297 # if we're stuffing a source operand back into an fsave frame then we 2298 # have to make sure that for single or double 2298 # have to make sure that for single or double source operands that the 2299 # format stuffed is as weird as the hardware 2299 # format stuffed is as weird as the hardware usually makes it. 2300 # 2300 # 2301 global funimp_skew 2301 global funimp_skew 2302 funimp_skew: 2302 funimp_skew: 2303 bfextu EXC_EXTWORD(%a6){&3:& 2303 bfextu EXC_EXTWORD(%a6){&3:&3},%d0 # extract src specifier 2304 cmpi.b %d0,&0x1 2304 cmpi.b %d0,&0x1 # was src sgl? 2305 beq.b funimp_skew_sgl 2305 beq.b funimp_skew_sgl # yes 2306 cmpi.b %d0,&0x5 2306 cmpi.b %d0,&0x5 # was src dbl? 2307 beq.b funimp_skew_dbl 2307 beq.b funimp_skew_dbl # yes 2308 rts 2308 rts 2309 2309 2310 funimp_skew_sgl: 2310 funimp_skew_sgl: 2311 mov.w FP_SRC_EX(%a6),%d0 2311 mov.w FP_SRC_EX(%a6),%d0 # fetch DENORM exponent 2312 andi.w &0x7fff,%d0 2312 andi.w &0x7fff,%d0 # strip sign 2313 beq.b funimp_skew_sgl_not 2313 beq.b funimp_skew_sgl_not 2314 cmpi.w %d0,&0x3f80 2314 cmpi.w %d0,&0x3f80 2315 bgt.b funimp_skew_sgl_not 2315 bgt.b funimp_skew_sgl_not 2316 neg.w %d0 2316 neg.w %d0 # make exponent negative 2317 addi.w &0x3f81,%d0 2317 addi.w &0x3f81,%d0 # find amt to shift 2318 mov.l FP_SRC_HI(%a6),%d1 2318 mov.l FP_SRC_HI(%a6),%d1 # fetch DENORM hi(man) 2319 lsr.l %d0,%d1 2319 lsr.l %d0,%d1 # shift it 2320 bset &31,%d1 2320 bset &31,%d1 # set j-bit 2321 mov.l %d1,FP_SRC_HI(%a6) 2321 mov.l %d1,FP_SRC_HI(%a6) # insert new hi(man) 2322 andi.w &0x8000,FP_SRC_EX(%a6 2322 andi.w &0x8000,FP_SRC_EX(%a6) # clear old exponent 2323 ori.w &0x3f80,FP_SRC_EX(%a6 2323 ori.w &0x3f80,FP_SRC_EX(%a6) # insert new "skewed" exponent 2324 funimp_skew_sgl_not: 2324 funimp_skew_sgl_not: 2325 rts 2325 rts 2326 2326 2327 funimp_skew_dbl: 2327 funimp_skew_dbl: 2328 mov.w FP_SRC_EX(%a6),%d0 2328 mov.w FP_SRC_EX(%a6),%d0 # fetch DENORM exponent 2329 andi.w &0x7fff,%d0 2329 andi.w &0x7fff,%d0 # strip sign 2330 beq.b funimp_skew_dbl_not 2330 beq.b funimp_skew_dbl_not 2331 cmpi.w %d0,&0x3c00 2331 cmpi.w %d0,&0x3c00 2332 bgt.b funimp_skew_dbl_not 2332 bgt.b funimp_skew_dbl_not 2333 2333 2334 tst.b FP_SRC_EX(%a6) 2334 tst.b FP_SRC_EX(%a6) # make "internal format" 2335 smi.b 0x2+FP_SRC(%a6) 2335 smi.b 0x2+FP_SRC(%a6) 2336 mov.w %d0,FP_SRC_EX(%a6) 2336 mov.w %d0,FP_SRC_EX(%a6) # insert exponent with cleared sign 2337 clr.l %d0 2337 clr.l %d0 # clear g,r,s 2338 lea FP_SRC(%a6),%a0 2338 lea FP_SRC(%a6),%a0 # pass ptr to src op 2339 mov.w &0x3c01,%d1 2339 mov.w &0x3c01,%d1 # pass denorm threshold 2340 bsr.l dnrm_lp 2340 bsr.l dnrm_lp # denorm it 2341 mov.w &0x3c00,%d0 2341 mov.w &0x3c00,%d0 # new exponent 2342 tst.b 0x2+FP_SRC(%a6) 2342 tst.b 0x2+FP_SRC(%a6) # is sign set? 2343 beq.b fss_dbl_denorm_done 2343 beq.b fss_dbl_denorm_done # no 2344 bset &15,%d0 2344 bset &15,%d0 # set sign 2345 fss_dbl_denorm_done: 2345 fss_dbl_denorm_done: 2346 bset &0x7,FP_SRC_HI(%a6) 2346 bset &0x7,FP_SRC_HI(%a6) # set j-bit 2347 mov.w %d0,FP_SRC_EX(%a6) 2347 mov.w %d0,FP_SRC_EX(%a6) # insert new exponent 2348 funimp_skew_dbl_not: 2348 funimp_skew_dbl_not: 2349 rts 2349 rts 2350 2350 2351 ############################################# 2351 ######################################################################### 2352 global _mem_write2 2352 global _mem_write2 2353 _mem_write2: 2353 _mem_write2: 2354 btst &0x5,EXC_SR(%a6) 2354 btst &0x5,EXC_SR(%a6) 2355 beq.l _dmem_write 2355 beq.l _dmem_write 2356 mov.l 0x0(%a0),FP_DST_EX(%a 2356 mov.l 0x0(%a0),FP_DST_EX(%a6) 2357 mov.l 0x4(%a0),FP_DST_HI(%a 2357 mov.l 0x4(%a0),FP_DST_HI(%a6) 2358 mov.l 0x8(%a0),FP_DST_LO(%a 2358 mov.l 0x8(%a0),FP_DST_LO(%a6) 2359 clr.l %d1 2359 clr.l %d1 2360 rts 2360 rts 2361 2361 2362 ############################################# 2362 ######################################################################### 2363 # XDEF ************************************** 2363 # XDEF **************************************************************** # 2364 # _fpsp_effadd(): 060FPSP entry point f 2364 # _fpsp_effadd(): 060FPSP entry point for FP "Unimplemented # 2365 # effective address" ex 2365 # effective address" exception. # 2366 # 2366 # # 2367 # This handler should be the first code 2367 # This handler should be the first code executed upon taking the # 2368 # FP Unimplemented Effective Address ex 2368 # FP Unimplemented Effective Address exception in an operating # 2369 # system. 2369 # system. # 2370 # 2370 # # 2371 # XREF ************************************** 2371 # XREF **************************************************************** # 2372 # _imem_read_long() - read instruction 2372 # _imem_read_long() - read instruction longword # 2373 # fix_skewed_ops() - adjust src operand 2373 # fix_skewed_ops() - adjust src operand in fsave frame # 2374 # set_tag_x() - determine optype of src 2374 # set_tag_x() - determine optype of src/dst operands # 2375 # store_fpreg() - store opclass 0 or 2 2375 # store_fpreg() - store opclass 0 or 2 result to FP regfile # 2376 # unnorm_fix() - change UNNORM operands 2376 # unnorm_fix() - change UNNORM operands to NORM or ZERO # 2377 # load_fpn2() - load dst operand from F 2377 # load_fpn2() - load dst operand from FP regfile # 2378 # tbl_unsupp - add of table of emulatio 2378 # tbl_unsupp - add of table of emulation routines for opclass 0,2 # 2379 # decbin() - convert packed data to FP 2379 # decbin() - convert packed data to FP binary data # 2380 # _real_fpu_disabled() - "callout" for 2380 # _real_fpu_disabled() - "callout" for "FPU disabled" exception # 2381 # _real_access() - "callout" for access 2381 # _real_access() - "callout" for access error exception # 2382 # _mem_read() - read extended immediate 2382 # _mem_read() - read extended immediate operand from memory # 2383 # _fpsp_done() - "callout" for exit; wo 2383 # _fpsp_done() - "callout" for exit; work all done # 2384 # _real_trace() - "callout" for Trace e 2384 # _real_trace() - "callout" for Trace enabled exception # 2385 # fmovm_dynamic() - emulate dynamic fmo 2385 # fmovm_dynamic() - emulate dynamic fmovm instruction # 2386 # fmovm_ctrl() - emulate fmovm control 2386 # fmovm_ctrl() - emulate fmovm control instruction # 2387 # 2387 # # 2388 # INPUT ************************************* 2388 # INPUT *************************************************************** # 2389 # - The system stack contains the "Unim 2389 # - The system stack contains the "Unimplemented <ea>" stk frame # 2390 # 2390 # # 2391 # OUTPUT ************************************ 2391 # OUTPUT ************************************************************** # 2392 # If access error: 2392 # If access error: # 2393 # - The system stack is changed to an a 2393 # - The system stack is changed to an access error stack frame # 2394 # If FPU disabled: 2394 # If FPU disabled: # 2395 # - The system stack is changed to an F 2395 # - The system stack is changed to an FPU disabled stack frame # 2396 # If Trace exception enabled: 2396 # If Trace exception enabled: # 2397 # - The system stack is changed to a Tr 2397 # - The system stack is changed to a Trace exception stack frame # 2398 # Else: (normal case) 2398 # Else: (normal case) # 2399 # - None (correct result has been store 2399 # - None (correct result has been stored as appropriate) # 2400 # 2400 # # 2401 # ALGORITHM ********************************* 2401 # ALGORITHM *********************************************************** # 2402 # This exception handles 3 types of ope 2402 # This exception handles 3 types of operations: # 2403 # (1) FP Instructions using extended precisio 2403 # (1) FP Instructions using extended precision or packed immediate # 2404 # addressing mode. 2404 # addressing mode. # 2405 # (2) The "fmovm.x" instruction w/ dynamic re 2405 # (2) The "fmovm.x" instruction w/ dynamic register specification. # 2406 # (3) The "fmovm.l" instruction w/ 2 or 3 con 2406 # (3) The "fmovm.l" instruction w/ 2 or 3 control registers. # 2407 # 2407 # # 2408 # For immediate data operations, the da 2408 # For immediate data operations, the data is read in w/ a # 2409 # _mem_read() "callout", converted to FP bina 2409 # _mem_read() "callout", converted to FP binary (if packed), and used # 2410 # as the source operand to the instruction sp 2410 # as the source operand to the instruction specified by the instruction # 2411 # word. If no FP exception should be reported 2411 # word. If no FP exception should be reported ads a result of the # 2412 # emulation, then the result is stored to the 2412 # emulation, then the result is stored to the destination register and # 2413 # the handler exits through _fpsp_done(). If 2413 # the handler exits through _fpsp_done(). If an enabled exc has been # 2414 # signalled as a result of emulation, then an 2414 # signalled as a result of emulation, then an fsave state frame # 2415 # corresponding to the FP exception type must 2415 # corresponding to the FP exception type must be entered into the 060 # 2416 # FPU before exiting. In either the enabled o 2416 # FPU before exiting. In either the enabled or disabled cases, we # 2417 # must also check if a Trace exception is pen 2417 # must also check if a Trace exception is pending, in which case, we # 2418 # must create a Trace exception stack frame f 2418 # must create a Trace exception stack frame from the current exception # 2419 # stack frame. If no Trace is pending, we sim 2419 # stack frame. If no Trace is pending, we simply exit through # 2420 # _fpsp_done(). 2420 # _fpsp_done(). # 2421 # For "fmovm.x", call the routine fmovm 2421 # For "fmovm.x", call the routine fmovm_dynamic() which will # 2422 # decode and emulate the instruction. No FP e 2422 # decode and emulate the instruction. No FP exceptions can be pending # 2423 # as a result of this operation emulation. A 2423 # as a result of this operation emulation. A Trace exception can be # 2424 # pending, though, which means the current st 2424 # pending, though, which means the current stack frame must be changed # 2425 # to a Trace stack frame and an exit made thr 2425 # to a Trace stack frame and an exit made through _real_trace(). # 2426 # For the case of "fmovm.x Dn,-(a7)", where t 2426 # For the case of "fmovm.x Dn,-(a7)", where the offending instruction # 2427 # was executed from supervisor mode, this han 2427 # was executed from supervisor mode, this handler must store the FP # 2428 # register file values to the system stack by 2428 # register file values to the system stack by itself since # 2429 # fmovm_dynamic() can't handle this. A normal 2429 # fmovm_dynamic() can't handle this. A normal exit is made through # 2430 # fpsp_done(). 2430 # fpsp_done(). # 2431 # For "fmovm.l", fmovm_ctrl() is used t 2431 # For "fmovm.l", fmovm_ctrl() is used to emulate the instruction. # 2432 # Again, a Trace exception may be pending and 2432 # Again, a Trace exception may be pending and an exit made through # 2433 # _real_trace(). Else, a normal exit is made 2433 # _real_trace(). Else, a normal exit is made through _fpsp_done(). # 2434 # 2434 # # 2435 # Before any of the above is attempted, 2435 # Before any of the above is attempted, it must be checked to # 2436 # see if the FPU is disabled. Since the "Unim 2436 # see if the FPU is disabled. Since the "Unimp <ea>" exception is taken # 2437 # before the "FPU disabled" exception, but th 2437 # before the "FPU disabled" exception, but the "FPU disabled" exception # 2438 # has higher priority, we check the disabled 2438 # has higher priority, we check the disabled bit in the PCR. If set, # 2439 # then we must create an 8 word "FPU disabled 2439 # then we must create an 8 word "FPU disabled" exception stack frame # 2440 # from the current 4 word exception stack fra 2440 # from the current 4 word exception stack frame. This includes # 2441 # reproducing the effective address of the in 2441 # reproducing the effective address of the instruction to put on the # 2442 # new stack frame. 2442 # new stack frame. # 2443 # 2443 # # 2444 # In the process of all emulation work, 2444 # In the process of all emulation work, if a _mem_read() # 2445 # "callout" returns a failing result indicati 2445 # "callout" returns a failing result indicating an access error, then # 2446 # we must create an access error stack frame 2446 # we must create an access error stack frame from the current stack # 2447 # frame. This information includes a faulting 2447 # frame. This information includes a faulting address and a fault- # 2448 # status-longword. These are created within t 2448 # status-longword. These are created within this handler. # 2449 # 2449 # # 2450 ############################################# 2450 ######################################################################### 2451 2451 2452 global _fpsp_effadd 2452 global _fpsp_effadd 2453 _fpsp_effadd: 2453 _fpsp_effadd: 2454 2454 2455 # This exception type takes priority over the 2455 # This exception type takes priority over the "Line F Emulator" 2456 # exception. Therefore, the FPU could be disa 2456 # exception. Therefore, the FPU could be disabled when entering here. 2457 # So, we must check to see if it's disabled a 2457 # So, we must check to see if it's disabled and handle that case separately. 2458 mov.l %d0,-(%sp) 2458 mov.l %d0,-(%sp) # save d0 2459 movc %pcr,%d0 2459 movc %pcr,%d0 # load proc cr 2460 btst &0x1,%d0 2460 btst &0x1,%d0 # is FPU disabled? 2461 bne.w iea_disabled 2461 bne.w iea_disabled # yes 2462 mov.l (%sp)+,%d0 2462 mov.l (%sp)+,%d0 # restore d0 2463 2463 2464 link %a6,&-LOCAL_SIZE 2464 link %a6,&-LOCAL_SIZE # init stack frame 2465 2465 2466 movm.l &0x0303,EXC_DREGS(%a6 2466 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2467 fmovm.l %fpcr,%fpsr,%fpiar,US 2467 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 2468 fmovm.x &0xc0,EXC_FPREGS(%a6) 2468 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 2469 2469 2470 # PC of instruction that took the exception i 2470 # PC of instruction that took the exception is the PC in the frame 2471 mov.l EXC_PC(%a6),EXC_EXTWP 2471 mov.l EXC_PC(%a6),EXC_EXTWPTR(%a6) 2472 2472 2473 mov.l EXC_EXTWPTR(%a6),%a0 2473 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 2474 addq.l &0x4,EXC_EXTWPTR(%a6) 2474 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 2475 bsr.l _imem_read_long 2475 bsr.l _imem_read_long # fetch the instruction words 2476 mov.l %d0,EXC_OPWORD(%a6) 2476 mov.l %d0,EXC_OPWORD(%a6) # store OPWORD and EXTWORD 2477 2477 2478 ############################################# 2478 ######################################################################### 2479 2479 2480 tst.w %d0 2480 tst.w %d0 # is operation fmovem? 2481 bmi.w iea_fmovm 2481 bmi.w iea_fmovm # yes 2482 2482 2483 # 2483 # 2484 # here, we will have: 2484 # here, we will have: 2485 # fabs fdabs fsabs facos 2485 # fabs fdabs fsabs facos fmod 2486 # fadd fdadd fsadd fasin 2486 # fadd fdadd fsadd fasin frem 2487 # fcmp fatan 2487 # fcmp fatan fscale 2488 # fdiv fddiv fsdiv fatan 2488 # fdiv fddiv fsdiv fatanh fsin 2489 # fint fcos 2489 # fint fcos fsincos 2490 # fintrz fcosh 2490 # fintrz fcosh fsinh 2491 # fmove fdmove fsmove fetox 2491 # fmove fdmove fsmove fetox ftan 2492 # fmul fdmul fsmul fetox 2492 # fmul fdmul fsmul fetoxm1 ftanh 2493 # fneg fdneg fsneg fgete 2493 # fneg fdneg fsneg fgetexp ftentox 2494 # fsgldiv fgetm 2494 # fsgldiv fgetman ftwotox 2495 # fsglmul flog1 2495 # fsglmul flog10 2496 # fsqrt flog2 2496 # fsqrt flog2 2497 # fsub fdsub fssub flogn 2497 # fsub fdsub fssub flogn 2498 # ftst flogn 2498 # ftst flognp1 2499 # which can all use f<op>.{x,p} 2499 # which can all use f<op>.{x,p} 2500 # so, now it's immediate data extended precis 2500 # so, now it's immediate data extended precision AND PACKED FORMAT! 2501 # 2501 # 2502 iea_op: 2502 iea_op: 2503 andi.l &0x00ff00ff,USER_FPSR 2503 andi.l &0x00ff00ff,USER_FPSR(%a6) 2504 2504 2505 btst &0xa,%d0 2505 btst &0xa,%d0 # is src fmt x or p? 2506 bne.b iea_op_pack 2506 bne.b iea_op_pack # packed 2507 2507 2508 2508 2509 mov.l EXC_EXTWPTR(%a6),%a0 2509 mov.l EXC_EXTWPTR(%a6),%a0 # pass: ptr to #<data> 2510 lea FP_SRC(%a6),%a1 2510 lea FP_SRC(%a6),%a1 # pass: ptr to super addr 2511 mov.l &0xc,%d0 2511 mov.l &0xc,%d0 # pass: 12 bytes 2512 bsr.l _imem_read 2512 bsr.l _imem_read # read extended immediate 2513 2513 2514 tst.l %d1 2514 tst.l %d1 # did ifetch fail? 2515 bne.w iea_iacc 2515 bne.w iea_iacc # yes 2516 2516 2517 bra.b iea_op_setsrc 2517 bra.b iea_op_setsrc 2518 2518 2519 iea_op_pack: 2519 iea_op_pack: 2520 2520 2521 mov.l EXC_EXTWPTR(%a6),%a0 2521 mov.l EXC_EXTWPTR(%a6),%a0 # pass: ptr to #<data> 2522 lea FP_SRC(%a6),%a1 2522 lea FP_SRC(%a6),%a1 # pass: ptr to super dst 2523 mov.l &0xc,%d0 2523 mov.l &0xc,%d0 # pass: 12 bytes 2524 bsr.l _imem_read 2524 bsr.l _imem_read # read packed operand 2525 2525 2526 tst.l %d1 2526 tst.l %d1 # did ifetch fail? 2527 bne.w iea_iacc 2527 bne.w iea_iacc # yes 2528 2528 2529 # The packed operand is an INF or a NAN if th 2529 # The packed operand is an INF or a NAN if the exponent field is all ones. 2530 bfextu FP_SRC(%a6){&1:&15},% 2530 bfextu FP_SRC(%a6){&1:&15},%d0 # get exp 2531 cmpi.w %d0,&0x7fff 2531 cmpi.w %d0,&0x7fff # INF or NAN? 2532 beq.b iea_op_setsrc 2532 beq.b iea_op_setsrc # operand is an INF or NAN 2533 2533 2534 # The packed operand is a zero if the mantiss 2534 # The packed operand is a zero if the mantissa is all zero, else it's 2535 # a normal packed op. 2535 # a normal packed op. 2536 mov.b 3+FP_SRC(%a6),%d0 2536 mov.b 3+FP_SRC(%a6),%d0 # get byte 4 2537 andi.b &0x0f,%d0 2537 andi.b &0x0f,%d0 # clear all but last nybble 2538 bne.b iea_op_gp_not_spec 2538 bne.b iea_op_gp_not_spec # not a zero 2539 tst.l FP_SRC_HI(%a6) 2539 tst.l FP_SRC_HI(%a6) # is lw 2 zero? 2540 bne.b iea_op_gp_not_spec 2540 bne.b iea_op_gp_not_spec # not a zero 2541 tst.l FP_SRC_LO(%a6) 2541 tst.l FP_SRC_LO(%a6) # is lw 3 zero? 2542 beq.b iea_op_setsrc 2542 beq.b iea_op_setsrc # operand is a ZERO 2543 iea_op_gp_not_spec: 2543 iea_op_gp_not_spec: 2544 lea FP_SRC(%a6),%a0 2544 lea FP_SRC(%a6),%a0 # pass: ptr to packed op 2545 bsr.l decbin 2545 bsr.l decbin # convert to extended 2546 fmovm.x &0x80,FP_SRC(%a6) 2546 fmovm.x &0x80,FP_SRC(%a6) # make this the srcop 2547 2547 2548 iea_op_setsrc: 2548 iea_op_setsrc: 2549 addi.l &0xc,EXC_EXTWPTR(%a6) 2549 addi.l &0xc,EXC_EXTWPTR(%a6) # update extension word pointer 2550 2550 2551 # FP_SRC now holds the src operand. 2551 # FP_SRC now holds the src operand. 2552 lea FP_SRC(%a6),%a0 2552 lea FP_SRC(%a6),%a0 # pass: ptr to src op 2553 bsr.l set_tag_x 2553 bsr.l set_tag_x # tag the operand type 2554 mov.b %d0,STAG(%a6) 2554 mov.b %d0,STAG(%a6) # could be ANYTHING!!! 2555 cmpi.b %d0,&UNNORM 2555 cmpi.b %d0,&UNNORM # is operand an UNNORM? 2556 bne.b iea_op_getdst 2556 bne.b iea_op_getdst # no 2557 bsr.l unnorm_fix 2557 bsr.l unnorm_fix # yes; convert to NORM/DENORM/ZERO 2558 mov.b %d0,STAG(%a6) 2558 mov.b %d0,STAG(%a6) # set new optype tag 2559 iea_op_getdst: 2559 iea_op_getdst: 2560 clr.b STORE_FLG(%a6) 2560 clr.b STORE_FLG(%a6) # clear "store result" boolean 2561 2561 2562 btst &0x5,1+EXC_CMDREG(%a6 2562 btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic? 2563 beq.b iea_op_extract 2563 beq.b iea_op_extract # monadic 2564 btst &0x4,1+EXC_CMDREG(%a6 2564 btst &0x4,1+EXC_CMDREG(%a6) # is operation fsincos,ftst,fcmp? 2565 bne.b iea_op_spec 2565 bne.b iea_op_spec # yes 2566 2566 2567 iea_op_loaddst: 2567 iea_op_loaddst: 2568 bfextu EXC_CMDREG(%a6){&6:&3 2568 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno 2569 bsr.l load_fpn2 2569 bsr.l load_fpn2 # load dst operand 2570 2570 2571 lea FP_DST(%a6),%a0 2571 lea FP_DST(%a6),%a0 # pass: ptr to dst op 2572 bsr.l set_tag_x 2572 bsr.l set_tag_x # tag the operand type 2573 mov.b %d0,DTAG(%a6) 2573 mov.b %d0,DTAG(%a6) # could be ANYTHING!!! 2574 cmpi.b %d0,&UNNORM 2574 cmpi.b %d0,&UNNORM # is operand an UNNORM? 2575 bne.b iea_op_extract 2575 bne.b iea_op_extract # no 2576 bsr.l unnorm_fix 2576 bsr.l unnorm_fix # yes; convert to NORM/DENORM/ZERO 2577 mov.b %d0,DTAG(%a6) 2577 mov.b %d0,DTAG(%a6) # set new optype tag 2578 bra.b iea_op_extract 2578 bra.b iea_op_extract 2579 2579 2580 # the operation is fsincos, ftst, or fcmp. on 2580 # the operation is fsincos, ftst, or fcmp. only fcmp is dyadic 2581 iea_op_spec: 2581 iea_op_spec: 2582 btst &0x3,1+EXC_CMDREG(%a6 2582 btst &0x3,1+EXC_CMDREG(%a6) # is operation fsincos? 2583 beq.b iea_op_extract 2583 beq.b iea_op_extract # yes 2584 # now, we're left with ftst and fcmp. so, fir 2584 # now, we're left with ftst and fcmp. so, first let's tag them so that they don't 2585 # store a result. then, only fcmp will branch 2585 # store a result. then, only fcmp will branch back and pick up a dst operand. 2586 st STORE_FLG(%a6) 2586 st STORE_FLG(%a6) # don't store a final result 2587 btst &0x1,1+EXC_CMDREG(%a6 2587 btst &0x1,1+EXC_CMDREG(%a6) # is operation fcmp? 2588 beq.b iea_op_loaddst 2588 beq.b iea_op_loaddst # yes 2589 2589 2590 iea_op_extract: 2590 iea_op_extract: 2591 clr.l %d0 2591 clr.l %d0 2592 mov.b FPCR_MODE(%a6),%d0 2592 mov.b FPCR_MODE(%a6),%d0 # pass: rnd mode,prec 2593 2593 2594 mov.b 1+EXC_CMDREG(%a6),%d1 2594 mov.b 1+EXC_CMDREG(%a6),%d1 2595 andi.w &0x007f,%d1 2595 andi.w &0x007f,%d1 # extract extension 2596 2596 2597 fmov.l &0x0,%fpcr 2597 fmov.l &0x0,%fpcr 2598 fmov.l &0x0,%fpsr 2598 fmov.l &0x0,%fpsr 2599 2599 2600 lea FP_SRC(%a6),%a0 2600 lea FP_SRC(%a6),%a0 2601 lea FP_DST(%a6),%a1 2601 lea FP_DST(%a6),%a1 2602 2602 2603 mov.l (tbl_unsupp.l,%pc,%d1 2603 mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr 2604 jsr (tbl_unsupp.l,%pc,%d1 2604 jsr (tbl_unsupp.l,%pc,%d1.l*1) 2605 2605 2606 # 2606 # 2607 # Exceptions in order of precedence: 2607 # Exceptions in order of precedence: 2608 # BSUN : none 2608 # BSUN : none 2609 # SNAN : all operations 2609 # SNAN : all operations 2610 # OPERR : all reg-reg or mem-reg oper 2610 # OPERR : all reg-reg or mem-reg operations that can normally operr 2611 # OVFL : same as OPERR 2611 # OVFL : same as OPERR 2612 # UNFL : same as OPERR 2612 # UNFL : same as OPERR 2613 # DZ : same as OPERR 2613 # DZ : same as OPERR 2614 # INEX2 : same as OPERR 2614 # INEX2 : same as OPERR 2615 # INEX1 : all packed immediate operat 2615 # INEX1 : all packed immediate operations 2616 # 2616 # 2617 2617 2618 # we determine the highest priority exception 2618 # we determine the highest priority exception(if any) set by the 2619 # emulation routine that has also been enable 2619 # emulation routine that has also been enabled by the user. 2620 mov.b FPCR_ENABLE(%a6),%d0 2620 mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled 2621 bne.b iea_op_ena 2621 bne.b iea_op_ena # some are enabled 2622 2622 2623 # now, we save the result, unless, of course, 2623 # now, we save the result, unless, of course, the operation was ftst or fcmp. 2624 # these don't save results. 2624 # these don't save results. 2625 iea_op_save: 2625 iea_op_save: 2626 tst.b STORE_FLG(%a6) 2626 tst.b STORE_FLG(%a6) # does this op store a result? 2627 bne.b iea_op_exit1 2627 bne.b iea_op_exit1 # exit with no frestore 2628 2628 2629 iea_op_store: 2629 iea_op_store: 2630 bfextu EXC_CMDREG(%a6){&6:&3 2630 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # fetch dst regno 2631 bsr.l store_fpreg 2631 bsr.l store_fpreg # store the result 2632 2632 2633 iea_op_exit1: 2633 iea_op_exit1: 2634 mov.l EXC_PC(%a6),USER_FPIA 2634 mov.l EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC" 2635 mov.l EXC_EXTWPTR(%a6),EXC_ 2635 mov.l EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame 2636 2636 2637 fmovm.x EXC_FPREGS(%a6),&0xc0 2637 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 2638 fmovm.l USER_FPCR(%a6),%fpcr, 2638 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2639 movm.l EXC_DREGS(%a6),&0x030 2639 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2640 2640 2641 unlk %a6 2641 unlk %a6 # unravel the frame 2642 2642 2643 btst &0x7,(%sp) 2643 btst &0x7,(%sp) # is trace on? 2644 bne.w iea_op_trace 2644 bne.w iea_op_trace # yes 2645 2645 2646 bra.l _fpsp_done 2646 bra.l _fpsp_done # exit to os 2647 2647 2648 iea_op_ena: 2648 iea_op_ena: 2649 and.b FPSR_EXCEPT(%a6),%d0 2649 and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enable and set 2650 bfffo %d0{&24:&8},%d0 2650 bfffo %d0{&24:&8},%d0 # find highest priority exception 2651 bne.b iea_op_exc 2651 bne.b iea_op_exc # at least one was set 2652 2652 2653 # no exception occurred. now, did a disabled, 2653 # no exception occurred. now, did a disabled, exact overflow occur with inexact 2654 # enabled? if so, then we have to stuff an ov 2654 # enabled? if so, then we have to stuff an overflow frame into the FPU. 2655 btst &ovfl_bit,FPSR_EXCEPT 2655 btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur? 2656 beq.b iea_op_save 2656 beq.b iea_op_save 2657 2657 2658 iea_op_ovfl: 2658 iea_op_ovfl: 2659 btst &inex2_bit,FPCR_ENABL 2659 btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled? 2660 beq.b iea_op_store 2660 beq.b iea_op_store # no 2661 bra.b iea_op_exc_ovfl 2661 bra.b iea_op_exc_ovfl # yes 2662 2662 2663 # an enabled exception occurred. we have to i 2663 # an enabled exception occurred. we have to insert the exception type back into 2664 # the machine. 2664 # the machine. 2665 iea_op_exc: 2665 iea_op_exc: 2666 subi.l &24,%d0 2666 subi.l &24,%d0 # fix offset to be 0-8 2667 cmpi.b %d0,&0x6 2667 cmpi.b %d0,&0x6 # is exception INEX? 2668 bne.b iea_op_exc_force 2668 bne.b iea_op_exc_force # no 2669 2669 2670 # the enabled exception was inexact. so, if i 2670 # the enabled exception was inexact. so, if it occurs with an overflow 2671 # or underflow that was disabled, then we hav 2671 # or underflow that was disabled, then we have to force an overflow or 2672 # underflow frame. 2672 # underflow frame. 2673 btst &ovfl_bit,FPSR_EXCEPT 2673 btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur? 2674 bne.b iea_op_exc_ovfl 2674 bne.b iea_op_exc_ovfl # yes 2675 btst &unfl_bit,FPSR_EXCEPT 2675 btst &unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur? 2676 bne.b iea_op_exc_unfl 2676 bne.b iea_op_exc_unfl # yes 2677 2677 2678 iea_op_exc_force: 2678 iea_op_exc_force: 2679 mov.w (tbl_iea_except.b,%pc 2679 mov.w (tbl_iea_except.b,%pc,%d0.w*2),2+FP_SRC(%a6) 2680 bra.b iea_op_exit2 2680 bra.b iea_op_exit2 # exit with frestore 2681 2681 2682 tbl_iea_except: 2682 tbl_iea_except: 2683 short 0xe002, 0xe006, 0xe00 2683 short 0xe002, 0xe006, 0xe004, 0xe005 2684 short 0xe003, 0xe002, 0xe00 2684 short 0xe003, 0xe002, 0xe001, 0xe001 2685 2685 2686 iea_op_exc_ovfl: 2686 iea_op_exc_ovfl: 2687 mov.w &0xe005,2+FP_SRC(%a6) 2687 mov.w &0xe005,2+FP_SRC(%a6) 2688 bra.b iea_op_exit2 2688 bra.b iea_op_exit2 2689 2689 2690 iea_op_exc_unfl: 2690 iea_op_exc_unfl: 2691 mov.w &0xe003,2+FP_SRC(%a6) 2691 mov.w &0xe003,2+FP_SRC(%a6) 2692 2692 2693 iea_op_exit2: 2693 iea_op_exit2: 2694 mov.l EXC_PC(%a6),USER_FPIA 2694 mov.l EXC_PC(%a6),USER_FPIAR(%a6) # set FPIAR to "Current PC" 2695 mov.l EXC_EXTWPTR(%a6),EXC_ 2695 mov.l EXC_EXTWPTR(%a6),EXC_PC(%a6) # set "Next PC" in exc frame 2696 2696 2697 fmovm.x EXC_FPREGS(%a6),&0xc0 2697 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 2698 fmovm.l USER_FPCR(%a6),%fpcr, 2698 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2699 movm.l EXC_DREGS(%a6),&0x030 2699 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2700 2700 2701 frestore FP_SRC(%a6) 2701 frestore FP_SRC(%a6) # restore exceptional state 2702 2702 2703 unlk %a6 2703 unlk %a6 # unravel the frame 2704 2704 2705 btst &0x7,(%sp) 2705 btst &0x7,(%sp) # is trace on? 2706 bne.b iea_op_trace 2706 bne.b iea_op_trace # yes 2707 2707 2708 bra.l _fpsp_done 2708 bra.l _fpsp_done # exit to os 2709 2709 2710 # 2710 # 2711 # The opclass two instruction that took an "U 2711 # The opclass two instruction that took an "Unimplemented Effective Address" 2712 # exception was being traced. Make the "curre 2712 # exception was being traced. Make the "current" PC the FPIAR and put it in 2713 # the trace stack frame then jump to _real_tr 2713 # the trace stack frame then jump to _real_trace(). 2714 # 2714 # 2715 # UNIMP EA FRAME TR 2715 # UNIMP EA FRAME TRACE FRAME 2716 # ***************** ***** 2716 # ***************** ***************** 2717 # * 0x0 * 0x0f0 * * 2717 # * 0x0 * 0x0f0 * * Current * 2718 # ***************** * 2718 # ***************** * PC * 2719 # * Current * ***** 2719 # * Current * ***************** 2720 # * PC * * 0x2 2720 # * PC * * 0x2 * 0x024 * 2721 # ***************** ***** 2721 # ***************** ***************** 2722 # * SR * * 2722 # * SR * * Next * 2723 # ***************** * 2723 # ***************** * PC * 2724 # ***** 2724 # ***************** 2725 # * 2725 # * SR * 2726 # ***** 2726 # ***************** 2727 iea_op_trace: 2727 iea_op_trace: 2728 mov.l (%sp),-(%sp) 2728 mov.l (%sp),-(%sp) # shift stack frame "down" 2729 mov.w 0x8(%sp),0x4(%sp) 2729 mov.w 0x8(%sp),0x4(%sp) 2730 mov.w &0x2024,0x6(%sp) 2730 mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x024 2731 fmov.l %fpiar,0x8(%sp) 2731 fmov.l %fpiar,0x8(%sp) # "Current PC" is in FPIAR 2732 2732 2733 bra.l _real_trace 2733 bra.l _real_trace 2734 2734 2735 ############################################# 2735 ######################################################################### 2736 iea_fmovm: 2736 iea_fmovm: 2737 btst &14,%d0 2737 btst &14,%d0 # ctrl or data reg 2738 beq.w iea_fmovm_ctrl 2738 beq.w iea_fmovm_ctrl 2739 2739 2740 iea_fmovm_data: 2740 iea_fmovm_data: 2741 2741 2742 btst &0x5,EXC_SR(%a6) 2742 btst &0x5,EXC_SR(%a6) # user or supervisor mode 2743 bne.b iea_fmovm_data_s 2743 bne.b iea_fmovm_data_s 2744 2744 2745 iea_fmovm_data_u: 2745 iea_fmovm_data_u: 2746 mov.l %usp,%a0 2746 mov.l %usp,%a0 2747 mov.l %a0,EXC_A7(%a6) 2747 mov.l %a0,EXC_A7(%a6) # store current a7 2748 bsr.l fmovm_dynamic 2748 bsr.l fmovm_dynamic # do dynamic fmovm 2749 mov.l EXC_A7(%a6),%a0 2749 mov.l EXC_A7(%a6),%a0 # load possibly new a7 2750 mov.l %a0,%usp 2750 mov.l %a0,%usp # update usp 2751 bra.w iea_fmovm_exit 2751 bra.w iea_fmovm_exit 2752 2752 2753 iea_fmovm_data_s: 2753 iea_fmovm_data_s: 2754 clr.b SPCOND_FLG(%a6) 2754 clr.b SPCOND_FLG(%a6) 2755 lea 0x2+EXC_VOFF(%a6),%a0 2755 lea 0x2+EXC_VOFF(%a6),%a0 2756 mov.l %a0,EXC_A7(%a6) 2756 mov.l %a0,EXC_A7(%a6) 2757 bsr.l fmovm_dynamic 2757 bsr.l fmovm_dynamic # do dynamic fmovm 2758 2758 2759 cmpi.b SPCOND_FLG(%a6),&mda7 2759 cmpi.b SPCOND_FLG(%a6),&mda7_flg 2760 beq.w iea_fmovm_data_predec 2760 beq.w iea_fmovm_data_predec 2761 cmpi.b SPCOND_FLG(%a6),&mia7 2761 cmpi.b SPCOND_FLG(%a6),&mia7_flg 2762 bne.w iea_fmovm_exit 2762 bne.w iea_fmovm_exit 2763 2763 2764 # right now, d0 = the size. 2764 # right now, d0 = the size. 2765 # the data has been fetched from the supervis 2765 # the data has been fetched from the supervisor stack, but we have not 2766 # incremented the stack pointer by the approp 2766 # incremented the stack pointer by the appropriate number of bytes. 2767 # do it here. 2767 # do it here. 2768 iea_fmovm_data_postinc: 2768 iea_fmovm_data_postinc: 2769 btst &0x7,EXC_SR(%a6) 2769 btst &0x7,EXC_SR(%a6) 2770 bne.b iea_fmovm_data_pi_tra 2770 bne.b iea_fmovm_data_pi_trace 2771 2771 2772 mov.w EXC_SR(%a6),(EXC_SR,% 2772 mov.w EXC_SR(%a6),(EXC_SR,%a6,%d0) 2773 mov.l EXC_EXTWPTR(%a6),(EXC 2773 mov.l EXC_EXTWPTR(%a6),(EXC_PC,%a6,%d0) 2774 mov.w &0x00f0,(EXC_VOFF,%a6 2774 mov.w &0x00f0,(EXC_VOFF,%a6,%d0) 2775 2775 2776 lea (EXC_SR,%a6,%d0),%a0 2776 lea (EXC_SR,%a6,%d0),%a0 2777 mov.l %a0,EXC_SR(%a6) 2777 mov.l %a0,EXC_SR(%a6) 2778 2778 2779 fmovm.x EXC_FP0(%a6),&0xc0 2779 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 2780 fmovm.l USER_FPCR(%a6),%fpcr, 2780 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2781 movm.l EXC_DREGS(%a6),&0x030 2781 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2782 2782 2783 unlk %a6 2783 unlk %a6 2784 mov.l (%sp)+,%sp 2784 mov.l (%sp)+,%sp 2785 bra.l _fpsp_done 2785 bra.l _fpsp_done 2786 2786 2787 iea_fmovm_data_pi_trace: 2787 iea_fmovm_data_pi_trace: 2788 mov.w EXC_SR(%a6),(EXC_SR-0 2788 mov.w EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0) 2789 mov.l EXC_EXTWPTR(%a6),(EXC 2789 mov.l EXC_EXTWPTR(%a6),(EXC_PC-0x4,%a6,%d0) 2790 mov.w &0x2024,(EXC_VOFF-0x4 2790 mov.w &0x2024,(EXC_VOFF-0x4,%a6,%d0) 2791 mov.l EXC_PC(%a6),(EXC_VOFF 2791 mov.l EXC_PC(%a6),(EXC_VOFF+0x2-0x4,%a6,%d0) 2792 2792 2793 lea (EXC_SR-0x4,%a6,%d0), 2793 lea (EXC_SR-0x4,%a6,%d0),%a0 2794 mov.l %a0,EXC_SR(%a6) 2794 mov.l %a0,EXC_SR(%a6) 2795 2795 2796 fmovm.x EXC_FP0(%a6),&0xc0 2796 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 2797 fmovm.l USER_FPCR(%a6),%fpcr, 2797 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2798 movm.l EXC_DREGS(%a6),&0x030 2798 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2799 2799 2800 unlk %a6 2800 unlk %a6 2801 mov.l (%sp)+,%sp 2801 mov.l (%sp)+,%sp 2802 bra.l _real_trace 2802 bra.l _real_trace 2803 2803 2804 # right now, d1 = size and d0 = the strg. 2804 # right now, d1 = size and d0 = the strg. 2805 iea_fmovm_data_predec: 2805 iea_fmovm_data_predec: 2806 mov.b %d1,EXC_VOFF(%a6) 2806 mov.b %d1,EXC_VOFF(%a6) # store strg 2807 mov.b %d0,0x1+EXC_VOFF(%a6) 2807 mov.b %d0,0x1+EXC_VOFF(%a6) # store size 2808 2808 2809 fmovm.x EXC_FP0(%a6),&0xc0 2809 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 2810 fmovm.l USER_FPCR(%a6),%fpcr, 2810 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2811 movm.l EXC_DREGS(%a6),&0x030 2811 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2812 2812 2813 mov.l (%a6),-(%sp) 2813 mov.l (%a6),-(%sp) # make a copy of a6 2814 mov.l %d0,-(%sp) 2814 mov.l %d0,-(%sp) # save d0 2815 mov.l %d1,-(%sp) 2815 mov.l %d1,-(%sp) # save d1 2816 mov.l EXC_EXTWPTR(%a6),-(%s 2816 mov.l EXC_EXTWPTR(%a6),-(%sp) # make a copy of Next PC 2817 2817 2818 clr.l %d0 2818 clr.l %d0 2819 mov.b 0x1+EXC_VOFF(%a6),%d0 2819 mov.b 0x1+EXC_VOFF(%a6),%d0 # fetch size 2820 neg.l %d0 2820 neg.l %d0 # get negative of size 2821 2821 2822 btst &0x7,EXC_SR(%a6) 2822 btst &0x7,EXC_SR(%a6) # is trace enabled? 2823 beq.b iea_fmovm_data_p2 2823 beq.b iea_fmovm_data_p2 2824 2824 2825 mov.w EXC_SR(%a6),(EXC_SR-0 2825 mov.w EXC_SR(%a6),(EXC_SR-0x4,%a6,%d0) 2826 mov.l EXC_PC(%a6),(EXC_VOFF 2826 mov.l EXC_PC(%a6),(EXC_VOFF-0x2,%a6,%d0) 2827 mov.l (%sp)+,(EXC_PC-0x4,%a 2827 mov.l (%sp)+,(EXC_PC-0x4,%a6,%d0) 2828 mov.w &0x2024,(EXC_VOFF-0x4 2828 mov.w &0x2024,(EXC_VOFF-0x4,%a6,%d0) 2829 2829 2830 pea (%a6,%d0) 2830 pea (%a6,%d0) # create final sp 2831 bra.b iea_fmovm_data_p3 2831 bra.b iea_fmovm_data_p3 2832 2832 2833 iea_fmovm_data_p2: 2833 iea_fmovm_data_p2: 2834 mov.w EXC_SR(%a6),(EXC_SR,% 2834 mov.w EXC_SR(%a6),(EXC_SR,%a6,%d0) 2835 mov.l (%sp)+,(EXC_PC,%a6,%d 2835 mov.l (%sp)+,(EXC_PC,%a6,%d0) 2836 mov.w &0x00f0,(EXC_VOFF,%a6 2836 mov.w &0x00f0,(EXC_VOFF,%a6,%d0) 2837 2837 2838 pea (0x4,%a6,%d0) 2838 pea (0x4,%a6,%d0) # create final sp 2839 2839 2840 iea_fmovm_data_p3: 2840 iea_fmovm_data_p3: 2841 clr.l %d1 2841 clr.l %d1 2842 mov.b EXC_VOFF(%a6),%d1 2842 mov.b EXC_VOFF(%a6),%d1 # fetch strg 2843 2843 2844 tst.b %d1 2844 tst.b %d1 2845 bpl.b fm_1 2845 bpl.b fm_1 2846 fmovm.x &0x80,(0x4+0x8,%a6,%d 2846 fmovm.x &0x80,(0x4+0x8,%a6,%d0) 2847 addi.l &0xc,%d0 2847 addi.l &0xc,%d0 2848 fm_1: 2848 fm_1: 2849 lsl.b &0x1,%d1 2849 lsl.b &0x1,%d1 2850 bpl.b fm_2 2850 bpl.b fm_2 2851 fmovm.x &0x40,(0x4+0x8,%a6,%d 2851 fmovm.x &0x40,(0x4+0x8,%a6,%d0) 2852 addi.l &0xc,%d0 2852 addi.l &0xc,%d0 2853 fm_2: 2853 fm_2: 2854 lsl.b &0x1,%d1 2854 lsl.b &0x1,%d1 2855 bpl.b fm_3 2855 bpl.b fm_3 2856 fmovm.x &0x20,(0x4+0x8,%a6,%d 2856 fmovm.x &0x20,(0x4+0x8,%a6,%d0) 2857 addi.l &0xc,%d0 2857 addi.l &0xc,%d0 2858 fm_3: 2858 fm_3: 2859 lsl.b &0x1,%d1 2859 lsl.b &0x1,%d1 2860 bpl.b fm_4 2860 bpl.b fm_4 2861 fmovm.x &0x10,(0x4+0x8,%a6,%d 2861 fmovm.x &0x10,(0x4+0x8,%a6,%d0) 2862 addi.l &0xc,%d0 2862 addi.l &0xc,%d0 2863 fm_4: 2863 fm_4: 2864 lsl.b &0x1,%d1 2864 lsl.b &0x1,%d1 2865 bpl.b fm_5 2865 bpl.b fm_5 2866 fmovm.x &0x08,(0x4+0x8,%a6,%d 2866 fmovm.x &0x08,(0x4+0x8,%a6,%d0) 2867 addi.l &0xc,%d0 2867 addi.l &0xc,%d0 2868 fm_5: 2868 fm_5: 2869 lsl.b &0x1,%d1 2869 lsl.b &0x1,%d1 2870 bpl.b fm_6 2870 bpl.b fm_6 2871 fmovm.x &0x04,(0x4+0x8,%a6,%d 2871 fmovm.x &0x04,(0x4+0x8,%a6,%d0) 2872 addi.l &0xc,%d0 2872 addi.l &0xc,%d0 2873 fm_6: 2873 fm_6: 2874 lsl.b &0x1,%d1 2874 lsl.b &0x1,%d1 2875 bpl.b fm_7 2875 bpl.b fm_7 2876 fmovm.x &0x02,(0x4+0x8,%a6,%d 2876 fmovm.x &0x02,(0x4+0x8,%a6,%d0) 2877 addi.l &0xc,%d0 2877 addi.l &0xc,%d0 2878 fm_7: 2878 fm_7: 2879 lsl.b &0x1,%d1 2879 lsl.b &0x1,%d1 2880 bpl.b fm_end 2880 bpl.b fm_end 2881 fmovm.x &0x01,(0x4+0x8,%a6,%d 2881 fmovm.x &0x01,(0x4+0x8,%a6,%d0) 2882 fm_end: 2882 fm_end: 2883 mov.l 0x4(%sp),%d1 2883 mov.l 0x4(%sp),%d1 2884 mov.l 0x8(%sp),%d0 2884 mov.l 0x8(%sp),%d0 2885 mov.l 0xc(%sp),%a6 2885 mov.l 0xc(%sp),%a6 2886 mov.l (%sp)+,%sp 2886 mov.l (%sp)+,%sp 2887 2887 2888 btst &0x7,(%sp) 2888 btst &0x7,(%sp) # is trace enabled? 2889 beq.l _fpsp_done 2889 beq.l _fpsp_done 2890 bra.l _real_trace 2890 bra.l _real_trace 2891 2891 2892 ############################################# 2892 ######################################################################### 2893 iea_fmovm_ctrl: 2893 iea_fmovm_ctrl: 2894 2894 2895 bsr.l fmovm_ctrl 2895 bsr.l fmovm_ctrl # load ctrl regs 2896 2896 2897 iea_fmovm_exit: 2897 iea_fmovm_exit: 2898 fmovm.x EXC_FPREGS(%a6),&0xc0 2898 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 2899 fmovm.l USER_FPCR(%a6),%fpcr, 2899 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 2900 movm.l EXC_DREGS(%a6),&0x030 2900 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2901 2901 2902 btst &0x7,EXC_SR(%a6) 2902 btst &0x7,EXC_SR(%a6) # is trace on? 2903 bne.b iea_fmovm_trace 2903 bne.b iea_fmovm_trace # yes 2904 2904 2905 mov.l EXC_EXTWPTR(%a6),EXC_ 2905 mov.l EXC_EXTWPTR(%a6),EXC_PC(%a6) # set Next PC 2906 2906 2907 unlk %a6 2907 unlk %a6 # unravel the frame 2908 2908 2909 bra.l _fpsp_done 2909 bra.l _fpsp_done # exit to os 2910 2910 2911 # 2911 # 2912 # The control reg instruction that took an "U 2912 # The control reg instruction that took an "Unimplemented Effective Address" 2913 # exception was being traced. The "Current PC 2913 # exception was being traced. The "Current PC" for the trace frame is the 2914 # PC stacked for Unimp EA. The "Next PC" is i 2914 # PC stacked for Unimp EA. The "Next PC" is in EXC_EXTWPTR. 2915 # After fixing the stack frame, jump to _real 2915 # After fixing the stack frame, jump to _real_trace(). 2916 # 2916 # 2917 # UNIMP EA FRAME TR 2917 # UNIMP EA FRAME TRACE FRAME 2918 # ***************** ***** 2918 # ***************** ***************** 2919 # * 0x0 * 0x0f0 * * 2919 # * 0x0 * 0x0f0 * * Current * 2920 # ***************** * 2920 # ***************** * PC * 2921 # * Current * ***** 2921 # * Current * ***************** 2922 # * PC * * 0x2 2922 # * PC * * 0x2 * 0x024 * 2923 # ***************** ***** 2923 # ***************** ***************** 2924 # * SR * * 2924 # * SR * * Next * 2925 # ***************** * 2925 # ***************** * PC * 2926 # ***** 2926 # ***************** 2927 # * 2927 # * SR * 2928 # ***** 2928 # ***************** 2929 # this ain't a pretty solution, but it works: 2929 # this ain't a pretty solution, but it works: 2930 # -restore a6 (not with unlk) 2930 # -restore a6 (not with unlk) 2931 # -shift stack frame down over where old a6 u 2931 # -shift stack frame down over where old a6 used to be 2932 # -add LOCAL_SIZE to stack pointer 2932 # -add LOCAL_SIZE to stack pointer 2933 iea_fmovm_trace: 2933 iea_fmovm_trace: 2934 mov.l (%a6),%a6 2934 mov.l (%a6),%a6 # restore frame pointer 2935 mov.w EXC_SR+LOCAL_SIZE(%sp 2935 mov.w EXC_SR+LOCAL_SIZE(%sp),0x0+LOCAL_SIZE(%sp) 2936 mov.l EXC_PC+LOCAL_SIZE(%sp 2936 mov.l EXC_PC+LOCAL_SIZE(%sp),0x8+LOCAL_SIZE(%sp) 2937 mov.l EXC_EXTWPTR+LOCAL_SIZ 2937 mov.l EXC_EXTWPTR+LOCAL_SIZE(%sp),0x2+LOCAL_SIZE(%sp) 2938 mov.w &0x2024,0x6+LOCAL_SIZ 2938 mov.w &0x2024,0x6+LOCAL_SIZE(%sp) # stk fmt = 0x2; voff = 0x024 2939 add.l &LOCAL_SIZE,%sp 2939 add.l &LOCAL_SIZE,%sp # clear stack frame 2940 2940 2941 bra.l _real_trace 2941 bra.l _real_trace 2942 2942 2943 ############################################# 2943 ######################################################################### 2944 # The FPU is disabled and so we should really 2944 # The FPU is disabled and so we should really have taken the "Line 2945 # F Emulator" exception. So, here we create a 2945 # F Emulator" exception. So, here we create an 8-word stack frame 2946 # from our 4-word stack frame. This means we 2946 # from our 4-word stack frame. This means we must calculate the length 2947 # the faulting instruction to get the "next P 2947 # the faulting instruction to get the "next PC". This is trivial for 2948 # immediate operands but requires some extra 2948 # immediate operands but requires some extra work for fmovm dynamic 2949 # which can use most addressing modes. 2949 # which can use most addressing modes. 2950 iea_disabled: 2950 iea_disabled: 2951 mov.l (%sp)+,%d0 2951 mov.l (%sp)+,%d0 # restore d0 2952 2952 2953 link %a6,&-LOCAL_SIZE 2953 link %a6,&-LOCAL_SIZE # init stack frame 2954 2954 2955 movm.l &0x0303,EXC_DREGS(%a6 2955 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 2956 2956 2957 # PC of instruction that took the exception i 2957 # PC of instruction that took the exception is the PC in the frame 2958 mov.l EXC_PC(%a6),EXC_EXTWP 2958 mov.l EXC_PC(%a6),EXC_EXTWPTR(%a6) 2959 mov.l EXC_EXTWPTR(%a6),%a0 2959 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 2960 addq.l &0x4,EXC_EXTWPTR(%a6) 2960 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 2961 bsr.l _imem_read_long 2961 bsr.l _imem_read_long # fetch the instruction words 2962 mov.l %d0,EXC_OPWORD(%a6) 2962 mov.l %d0,EXC_OPWORD(%a6) # store OPWORD and EXTWORD 2963 2963 2964 tst.w %d0 2964 tst.w %d0 # is instr fmovm? 2965 bmi.b iea_dis_fmovm 2965 bmi.b iea_dis_fmovm # yes 2966 # instruction is using an extended precision 2966 # instruction is using an extended precision immediate operand. Therefore, 2967 # the total instruction length is 16 bytes. 2967 # the total instruction length is 16 bytes. 2968 iea_dis_immed: 2968 iea_dis_immed: 2969 mov.l &0x10,%d0 2969 mov.l &0x10,%d0 # 16 bytes of instruction 2970 bra.b iea_dis_cont 2970 bra.b iea_dis_cont 2971 iea_dis_fmovm: 2971 iea_dis_fmovm: 2972 btst &0xe,%d0 2972 btst &0xe,%d0 # is instr fmovm ctrl 2973 bne.b iea_dis_fmovm_data 2973 bne.b iea_dis_fmovm_data # no 2974 # the instruction is a fmovm.l with 2 or 3 re 2974 # the instruction is a fmovm.l with 2 or 3 registers. 2975 bfextu %d0{&19:&3},%d1 2975 bfextu %d0{&19:&3},%d1 2976 mov.l &0xc,%d0 2976 mov.l &0xc,%d0 2977 cmpi.b %d1,&0x7 2977 cmpi.b %d1,&0x7 # move all regs? 2978 bne.b iea_dis_cont 2978 bne.b iea_dis_cont 2979 addq.l &0x4,%d0 2979 addq.l &0x4,%d0 2980 bra.b iea_dis_cont 2980 bra.b iea_dis_cont 2981 # the instruction is an fmovm.x dynamic which 2981 # the instruction is an fmovm.x dynamic which can use many addressing 2982 # modes and thus can have several different t 2982 # modes and thus can have several different total instruction lengths. 2983 # call fmovm_calc_ea which will go through th 2983 # call fmovm_calc_ea which will go through the ea calc process and, 2984 # as a by-product, will tell us how long the 2984 # as a by-product, will tell us how long the instruction is. 2985 iea_dis_fmovm_data: 2985 iea_dis_fmovm_data: 2986 clr.l %d0 2986 clr.l %d0 2987 bsr.l fmovm_calc_ea 2987 bsr.l fmovm_calc_ea 2988 mov.l EXC_EXTWPTR(%a6),%d0 2988 mov.l EXC_EXTWPTR(%a6),%d0 2989 sub.l EXC_PC(%a6),%d0 2989 sub.l EXC_PC(%a6),%d0 2990 iea_dis_cont: 2990 iea_dis_cont: 2991 mov.w %d0,EXC_VOFF(%a6) 2991 mov.w %d0,EXC_VOFF(%a6) # store stack shift value 2992 2992 2993 movm.l EXC_DREGS(%a6),&0x030 2993 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 2994 2994 2995 unlk %a6 2995 unlk %a6 2996 2996 2997 # here, we actually create the 8-word frame f 2997 # here, we actually create the 8-word frame from the 4-word frame, 2998 # with the "next PC" as additional info. 2998 # with the "next PC" as additional info. 2999 # the <ea> field is let as undefined. 2999 # the <ea> field is let as undefined. 3000 subq.l &0x8,%sp 3000 subq.l &0x8,%sp # make room for new stack 3001 mov.l %d0,-(%sp) 3001 mov.l %d0,-(%sp) # save d0 3002 mov.w 0xc(%sp),0x4(%sp) 3002 mov.w 0xc(%sp),0x4(%sp) # move SR 3003 mov.l 0xe(%sp),0x6(%sp) 3003 mov.l 0xe(%sp),0x6(%sp) # move Current PC 3004 clr.l %d0 3004 clr.l %d0 3005 mov.w 0x12(%sp),%d0 3005 mov.w 0x12(%sp),%d0 3006 mov.l 0x6(%sp),0x10(%sp) 3006 mov.l 0x6(%sp),0x10(%sp) # move Current PC 3007 add.l %d0,0x6(%sp) 3007 add.l %d0,0x6(%sp) # make Next PC 3008 mov.w &0x402c,0xa(%sp) 3008 mov.w &0x402c,0xa(%sp) # insert offset,frame format 3009 mov.l (%sp)+,%d0 3009 mov.l (%sp)+,%d0 # restore d0 3010 3010 3011 bra.l _real_fpu_disabled 3011 bra.l _real_fpu_disabled 3012 3012 3013 ########## 3013 ########## 3014 3014 3015 iea_iacc: 3015 iea_iacc: 3016 movc %pcr,%d0 3016 movc %pcr,%d0 3017 btst &0x1,%d0 3017 btst &0x1,%d0 3018 bne.b iea_iacc_cont 3018 bne.b iea_iacc_cont 3019 fmovm.l USER_FPCR(%a6),%fpcr, 3019 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 3020 fmovm.x EXC_FPREGS(%a6),&0xc0 3020 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 on stack 3021 iea_iacc_cont: 3021 iea_iacc_cont: 3022 movm.l EXC_DREGS(%a6),&0x030 3022 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3023 3023 3024 unlk %a6 3024 unlk %a6 3025 3025 3026 subq.w &0x8,%sp 3026 subq.w &0x8,%sp # make stack frame bigger 3027 mov.l 0x8(%sp),(%sp) 3027 mov.l 0x8(%sp),(%sp) # store SR,hi(PC) 3028 mov.w 0xc(%sp),0x4(%sp) 3028 mov.w 0xc(%sp),0x4(%sp) # store lo(PC) 3029 mov.w &0x4008,0x6(%sp) 3029 mov.w &0x4008,0x6(%sp) # store voff 3030 mov.l 0x2(%sp),0x8(%sp) 3030 mov.l 0x2(%sp),0x8(%sp) # store ea 3031 mov.l &0x09428001,0xc(%sp) 3031 mov.l &0x09428001,0xc(%sp) # store fslw 3032 3032 3033 iea_acc_done: 3033 iea_acc_done: 3034 btst &0x5,(%sp) 3034 btst &0x5,(%sp) # user or supervisor mode? 3035 beq.b iea_acc_done2 3035 beq.b iea_acc_done2 # user 3036 bset &0x2,0xd(%sp) 3036 bset &0x2,0xd(%sp) # set supervisor TM bit 3037 3037 3038 iea_acc_done2: 3038 iea_acc_done2: 3039 bra.l _real_access 3039 bra.l _real_access 3040 3040 3041 iea_dacc: 3041 iea_dacc: 3042 lea -LOCAL_SIZE(%a6),%sp 3042 lea -LOCAL_SIZE(%a6),%sp 3043 3043 3044 movc %pcr,%d1 3044 movc %pcr,%d1 3045 btst &0x1,%d1 3045 btst &0x1,%d1 3046 bne.b iea_dacc_cont 3046 bne.b iea_dacc_cont 3047 fmovm.x EXC_FPREGS(%a6),&0xc0 3047 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 on stack 3048 fmovm.l LOCAL_SIZE+USER_FPCR( 3048 fmovm.l LOCAL_SIZE+USER_FPCR(%sp),%fpcr,%fpsr,%fpiar # restore ctrl regs 3049 iea_dacc_cont: 3049 iea_dacc_cont: 3050 mov.l (%a6),%a6 3050 mov.l (%a6),%a6 3051 3051 3052 mov.l 0x4+LOCAL_SIZE(%sp),- 3052 mov.l 0x4+LOCAL_SIZE(%sp),-0x8+0x4+LOCAL_SIZE(%sp) 3053 mov.w 0x8+LOCAL_SIZE(%sp),- 3053 mov.w 0x8+LOCAL_SIZE(%sp),-0x8+0x8+LOCAL_SIZE(%sp) 3054 mov.w &0x4008,-0x8+0xa+LOCA 3054 mov.w &0x4008,-0x8+0xa+LOCAL_SIZE(%sp) 3055 mov.l %a0,-0x8+0xc+LOCAL_SI 3055 mov.l %a0,-0x8+0xc+LOCAL_SIZE(%sp) 3056 mov.w %d0,-0x8+0x10+LOCAL_S 3056 mov.w %d0,-0x8+0x10+LOCAL_SIZE(%sp) 3057 mov.w &0x0001,-0x8+0x12+LOC 3057 mov.w &0x0001,-0x8+0x12+LOCAL_SIZE(%sp) 3058 3058 3059 movm.l LOCAL_SIZE+EXC_DREGS( 3059 movm.l LOCAL_SIZE+EXC_DREGS(%sp),&0x0303 # restore d0-d1/a0-a1 3060 add.w &LOCAL_SIZE-0x4,%sp 3060 add.w &LOCAL_SIZE-0x4,%sp 3061 3061 3062 bra.b iea_acc_done 3062 bra.b iea_acc_done 3063 3063 3064 ############################################# 3064 ######################################################################### 3065 # XDEF ************************************** 3065 # XDEF **************************************************************** # 3066 # _fpsp_operr(): 060FPSP entry point fo 3066 # _fpsp_operr(): 060FPSP entry point for FP Operr exception. # 3067 # 3067 # # 3068 # This handler should be the first code 3068 # This handler should be the first code executed upon taking the # 3069 # FP Operand Error exception in an oper 3069 # FP Operand Error exception in an operating system. # 3070 # 3070 # # 3071 # XREF ************************************** 3071 # XREF **************************************************************** # 3072 # _imem_read_long() - read instruction 3072 # _imem_read_long() - read instruction longword # 3073 # fix_skewed_ops() - adjust src operand 3073 # fix_skewed_ops() - adjust src operand in fsave frame # 3074 # _real_operr() - "callout" to operatin 3074 # _real_operr() - "callout" to operating system operr handler # 3075 # _dmem_write_{byte,word,long}() - stor 3075 # _dmem_write_{byte,word,long}() - store data to mem (opclass 3) # 3076 # store_dreg_{b,w,l}() - store data to 3076 # store_dreg_{b,w,l}() - store data to data regfile (opclass 3) # 3077 # facc_out_{b,w,l}() - store to memory 3077 # facc_out_{b,w,l}() - store to memory took access error (opcl 3) # 3078 # 3078 # # 3079 # INPUT ************************************* 3079 # INPUT *************************************************************** # 3080 # - The system stack contains the FP Op 3080 # - The system stack contains the FP Operr exception frame # 3081 # - The fsave frame contains the source 3081 # - The fsave frame contains the source operand # 3082 # 3082 # # 3083 # OUTPUT ************************************ 3083 # OUTPUT ************************************************************** # 3084 # No access error: 3084 # No access error: # 3085 # - The system stack is unchanged 3085 # - The system stack is unchanged # 3086 # - The fsave frame contains the adjust 3086 # - The fsave frame contains the adjusted src op for opclass 0,2 # 3087 # 3087 # # 3088 # ALGORITHM ********************************* 3088 # ALGORITHM *********************************************************** # 3089 # In a system where the FP Operr except 3089 # In a system where the FP Operr exception is enabled, the goal # 3090 # is to get to the handler specified at _real 3090 # is to get to the handler specified at _real_operr(). But, on the 060, # 3091 # for opclass zero and two instruction taking 3091 # for opclass zero and two instruction taking this exception, the # 3092 # input operand in the fsave frame may be inc 3092 # input operand in the fsave frame may be incorrect for some cases # 3093 # and needs to be corrected. This handler cal 3093 # and needs to be corrected. This handler calls fix_skewed_ops() to # 3094 # do just this and then exits through _real_o 3094 # do just this and then exits through _real_operr(). # 3095 # For opclass 3 instructions, the 060 d 3095 # For opclass 3 instructions, the 060 doesn't store the default # 3096 # operr result out to memory or data register 3096 # operr result out to memory or data register file as it should. # 3097 # This code must emulate the move out before 3097 # This code must emulate the move out before finally exiting through # 3098 # _real_inex(). The move out, if to memory, i 3098 # _real_inex(). The move out, if to memory, is performed using # 3099 # _mem_write() "callout" routines that may re 3099 # _mem_write() "callout" routines that may return a failing result. # 3100 # In this special case, the handler must exit 3100 # In this special case, the handler must exit through facc_out() # 3101 # which creates an access error stack frame f 3101 # which creates an access error stack frame from the current operr # 3102 # stack frame. 3102 # stack frame. # 3103 # 3103 # # 3104 ############################################# 3104 ######################################################################### 3105 3105 3106 global _fpsp_operr 3106 global _fpsp_operr 3107 _fpsp_operr: 3107 _fpsp_operr: 3108 3108 3109 link.w %a6,&-LOCAL_SIZE 3109 link.w %a6,&-LOCAL_SIZE # init stack frame 3110 3110 3111 fsave FP_SRC(%a6) 3111 fsave FP_SRC(%a6) # grab the "busy" frame 3112 3112 3113 movm.l &0x0303,EXC_DREGS(%a6 3113 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3114 fmovm.l %fpcr,%fpsr,%fpiar,US 3114 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 3115 fmovm.x &0xc0,EXC_FPREGS(%a6) 3115 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 3116 3116 3117 # the FPIAR holds the "current PC" of the fau 3117 # the FPIAR holds the "current PC" of the faulting instruction 3118 mov.l USER_FPIAR(%a6),EXC_E 3118 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 3119 3119 3120 mov.l EXC_EXTWPTR(%a6),%a0 3120 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 3121 addq.l &0x4,EXC_EXTWPTR(%a6) 3121 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 3122 bsr.l _imem_read_long 3122 bsr.l _imem_read_long # fetch the instruction words 3123 mov.l %d0,EXC_OPWORD(%a6) 3123 mov.l %d0,EXC_OPWORD(%a6) 3124 3124 3125 ############################################# 3125 ############################################################################## 3126 3126 3127 btst &13,%d0 3127 btst &13,%d0 # is instr an fmove out? 3128 bne.b foperr_out 3128 bne.b foperr_out # fmove out 3129 3129 3130 3130 3131 # here, we simply see if the operand in the f 3131 # here, we simply see if the operand in the fsave frame needs to be "unskewed". 3132 # this would be the case for opclass two oper 3132 # this would be the case for opclass two operations with a source infinity or 3133 # denorm operand in the sgl or dbl format. NA 3133 # denorm operand in the sgl or dbl format. NANs also become skewed, but can't 3134 # cause an operr so we don't need to check fo 3134 # cause an operr so we don't need to check for them here. 3135 lea FP_SRC(%a6),%a0 3135 lea FP_SRC(%a6),%a0 # pass: ptr to src op 3136 bsr.l fix_skewed_ops 3136 bsr.l fix_skewed_ops # fix src op 3137 3137 3138 foperr_exit: 3138 foperr_exit: 3139 fmovm.x EXC_FPREGS(%a6),&0xc0 3139 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 3140 fmovm.l USER_FPCR(%a6),%fpcr, 3140 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 3141 movm.l EXC_DREGS(%a6),&0x030 3141 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3142 3142 3143 frestore FP_SRC(%a6) 3143 frestore FP_SRC(%a6) 3144 3144 3145 unlk %a6 3145 unlk %a6 3146 bra.l _real_operr 3146 bra.l _real_operr 3147 3147 3148 ############################################# 3148 ######################################################################## 3149 3149 3150 # 3150 # 3151 # the hardware does not save the default resu 3151 # the hardware does not save the default result to memory on enabled 3152 # operand error exceptions. we do this here b 3152 # operand error exceptions. we do this here before passing control to 3153 # the user operand error handler. 3153 # the user operand error handler. 3154 # 3154 # 3155 # byte, word, and long destination format ope 3155 # byte, word, and long destination format operations can pass 3156 # through here. we simply need to test the si 3156 # through here. we simply need to test the sign of the src 3157 # operand and save the appropriate minimum or 3157 # operand and save the appropriate minimum or maximum integer value 3158 # to the effective address as pointed to by t 3158 # to the effective address as pointed to by the stacked effective address. 3159 # 3159 # 3160 # although packed opclass three operations ca 3160 # although packed opclass three operations can take operand error 3161 # exceptions, they won't pass through here si 3161 # exceptions, they won't pass through here since they are caught 3162 # first by the unsupported data format except 3162 # first by the unsupported data format exception handler. that handler 3163 # sends them directly to _real_operr() if nec 3163 # sends them directly to _real_operr() if necessary. 3164 # 3164 # 3165 foperr_out: 3165 foperr_out: 3166 3166 3167 mov.w FP_SRC_EX(%a6),%d1 3167 mov.w FP_SRC_EX(%a6),%d1 # fetch exponent 3168 andi.w &0x7fff,%d1 3168 andi.w &0x7fff,%d1 3169 cmpi.w %d1,&0x7fff 3169 cmpi.w %d1,&0x7fff 3170 bne.b foperr_out_not_qnan 3170 bne.b foperr_out_not_qnan 3171 # the operand is either an infinity or a QNAN 3171 # the operand is either an infinity or a QNAN. 3172 tst.l FP_SRC_LO(%a6) 3172 tst.l FP_SRC_LO(%a6) 3173 bne.b foperr_out_qnan 3173 bne.b foperr_out_qnan 3174 mov.l FP_SRC_HI(%a6),%d1 3174 mov.l FP_SRC_HI(%a6),%d1 3175 andi.l &0x7fffffff,%d1 3175 andi.l &0x7fffffff,%d1 3176 beq.b foperr_out_not_qnan 3176 beq.b foperr_out_not_qnan 3177 foperr_out_qnan: 3177 foperr_out_qnan: 3178 mov.l FP_SRC_HI(%a6),L_SCR1 3178 mov.l FP_SRC_HI(%a6),L_SCR1(%a6) 3179 bra.b foperr_out_jmp 3179 bra.b foperr_out_jmp 3180 3180 3181 foperr_out_not_qnan: 3181 foperr_out_not_qnan: 3182 mov.l &0x7fffffff,%d1 3182 mov.l &0x7fffffff,%d1 3183 tst.b FP_SRC_EX(%a6) 3183 tst.b FP_SRC_EX(%a6) 3184 bpl.b foperr_out_not_qnan2 3184 bpl.b foperr_out_not_qnan2 3185 addq.l &0x1,%d1 3185 addq.l &0x1,%d1 3186 foperr_out_not_qnan2: 3186 foperr_out_not_qnan2: 3187 mov.l %d1,L_SCR1(%a6) 3187 mov.l %d1,L_SCR1(%a6) 3188 3188 3189 foperr_out_jmp: 3189 foperr_out_jmp: 3190 bfextu %d0{&19:&3},%d0 3190 bfextu %d0{&19:&3},%d0 # extract dst format field 3191 mov.b 1+EXC_OPWORD(%a6),%d1 3191 mov.b 1+EXC_OPWORD(%a6),%d1 # extract <ea> mode,reg 3192 mov.w (tbl_operr.b,%pc,%d0. 3192 mov.w (tbl_operr.b,%pc,%d0.w*2),%a0 3193 jmp (tbl_operr.b,%pc,%a0) 3193 jmp (tbl_operr.b,%pc,%a0) 3194 3194 3195 tbl_operr: 3195 tbl_operr: 3196 short foperr_out_l - tbl_op 3196 short foperr_out_l - tbl_operr # long word integer 3197 short tbl_operr - tbl_op 3197 short tbl_operr - tbl_operr # sgl prec shouldn't happen 3198 short tbl_operr - tbl_op 3198 short tbl_operr - tbl_operr # ext prec shouldn't happen 3199 short foperr_exit - tbl_op 3199 short foperr_exit - tbl_operr # packed won't enter here 3200 short foperr_out_w - tbl_op 3200 short foperr_out_w - tbl_operr # word integer 3201 short tbl_operr - tbl_op 3201 short tbl_operr - tbl_operr # dbl prec shouldn't happen 3202 short foperr_out_b - tbl_op 3202 short foperr_out_b - tbl_operr # byte integer 3203 short tbl_operr - tbl_op 3203 short tbl_operr - tbl_operr # packed won't enter here 3204 3204 3205 foperr_out_b: 3205 foperr_out_b: 3206 mov.b L_SCR1(%a6),%d0 3206 mov.b L_SCR1(%a6),%d0 # load positive default result 3207 cmpi.b %d1,&0x7 3207 cmpi.b %d1,&0x7 # is <ea> mode a data reg? 3208 ble.b foperr_out_b_save_dn 3208 ble.b foperr_out_b_save_dn # yes 3209 mov.l EXC_EA(%a6),%a0 3209 mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result 3210 bsr.l _dmem_write_byte 3210 bsr.l _dmem_write_byte # write the default result 3211 3211 3212 tst.l %d1 3212 tst.l %d1 # did dstore fail? 3213 bne.l facc_out_b 3213 bne.l facc_out_b # yes 3214 3214 3215 bra.w foperr_exit 3215 bra.w foperr_exit 3216 foperr_out_b_save_dn: 3216 foperr_out_b_save_dn: 3217 andi.w &0x0007,%d1 3217 andi.w &0x0007,%d1 3218 bsr.l store_dreg_b 3218 bsr.l store_dreg_b # store result to regfile 3219 bra.w foperr_exit 3219 bra.w foperr_exit 3220 3220 3221 foperr_out_w: 3221 foperr_out_w: 3222 mov.w L_SCR1(%a6),%d0 3222 mov.w L_SCR1(%a6),%d0 # load positive default result 3223 cmpi.b %d1,&0x7 3223 cmpi.b %d1,&0x7 # is <ea> mode a data reg? 3224 ble.b foperr_out_w_save_dn 3224 ble.b foperr_out_w_save_dn # yes 3225 mov.l EXC_EA(%a6),%a0 3225 mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result 3226 bsr.l _dmem_write_word 3226 bsr.l _dmem_write_word # write the default result 3227 3227 3228 tst.l %d1 3228 tst.l %d1 # did dstore fail? 3229 bne.l facc_out_w 3229 bne.l facc_out_w # yes 3230 3230 3231 bra.w foperr_exit 3231 bra.w foperr_exit 3232 foperr_out_w_save_dn: 3232 foperr_out_w_save_dn: 3233 andi.w &0x0007,%d1 3233 andi.w &0x0007,%d1 3234 bsr.l store_dreg_w 3234 bsr.l store_dreg_w # store result to regfile 3235 bra.w foperr_exit 3235 bra.w foperr_exit 3236 3236 3237 foperr_out_l: 3237 foperr_out_l: 3238 mov.l L_SCR1(%a6),%d0 3238 mov.l L_SCR1(%a6),%d0 # load positive default result 3239 cmpi.b %d1,&0x7 3239 cmpi.b %d1,&0x7 # is <ea> mode a data reg? 3240 ble.b foperr_out_l_save_dn 3240 ble.b foperr_out_l_save_dn # yes 3241 mov.l EXC_EA(%a6),%a0 3241 mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result 3242 bsr.l _dmem_write_long 3242 bsr.l _dmem_write_long # write the default result 3243 3243 3244 tst.l %d1 3244 tst.l %d1 # did dstore fail? 3245 bne.l facc_out_l 3245 bne.l facc_out_l # yes 3246 3246 3247 bra.w foperr_exit 3247 bra.w foperr_exit 3248 foperr_out_l_save_dn: 3248 foperr_out_l_save_dn: 3249 andi.w &0x0007,%d1 3249 andi.w &0x0007,%d1 3250 bsr.l store_dreg_l 3250 bsr.l store_dreg_l # store result to regfile 3251 bra.w foperr_exit 3251 bra.w foperr_exit 3252 3252 3253 ############################################# 3253 ######################################################################### 3254 # XDEF ************************************** 3254 # XDEF **************************************************************** # 3255 # _fpsp_snan(): 060FPSP entry point for 3255 # _fpsp_snan(): 060FPSP entry point for FP SNAN exception. # 3256 # 3256 # # 3257 # This handler should be the first code 3257 # This handler should be the first code executed upon taking the # 3258 # FP Signalling NAN exception in an ope 3258 # FP Signalling NAN exception in an operating system. # 3259 # 3259 # # 3260 # XREF ************************************** 3260 # XREF **************************************************************** # 3261 # _imem_read_long() - read instruction 3261 # _imem_read_long() - read instruction longword # 3262 # fix_skewed_ops() - adjust src operand 3262 # fix_skewed_ops() - adjust src operand in fsave frame # 3263 # _real_snan() - "callout" to operating 3263 # _real_snan() - "callout" to operating system SNAN handler # 3264 # _dmem_write_{byte,word,long}() - stor 3264 # _dmem_write_{byte,word,long}() - store data to mem (opclass 3) # 3265 # store_dreg_{b,w,l}() - store data to 3265 # store_dreg_{b,w,l}() - store data to data regfile (opclass 3) # 3266 # facc_out_{b,w,l,d,x}() - store to mem 3266 # facc_out_{b,w,l,d,x}() - store to mem took acc error (opcl 3) # 3267 # _calc_ea_fout() - fix An if <ea> is - 3267 # _calc_ea_fout() - fix An if <ea> is -() or ()+; also get <ea> # 3268 # 3268 # # 3269 # INPUT ************************************* 3269 # INPUT *************************************************************** # 3270 # - The system stack contains the FP SN 3270 # - The system stack contains the FP SNAN exception frame # 3271 # - The fsave frame contains the source 3271 # - The fsave frame contains the source operand # 3272 # 3272 # # 3273 # OUTPUT ************************************ 3273 # OUTPUT ************************************************************** # 3274 # No access error: 3274 # No access error: # 3275 # - The system stack is unchanged 3275 # - The system stack is unchanged # 3276 # - The fsave frame contains the adjust 3276 # - The fsave frame contains the adjusted src op for opclass 0,2 # 3277 # 3277 # # 3278 # ALGORITHM ********************************* 3278 # ALGORITHM *********************************************************** # 3279 # In a system where the FP SNAN excepti 3279 # In a system where the FP SNAN exception is enabled, the goal # 3280 # is to get to the handler specified at _real 3280 # is to get to the handler specified at _real_snan(). But, on the 060, # 3281 # for opclass zero and two instructions takin 3281 # for opclass zero and two instructions taking this exception, the # 3282 # input operand in the fsave frame may be inc 3282 # input operand in the fsave frame may be incorrect for some cases # 3283 # and needs to be corrected. This handler cal 3283 # and needs to be corrected. This handler calls fix_skewed_ops() to # 3284 # do just this and then exits through _real_s 3284 # do just this and then exits through _real_snan(). # 3285 # For opclass 3 instructions, the 060 d 3285 # For opclass 3 instructions, the 060 doesn't store the default # 3286 # SNAN result out to memory or data register 3286 # SNAN result out to memory or data register file as it should. # 3287 # This code must emulate the move out before 3287 # This code must emulate the move out before finally exiting through # 3288 # _real_snan(). The move out, if to memory, i 3288 # _real_snan(). The move out, if to memory, is performed using # 3289 # _mem_write() "callout" routines that may re 3289 # _mem_write() "callout" routines that may return a failing result. # 3290 # In this special case, the handler must exit 3290 # In this special case, the handler must exit through facc_out() # 3291 # which creates an access error stack frame f 3291 # which creates an access error stack frame from the current SNAN # 3292 # stack frame. 3292 # stack frame. # 3293 # For the case of an extended precision 3293 # For the case of an extended precision opclass 3 instruction, # 3294 # if the effective addressing mode was -() or 3294 # if the effective addressing mode was -() or ()+, then the address # 3295 # register must get updated by calling _calc_ 3295 # register must get updated by calling _calc_ea_fout(). If the <ea> # 3296 # was -(a7) from supervisor mode, then the ex 3296 # was -(a7) from supervisor mode, then the exception frame currently # 3297 # on the system stack must be carefully moved 3297 # on the system stack must be carefully moved "down" to make room # 3298 # for the operand being moved. 3298 # for the operand being moved. # 3299 # 3299 # # 3300 ############################################# 3300 ######################################################################### 3301 3301 3302 global _fpsp_snan 3302 global _fpsp_snan 3303 _fpsp_snan: 3303 _fpsp_snan: 3304 3304 3305 link.w %a6,&-LOCAL_SIZE 3305 link.w %a6,&-LOCAL_SIZE # init stack frame 3306 3306 3307 fsave FP_SRC(%a6) 3307 fsave FP_SRC(%a6) # grab the "busy" frame 3308 3308 3309 movm.l &0x0303,EXC_DREGS(%a6 3309 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3310 fmovm.l %fpcr,%fpsr,%fpiar,US 3310 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 3311 fmovm.x &0xc0,EXC_FPREGS(%a6) 3311 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 3312 3312 3313 # the FPIAR holds the "current PC" of the fau 3313 # the FPIAR holds the "current PC" of the faulting instruction 3314 mov.l USER_FPIAR(%a6),EXC_E 3314 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 3315 3315 3316 mov.l EXC_EXTWPTR(%a6),%a0 3316 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 3317 addq.l &0x4,EXC_EXTWPTR(%a6) 3317 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 3318 bsr.l _imem_read_long 3318 bsr.l _imem_read_long # fetch the instruction words 3319 mov.l %d0,EXC_OPWORD(%a6) 3319 mov.l %d0,EXC_OPWORD(%a6) 3320 3320 3321 ############################################# 3321 ############################################################################## 3322 3322 3323 btst &13,%d0 3323 btst &13,%d0 # is instr an fmove out? 3324 bne.w fsnan_out 3324 bne.w fsnan_out # fmove out 3325 3325 3326 3326 3327 # here, we simply see if the operand in the f 3327 # here, we simply see if the operand in the fsave frame needs to be "unskewed". 3328 # this would be the case for opclass two oper 3328 # this would be the case for opclass two operations with a source infinity or 3329 # denorm operand in the sgl or dbl format. NA 3329 # denorm operand in the sgl or dbl format. NANs also become skewed and must be 3330 # fixed here. 3330 # fixed here. 3331 lea FP_SRC(%a6),%a0 3331 lea FP_SRC(%a6),%a0 # pass: ptr to src op 3332 bsr.l fix_skewed_ops 3332 bsr.l fix_skewed_ops # fix src op 3333 3333 3334 fsnan_exit: 3334 fsnan_exit: 3335 fmovm.x EXC_FPREGS(%a6),&0xc0 3335 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 3336 fmovm.l USER_FPCR(%a6),%fpcr, 3336 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 3337 movm.l EXC_DREGS(%a6),&0x030 3337 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3338 3338 3339 frestore FP_SRC(%a6) 3339 frestore FP_SRC(%a6) 3340 3340 3341 unlk %a6 3341 unlk %a6 3342 bra.l _real_snan 3342 bra.l _real_snan 3343 3343 3344 ############################################# 3344 ######################################################################## 3345 3345 3346 # 3346 # 3347 # the hardware does not save the default resu 3347 # the hardware does not save the default result to memory on enabled 3348 # snan exceptions. we do this here before pas 3348 # snan exceptions. we do this here before passing control to 3349 # the user snan handler. 3349 # the user snan handler. 3350 # 3350 # 3351 # byte, word, long, and packed destination fo 3351 # byte, word, long, and packed destination format operations can pass 3352 # through here. since packed format operation 3352 # through here. since packed format operations already were handled by 3353 # fpsp_unsupp(), then we need to do nothing e 3353 # fpsp_unsupp(), then we need to do nothing else for them here. 3354 # for byte, word, and long, we simply need to 3354 # for byte, word, and long, we simply need to test the sign of the src 3355 # operand and save the appropriate minimum or 3355 # operand and save the appropriate minimum or maximum integer value 3356 # to the effective address as pointed to by t 3356 # to the effective address as pointed to by the stacked effective address. 3357 # 3357 # 3358 fsnan_out: 3358 fsnan_out: 3359 3359 3360 bfextu %d0{&19:&3},%d0 3360 bfextu %d0{&19:&3},%d0 # extract dst format field 3361 mov.b 1+EXC_OPWORD(%a6),%d1 3361 mov.b 1+EXC_OPWORD(%a6),%d1 # extract <ea> mode,reg 3362 mov.w (tbl_snan.b,%pc,%d0.w 3362 mov.w (tbl_snan.b,%pc,%d0.w*2),%a0 3363 jmp (tbl_snan.b,%pc,%a0) 3363 jmp (tbl_snan.b,%pc,%a0) 3364 3364 3365 tbl_snan: 3365 tbl_snan: 3366 short fsnan_out_l - tbl_sna 3366 short fsnan_out_l - tbl_snan # long word integer 3367 short fsnan_out_s - tbl_sna 3367 short fsnan_out_s - tbl_snan # sgl prec shouldn't happen 3368 short fsnan_out_x - tbl_sna 3368 short fsnan_out_x - tbl_snan # ext prec shouldn't happen 3369 short tbl_snan - tbl_sna 3369 short tbl_snan - tbl_snan # packed needs no help 3370 short fsnan_out_w - tbl_sna 3370 short fsnan_out_w - tbl_snan # word integer 3371 short fsnan_out_d - tbl_sna 3371 short fsnan_out_d - tbl_snan # dbl prec shouldn't happen 3372 short fsnan_out_b - tbl_sna 3372 short fsnan_out_b - tbl_snan # byte integer 3373 short tbl_snan - tbl_sna 3373 short tbl_snan - tbl_snan # packed needs no help 3374 3374 3375 fsnan_out_b: 3375 fsnan_out_b: 3376 mov.b FP_SRC_HI(%a6),%d0 3376 mov.b FP_SRC_HI(%a6),%d0 # load upper byte of SNAN 3377 bset &6,%d0 3377 bset &6,%d0 # set SNAN bit 3378 cmpi.b %d1,&0x7 3378 cmpi.b %d1,&0x7 # is <ea> mode a data reg? 3379 ble.b fsnan_out_b_dn 3379 ble.b fsnan_out_b_dn # yes 3380 mov.l EXC_EA(%a6),%a0 3380 mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result 3381 bsr.l _dmem_write_byte 3381 bsr.l _dmem_write_byte # write the default result 3382 3382 3383 tst.l %d1 3383 tst.l %d1 # did dstore fail? 3384 bne.l facc_out_b 3384 bne.l facc_out_b # yes 3385 3385 3386 bra.w fsnan_exit 3386 bra.w fsnan_exit 3387 fsnan_out_b_dn: 3387 fsnan_out_b_dn: 3388 andi.w &0x0007,%d1 3388 andi.w &0x0007,%d1 3389 bsr.l store_dreg_b 3389 bsr.l store_dreg_b # store result to regfile 3390 bra.w fsnan_exit 3390 bra.w fsnan_exit 3391 3391 3392 fsnan_out_w: 3392 fsnan_out_w: 3393 mov.w FP_SRC_HI(%a6),%d0 3393 mov.w FP_SRC_HI(%a6),%d0 # load upper word of SNAN 3394 bset &14,%d0 3394 bset &14,%d0 # set SNAN bit 3395 cmpi.b %d1,&0x7 3395 cmpi.b %d1,&0x7 # is <ea> mode a data reg? 3396 ble.b fsnan_out_w_dn 3396 ble.b fsnan_out_w_dn # yes 3397 mov.l EXC_EA(%a6),%a0 3397 mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result 3398 bsr.l _dmem_write_word 3398 bsr.l _dmem_write_word # write the default result 3399 3399 3400 tst.l %d1 3400 tst.l %d1 # did dstore fail? 3401 bne.l facc_out_w 3401 bne.l facc_out_w # yes 3402 3402 3403 bra.w fsnan_exit 3403 bra.w fsnan_exit 3404 fsnan_out_w_dn: 3404 fsnan_out_w_dn: 3405 andi.w &0x0007,%d1 3405 andi.w &0x0007,%d1 3406 bsr.l store_dreg_w 3406 bsr.l store_dreg_w # store result to regfile 3407 bra.w fsnan_exit 3407 bra.w fsnan_exit 3408 3408 3409 fsnan_out_l: 3409 fsnan_out_l: 3410 mov.l FP_SRC_HI(%a6),%d0 3410 mov.l FP_SRC_HI(%a6),%d0 # load upper longword of SNAN 3411 bset &30,%d0 3411 bset &30,%d0 # set SNAN bit 3412 cmpi.b %d1,&0x7 3412 cmpi.b %d1,&0x7 # is <ea> mode a data reg? 3413 ble.b fsnan_out_l_dn 3413 ble.b fsnan_out_l_dn # yes 3414 mov.l EXC_EA(%a6),%a0 3414 mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result 3415 bsr.l _dmem_write_long 3415 bsr.l _dmem_write_long # write the default result 3416 3416 3417 tst.l %d1 3417 tst.l %d1 # did dstore fail? 3418 bne.l facc_out_l 3418 bne.l facc_out_l # yes 3419 3419 3420 bra.w fsnan_exit 3420 bra.w fsnan_exit 3421 fsnan_out_l_dn: 3421 fsnan_out_l_dn: 3422 andi.w &0x0007,%d1 3422 andi.w &0x0007,%d1 3423 bsr.l store_dreg_l 3423 bsr.l store_dreg_l # store result to regfile 3424 bra.w fsnan_exit 3424 bra.w fsnan_exit 3425 3425 3426 fsnan_out_s: 3426 fsnan_out_s: 3427 cmpi.b %d1,&0x7 3427 cmpi.b %d1,&0x7 # is <ea> mode a data reg? 3428 ble.b fsnan_out_d_dn 3428 ble.b fsnan_out_d_dn # yes 3429 mov.l FP_SRC_EX(%a6),%d0 3429 mov.l FP_SRC_EX(%a6),%d0 # fetch SNAN sign 3430 andi.l &0x80000000,%d0 3430 andi.l &0x80000000,%d0 # keep sign 3431 ori.l &0x7fc00000,%d0 3431 ori.l &0x7fc00000,%d0 # insert new exponent,SNAN bit 3432 mov.l FP_SRC_HI(%a6),%d1 3432 mov.l FP_SRC_HI(%a6),%d1 # load mantissa 3433 lsr.l &0x8,%d1 3433 lsr.l &0x8,%d1 # shift mantissa for sgl 3434 or.l %d1,%d0 3434 or.l %d1,%d0 # create sgl SNAN 3435 mov.l EXC_EA(%a6),%a0 3435 mov.l EXC_EA(%a6),%a0 # pass: <ea> of default result 3436 bsr.l _dmem_write_long 3436 bsr.l _dmem_write_long # write the default result 3437 3437 3438 tst.l %d1 3438 tst.l %d1 # did dstore fail? 3439 bne.l facc_out_l 3439 bne.l facc_out_l # yes 3440 3440 3441 bra.w fsnan_exit 3441 bra.w fsnan_exit 3442 fsnan_out_d_dn: 3442 fsnan_out_d_dn: 3443 mov.l FP_SRC_EX(%a6),%d0 3443 mov.l FP_SRC_EX(%a6),%d0 # fetch SNAN sign 3444 andi.l &0x80000000,%d0 3444 andi.l &0x80000000,%d0 # keep sign 3445 ori.l &0x7fc00000,%d0 3445 ori.l &0x7fc00000,%d0 # insert new exponent,SNAN bit 3446 mov.l %d1,-(%sp) 3446 mov.l %d1,-(%sp) 3447 mov.l FP_SRC_HI(%a6),%d1 3447 mov.l FP_SRC_HI(%a6),%d1 # load mantissa 3448 lsr.l &0x8,%d1 3448 lsr.l &0x8,%d1 # shift mantissa for sgl 3449 or.l %d1,%d0 3449 or.l %d1,%d0 # create sgl SNAN 3450 mov.l (%sp)+,%d1 3450 mov.l (%sp)+,%d1 3451 andi.w &0x0007,%d1 3451 andi.w &0x0007,%d1 3452 bsr.l store_dreg_l 3452 bsr.l store_dreg_l # store result to regfile 3453 bra.w fsnan_exit 3453 bra.w fsnan_exit 3454 3454 3455 fsnan_out_d: 3455 fsnan_out_d: 3456 mov.l FP_SRC_EX(%a6),%d0 3456 mov.l FP_SRC_EX(%a6),%d0 # fetch SNAN sign 3457 andi.l &0x80000000,%d0 3457 andi.l &0x80000000,%d0 # keep sign 3458 ori.l &0x7ff80000,%d0 3458 ori.l &0x7ff80000,%d0 # insert new exponent,SNAN bit 3459 mov.l FP_SRC_HI(%a6),%d1 3459 mov.l FP_SRC_HI(%a6),%d1 # load hi mantissa 3460 mov.l %d0,FP_SCR0_EX(%a6) 3460 mov.l %d0,FP_SCR0_EX(%a6) # store to temp space 3461 mov.l &11,%d0 3461 mov.l &11,%d0 # load shift amt 3462 lsr.l %d0,%d1 3462 lsr.l %d0,%d1 3463 or.l %d1,FP_SCR0_EX(%a6) 3463 or.l %d1,FP_SCR0_EX(%a6) # create dbl hi 3464 mov.l FP_SRC_HI(%a6),%d1 3464 mov.l FP_SRC_HI(%a6),%d1 # load hi mantissa 3465 andi.l &0x000007ff,%d1 3465 andi.l &0x000007ff,%d1 3466 ror.l %d0,%d1 3466 ror.l %d0,%d1 3467 mov.l %d1,FP_SCR0_HI(%a6) 3467 mov.l %d1,FP_SCR0_HI(%a6) # store to temp space 3468 mov.l FP_SRC_LO(%a6),%d1 3468 mov.l FP_SRC_LO(%a6),%d1 # load lo mantissa 3469 lsr.l %d0,%d1 3469 lsr.l %d0,%d1 3470 or.l %d1,FP_SCR0_HI(%a6) 3470 or.l %d1,FP_SCR0_HI(%a6) # create dbl lo 3471 lea FP_SCR0(%a6),%a0 3471 lea FP_SCR0(%a6),%a0 # pass: ptr to operand 3472 mov.l EXC_EA(%a6),%a1 3472 mov.l EXC_EA(%a6),%a1 # pass: dst addr 3473 movq.l &0x8,%d0 3473 movq.l &0x8,%d0 # pass: size of 8 bytes 3474 bsr.l _dmem_write 3474 bsr.l _dmem_write # write the default result 3475 3475 3476 tst.l %d1 3476 tst.l %d1 # did dstore fail? 3477 bne.l facc_out_d 3477 bne.l facc_out_d # yes 3478 3478 3479 bra.w fsnan_exit 3479 bra.w fsnan_exit 3480 3480 3481 # for extended precision, if the addressing m 3481 # for extended precision, if the addressing mode is pre-decrement or 3482 # post-increment, then the address register d 3482 # post-increment, then the address register did not get updated. 3483 # in addition, for pre-decrement, the stacked 3483 # in addition, for pre-decrement, the stacked <ea> is incorrect. 3484 fsnan_out_x: 3484 fsnan_out_x: 3485 clr.b SPCOND_FLG(%a6) 3485 clr.b SPCOND_FLG(%a6) # clear special case flag 3486 3486 3487 mov.w FP_SRC_EX(%a6),FP_SCR 3487 mov.w FP_SRC_EX(%a6),FP_SCR0_EX(%a6) 3488 clr.w 2+FP_SCR0(%a6) 3488 clr.w 2+FP_SCR0(%a6) 3489 mov.l FP_SRC_HI(%a6),%d0 3489 mov.l FP_SRC_HI(%a6),%d0 3490 bset &30,%d0 3490 bset &30,%d0 3491 mov.l %d0,FP_SCR0_HI(%a6) 3491 mov.l %d0,FP_SCR0_HI(%a6) 3492 mov.l FP_SRC_LO(%a6),FP_SCR 3492 mov.l FP_SRC_LO(%a6),FP_SCR0_LO(%a6) 3493 3493 3494 btst &0x5,EXC_SR(%a6) 3494 btst &0x5,EXC_SR(%a6) # supervisor mode exception? 3495 bne.b fsnan_out_x_s 3495 bne.b fsnan_out_x_s # yes 3496 3496 3497 mov.l %usp,%a0 3497 mov.l %usp,%a0 # fetch user stack pointer 3498 mov.l %a0,EXC_A7(%a6) 3498 mov.l %a0,EXC_A7(%a6) # save on stack for calc_ea() 3499 mov.l (%a6),EXC_A6(%a6) 3499 mov.l (%a6),EXC_A6(%a6) 3500 3500 3501 bsr.l _calc_ea_fout 3501 bsr.l _calc_ea_fout # find the correct ea,update An 3502 mov.l %a0,%a1 3502 mov.l %a0,%a1 3503 mov.l %a0,EXC_EA(%a6) 3503 mov.l %a0,EXC_EA(%a6) # stack correct <ea> 3504 3504 3505 mov.l EXC_A7(%a6),%a0 3505 mov.l EXC_A7(%a6),%a0 3506 mov.l %a0,%usp 3506 mov.l %a0,%usp # restore user stack pointer 3507 mov.l EXC_A6(%a6),(%a6) 3507 mov.l EXC_A6(%a6),(%a6) 3508 3508 3509 fsnan_out_x_save: 3509 fsnan_out_x_save: 3510 lea FP_SCR0(%a6),%a0 3510 lea FP_SCR0(%a6),%a0 # pass: ptr to operand 3511 movq.l &0xc,%d0 3511 movq.l &0xc,%d0 # pass: size of extended 3512 bsr.l _dmem_write 3512 bsr.l _dmem_write # write the default result 3513 3513 3514 tst.l %d1 3514 tst.l %d1 # did dstore fail? 3515 bne.l facc_out_x 3515 bne.l facc_out_x # yes 3516 3516 3517 bra.w fsnan_exit 3517 bra.w fsnan_exit 3518 3518 3519 fsnan_out_x_s: 3519 fsnan_out_x_s: 3520 mov.l (%a6),EXC_A6(%a6) 3520 mov.l (%a6),EXC_A6(%a6) 3521 3521 3522 bsr.l _calc_ea_fout 3522 bsr.l _calc_ea_fout # find the correct ea,update An 3523 mov.l %a0,%a1 3523 mov.l %a0,%a1 3524 mov.l %a0,EXC_EA(%a6) 3524 mov.l %a0,EXC_EA(%a6) # stack correct <ea> 3525 3525 3526 mov.l EXC_A6(%a6),(%a6) 3526 mov.l EXC_A6(%a6),(%a6) 3527 3527 3528 cmpi.b SPCOND_FLG(%a6),&mda7 3528 cmpi.b SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)? 3529 bne.b fsnan_out_x_save 3529 bne.b fsnan_out_x_save # no 3530 3530 3531 # the operation was "fmove.x SNAN,-(a7)" from 3531 # the operation was "fmove.x SNAN,-(a7)" from supervisor mode. 3532 fmovm.x EXC_FPREGS(%a6),&0xc0 3532 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 3533 fmovm.l USER_FPCR(%a6),%fpcr, 3533 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 3534 movm.l EXC_DREGS(%a6),&0x030 3534 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3535 3535 3536 frestore FP_SRC(%a6) 3536 frestore FP_SRC(%a6) 3537 3537 3538 mov.l EXC_A6(%a6),%a6 3538 mov.l EXC_A6(%a6),%a6 # restore frame pointer 3539 3539 3540 mov.l LOCAL_SIZE+EXC_SR(%sp 3540 mov.l LOCAL_SIZE+EXC_SR(%sp),LOCAL_SIZE+EXC_SR-0xc(%sp) 3541 mov.l LOCAL_SIZE+EXC_PC+0x2 3541 mov.l LOCAL_SIZE+EXC_PC+0x2(%sp),LOCAL_SIZE+EXC_PC+0x2-0xc(%sp) 3542 mov.l LOCAL_SIZE+EXC_EA(%sp 3542 mov.l LOCAL_SIZE+EXC_EA(%sp),LOCAL_SIZE+EXC_EA-0xc(%sp) 3543 3543 3544 mov.l LOCAL_SIZE+FP_SCR0_EX 3544 mov.l LOCAL_SIZE+FP_SCR0_EX(%sp),LOCAL_SIZE+EXC_SR(%sp) 3545 mov.l LOCAL_SIZE+FP_SCR0_HI 3545 mov.l LOCAL_SIZE+FP_SCR0_HI(%sp),LOCAL_SIZE+EXC_PC+0x2(%sp) 3546 mov.l LOCAL_SIZE+FP_SCR0_LO 3546 mov.l LOCAL_SIZE+FP_SCR0_LO(%sp),LOCAL_SIZE+EXC_EA(%sp) 3547 3547 3548 add.l &LOCAL_SIZE-0x8,%sp 3548 add.l &LOCAL_SIZE-0x8,%sp 3549 3549 3550 bra.l _real_snan 3550 bra.l _real_snan 3551 3551 3552 ############################################# 3552 ######################################################################### 3553 # XDEF ************************************** 3553 # XDEF **************************************************************** # 3554 # _fpsp_inex(): 060FPSP entry point for 3554 # _fpsp_inex(): 060FPSP entry point for FP Inexact exception. # 3555 # 3555 # # 3556 # This handler should be the first code 3556 # This handler should be the first code executed upon taking the # 3557 # FP Inexact exception in an operating 3557 # FP Inexact exception in an operating system. # 3558 # 3558 # # 3559 # XREF ************************************** 3559 # XREF **************************************************************** # 3560 # _imem_read_long() - read instruction 3560 # _imem_read_long() - read instruction longword # 3561 # fix_skewed_ops() - adjust src operand 3561 # fix_skewed_ops() - adjust src operand in fsave frame # 3562 # set_tag_x() - determine optype of src 3562 # set_tag_x() - determine optype of src/dst operands # 3563 # store_fpreg() - store opclass 0 or 2 3563 # store_fpreg() - store opclass 0 or 2 result to FP regfile # 3564 # unnorm_fix() - change UNNORM operands 3564 # unnorm_fix() - change UNNORM operands to NORM or ZERO # 3565 # load_fpn2() - load dst operand from F 3565 # load_fpn2() - load dst operand from FP regfile # 3566 # smovcr() - emulate an "fmovcr" instru 3566 # smovcr() - emulate an "fmovcr" instruction # 3567 # fout() - emulate an opclass 3 instruc 3567 # fout() - emulate an opclass 3 instruction # 3568 # tbl_unsupp - add of table of emulatio 3568 # tbl_unsupp - add of table of emulation routines for opclass 0,2 # 3569 # _real_inex() - "callout" to operating 3569 # _real_inex() - "callout" to operating system inexact handler # 3570 # 3570 # # 3571 # INPUT ************************************* 3571 # INPUT *************************************************************** # 3572 # - The system stack contains the FP In 3572 # - The system stack contains the FP Inexact exception frame # 3573 # - The fsave frame contains the source 3573 # - The fsave frame contains the source operand # 3574 # 3574 # # 3575 # OUTPUT ************************************ 3575 # OUTPUT ************************************************************** # 3576 # - The system stack is unchanged 3576 # - The system stack is unchanged # 3577 # - The fsave frame contains the adjust 3577 # - The fsave frame contains the adjusted src op for opclass 0,2 # 3578 # 3578 # # 3579 # ALGORITHM ********************************* 3579 # ALGORITHM *********************************************************** # 3580 # In a system where the FP Inexact exce 3580 # In a system where the FP Inexact exception is enabled, the goal # 3581 # is to get to the handler specified at _real 3581 # is to get to the handler specified at _real_inex(). But, on the 060, # 3582 # for opclass zero and two instruction taking 3582 # for opclass zero and two instruction taking this exception, the # 3583 # hardware doesn't store the correct result t 3583 # hardware doesn't store the correct result to the destination FP # 3584 # register as did the '040 and '881/2. This h 3584 # register as did the '040 and '881/2. This handler must emulate the # 3585 # instruction in order to get this value and 3585 # instruction in order to get this value and then store it to the # 3586 # correct register before calling _real_inex( 3586 # correct register before calling _real_inex(). # 3587 # For opclass 3 instructions, the 060 d 3587 # For opclass 3 instructions, the 060 doesn't store the default # 3588 # inexact result out to memory or data regist 3588 # inexact result out to memory or data register file as it should. # 3589 # This code must emulate the move out by call 3589 # This code must emulate the move out by calling fout() before finally # 3590 # exiting through _real_inex(). 3590 # exiting through _real_inex(). # 3591 # 3591 # # 3592 ############################################# 3592 ######################################################################### 3593 3593 3594 global _fpsp_inex 3594 global _fpsp_inex 3595 _fpsp_inex: 3595 _fpsp_inex: 3596 3596 3597 link.w %a6,&-LOCAL_SIZE 3597 link.w %a6,&-LOCAL_SIZE # init stack frame 3598 3598 3599 fsave FP_SRC(%a6) 3599 fsave FP_SRC(%a6) # grab the "busy" frame 3600 3600 3601 movm.l &0x0303,EXC_DREGS(%a6 3601 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3602 fmovm.l %fpcr,%fpsr,%fpiar,US 3602 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 3603 fmovm.x &0xc0,EXC_FPREGS(%a6) 3603 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 3604 3604 3605 # the FPIAR holds the "current PC" of the fau 3605 # the FPIAR holds the "current PC" of the faulting instruction 3606 mov.l USER_FPIAR(%a6),EXC_E 3606 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 3607 3607 3608 mov.l EXC_EXTWPTR(%a6),%a0 3608 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 3609 addq.l &0x4,EXC_EXTWPTR(%a6) 3609 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 3610 bsr.l _imem_read_long 3610 bsr.l _imem_read_long # fetch the instruction words 3611 mov.l %d0,EXC_OPWORD(%a6) 3611 mov.l %d0,EXC_OPWORD(%a6) 3612 3612 3613 ############################################# 3613 ############################################################################## 3614 3614 3615 btst &13,%d0 3615 btst &13,%d0 # is instr an fmove out? 3616 bne.w finex_out 3616 bne.w finex_out # fmove out 3617 3617 3618 3618 3619 # the hardware, for "fabs" and "fneg" w/ a lo 3619 # the hardware, for "fabs" and "fneg" w/ a long source format, puts the 3620 # longword integer directly into the upper lo 3620 # longword integer directly into the upper longword of the mantissa along 3621 # w/ an exponent value of 0x401e. we convert 3621 # w/ an exponent value of 0x401e. we convert this to extended precision here. 3622 bfextu %d0{&19:&3},%d0 3622 bfextu %d0{&19:&3},%d0 # fetch instr size 3623 bne.b finex_cont 3623 bne.b finex_cont # instr size is not long 3624 cmpi.w FP_SRC_EX(%a6),&0x401 3624 cmpi.w FP_SRC_EX(%a6),&0x401e # is exponent 0x401e? 3625 bne.b finex_cont 3625 bne.b finex_cont # no 3626 fmov.l &0x0,%fpcr 3626 fmov.l &0x0,%fpcr 3627 fmov.l FP_SRC_HI(%a6),%fp0 3627 fmov.l FP_SRC_HI(%a6),%fp0 # load integer src 3628 fmov.x %fp0,FP_SRC(%a6) 3628 fmov.x %fp0,FP_SRC(%a6) # store integer as extended precision 3629 mov.w &0xe001,0x2+FP_SRC(%a 3629 mov.w &0xe001,0x2+FP_SRC(%a6) 3630 3630 3631 finex_cont: 3631 finex_cont: 3632 lea FP_SRC(%a6),%a0 3632 lea FP_SRC(%a6),%a0 # pass: ptr to src op 3633 bsr.l fix_skewed_ops 3633 bsr.l fix_skewed_ops # fix src op 3634 3634 3635 # Here, we zero the ccode and exception byte 3635 # Here, we zero the ccode and exception byte field since we're going to 3636 # emulate the whole instruction. Notice, thou 3636 # emulate the whole instruction. Notice, though, that we don't kill the 3637 # INEX1 bit. This is because a packed op has 3637 # INEX1 bit. This is because a packed op has long since been converted 3638 # to extended before arriving here. Therefore 3638 # to extended before arriving here. Therefore, we need to retain the 3639 # INEX1 bit from when the operand was first c 3639 # INEX1 bit from when the operand was first converted. 3640 andi.l &0x00ff01ff,USER_FPSR 3640 andi.l &0x00ff01ff,USER_FPSR(%a6) # zero all but accured field 3641 3641 3642 fmov.l &0x0,%fpcr 3642 fmov.l &0x0,%fpcr # zero current control regs 3643 fmov.l &0x0,%fpsr 3643 fmov.l &0x0,%fpsr 3644 3644 3645 bfextu EXC_EXTWORD(%a6){&0:& 3645 bfextu EXC_EXTWORD(%a6){&0:&6},%d1 # extract upper 6 of cmdreg 3646 cmpi.b %d1,&0x17 3646 cmpi.b %d1,&0x17 # is op an fmovecr? 3647 beq.w finex_fmovcr 3647 beq.w finex_fmovcr # yes 3648 3648 3649 lea FP_SRC(%a6),%a0 3649 lea FP_SRC(%a6),%a0 # pass: ptr to src op 3650 bsr.l set_tag_x 3650 bsr.l set_tag_x # tag the operand type 3651 mov.b %d0,STAG(%a6) 3651 mov.b %d0,STAG(%a6) # maybe NORM,DENORM 3652 3652 3653 # bits four and five of the fp extension word 3653 # bits four and five of the fp extension word separate the monadic and dyadic 3654 # operations that can pass through fpsp_inex( 3654 # operations that can pass through fpsp_inex(). remember that fcmp and ftst 3655 # will never take this exception, but fsincos 3655 # will never take this exception, but fsincos will. 3656 btst &0x5,1+EXC_CMDREG(%a6 3656 btst &0x5,1+EXC_CMDREG(%a6) # is operation monadic or dyadic? 3657 beq.b finex_extract 3657 beq.b finex_extract # monadic 3658 3658 3659 btst &0x4,1+EXC_CMDREG(%a6 3659 btst &0x4,1+EXC_CMDREG(%a6) # is operation an fsincos? 3660 bne.b finex_extract 3660 bne.b finex_extract # yes 3661 3661 3662 bfextu EXC_CMDREG(%a6){&6:&3 3662 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # dyadic; load dst reg 3663 bsr.l load_fpn2 3663 bsr.l load_fpn2 # load dst into FP_DST 3664 3664 3665 lea FP_DST(%a6),%a0 3665 lea FP_DST(%a6),%a0 # pass: ptr to dst op 3666 bsr.l set_tag_x 3666 bsr.l set_tag_x # tag the operand type 3667 cmpi.b %d0,&UNNORM 3667 cmpi.b %d0,&UNNORM # is operand an UNNORM? 3668 bne.b finex_op2_done 3668 bne.b finex_op2_done # no 3669 bsr.l unnorm_fix 3669 bsr.l unnorm_fix # yes; convert to NORM,DENORM,or ZERO 3670 finex_op2_done: 3670 finex_op2_done: 3671 mov.b %d0,DTAG(%a6) 3671 mov.b %d0,DTAG(%a6) # save dst optype tag 3672 3672 3673 finex_extract: 3673 finex_extract: 3674 clr.l %d0 3674 clr.l %d0 3675 mov.b FPCR_MODE(%a6),%d0 3675 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec/mode 3676 3676 3677 mov.b 1+EXC_CMDREG(%a6),%d1 3677 mov.b 1+EXC_CMDREG(%a6),%d1 3678 andi.w &0x007f,%d1 3678 andi.w &0x007f,%d1 # extract extension 3679 3679 3680 lea FP_SRC(%a6),%a0 3680 lea FP_SRC(%a6),%a0 3681 lea FP_DST(%a6),%a1 3681 lea FP_DST(%a6),%a1 3682 3682 3683 mov.l (tbl_unsupp.l,%pc,%d1 3683 mov.l (tbl_unsupp.l,%pc,%d1.w*4),%d1 # fetch routine addr 3684 jsr (tbl_unsupp.l,%pc,%d1 3684 jsr (tbl_unsupp.l,%pc,%d1.l*1) 3685 3685 3686 # the operation has been emulated. the result 3686 # the operation has been emulated. the result is in fp0. 3687 finex_save: 3687 finex_save: 3688 bfextu EXC_CMDREG(%a6){&6:&3 3688 bfextu EXC_CMDREG(%a6){&6:&3},%d0 3689 bsr.l store_fpreg 3689 bsr.l store_fpreg 3690 3690 3691 finex_exit: 3691 finex_exit: 3692 fmovm.x EXC_FPREGS(%a6),&0xc0 3692 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 3693 fmovm.l USER_FPCR(%a6),%fpcr, 3693 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 3694 movm.l EXC_DREGS(%a6),&0x030 3694 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3695 3695 3696 frestore FP_SRC(%a6) 3696 frestore FP_SRC(%a6) 3697 3697 3698 unlk %a6 3698 unlk %a6 3699 bra.l _real_inex 3699 bra.l _real_inex 3700 3700 3701 finex_fmovcr: 3701 finex_fmovcr: 3702 clr.l %d0 3702 clr.l %d0 3703 mov.b FPCR_MODE(%a6),%d0 3703 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec,mode 3704 mov.b 1+EXC_CMDREG(%a6),%d1 3704 mov.b 1+EXC_CMDREG(%a6),%d1 3705 andi.l &0x0000007f,%d1 3705 andi.l &0x0000007f,%d1 # pass rom offset 3706 bsr.l smovcr 3706 bsr.l smovcr 3707 bra.b finex_save 3707 bra.b finex_save 3708 3708 3709 ############################################# 3709 ######################################################################## 3710 3710 3711 # 3711 # 3712 # the hardware does not save the default resu 3712 # the hardware does not save the default result to memory on enabled 3713 # inexact exceptions. we do this here before 3713 # inexact exceptions. we do this here before passing control to 3714 # the user inexact handler. 3714 # the user inexact handler. 3715 # 3715 # 3716 # byte, word, and long destination format ope 3716 # byte, word, and long destination format operations can pass 3717 # through here. so can double and single prec 3717 # through here. so can double and single precision. 3718 # although packed opclass three operations ca 3718 # although packed opclass three operations can take inexact 3719 # exceptions, they won't pass through here si 3719 # exceptions, they won't pass through here since they are caught 3720 # first by the unsupported data format except 3720 # first by the unsupported data format exception handler. that handler 3721 # sends them directly to _real_inex() if nece 3721 # sends them directly to _real_inex() if necessary. 3722 # 3722 # 3723 finex_out: 3723 finex_out: 3724 3724 3725 mov.b &NORM,STAG(%a6) 3725 mov.b &NORM,STAG(%a6) # src is a NORM 3726 3726 3727 clr.l %d0 3727 clr.l %d0 3728 mov.b FPCR_MODE(%a6),%d0 3728 mov.b FPCR_MODE(%a6),%d0 # pass rnd prec,mode 3729 3729 3730 andi.l &0xffff00ff,USER_FPSR 3730 andi.l &0xffff00ff,USER_FPSR(%a6) # zero exception field 3731 3731 3732 lea FP_SRC(%a6),%a0 3732 lea FP_SRC(%a6),%a0 # pass ptr to src operand 3733 3733 3734 bsr.l fout 3734 bsr.l fout # store the default result 3735 3735 3736 bra.b finex_exit 3736 bra.b finex_exit 3737 3737 3738 ############################################# 3738 ######################################################################### 3739 # XDEF ************************************** 3739 # XDEF **************************************************************** # 3740 # _fpsp_dz(): 060FPSP entry point for F 3740 # _fpsp_dz(): 060FPSP entry point for FP DZ exception. # 3741 # 3741 # # 3742 # This handler should be the first code 3742 # This handler should be the first code executed upon taking # 3743 # the FP DZ exception in an operating s 3743 # the FP DZ exception in an operating system. # 3744 # 3744 # # 3745 # XREF ************************************** 3745 # XREF **************************************************************** # 3746 # _imem_read_long() - read instruction 3746 # _imem_read_long() - read instruction longword from memory # 3747 # fix_skewed_ops() - adjust fsave opera 3747 # fix_skewed_ops() - adjust fsave operand # 3748 # _real_dz() - "callout" exit point fro 3748 # _real_dz() - "callout" exit point from FP DZ handler # 3749 # 3749 # # 3750 # INPUT ************************************* 3750 # INPUT *************************************************************** # 3751 # - The system stack contains the FP DZ 3751 # - The system stack contains the FP DZ exception stack. # 3752 # - The fsave frame contains the source 3752 # - The fsave frame contains the source operand. # 3753 # 3753 # # 3754 # OUTPUT ************************************ 3754 # OUTPUT ************************************************************** # 3755 # - The system stack contains the FP DZ 3755 # - The system stack contains the FP DZ exception stack. # 3756 # - The fsave frame contains the adjust 3756 # - The fsave frame contains the adjusted source operand. # 3757 # 3757 # # 3758 # ALGORITHM ********************************* 3758 # ALGORITHM *********************************************************** # 3759 # In a system where the DZ exception is 3759 # In a system where the DZ exception is enabled, the goal is to # 3760 # get to the handler specified at _real_dz(). 3760 # get to the handler specified at _real_dz(). But, on the 060, when the # 3761 # exception is taken, the input operand in th 3761 # exception is taken, the input operand in the fsave state frame may # 3762 # be incorrect for some cases and need to be 3762 # be incorrect for some cases and need to be adjusted. So, this package # 3763 # adjusts the operand using fix_skewed_ops() 3763 # adjusts the operand using fix_skewed_ops() and then branches to # 3764 # _real_dz(). 3764 # _real_dz(). # 3765 # 3765 # # 3766 ############################################# 3766 ######################################################################### 3767 3767 3768 global _fpsp_dz 3768 global _fpsp_dz 3769 _fpsp_dz: 3769 _fpsp_dz: 3770 3770 3771 link.w %a6,&-LOCAL_SIZE 3771 link.w %a6,&-LOCAL_SIZE # init stack frame 3772 3772 3773 fsave FP_SRC(%a6) 3773 fsave FP_SRC(%a6) # grab the "busy" frame 3774 3774 3775 movm.l &0x0303,EXC_DREGS(%a6 3775 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3776 fmovm.l %fpcr,%fpsr,%fpiar,US 3776 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 3777 fmovm.x &0xc0,EXC_FPREGS(%a6) 3777 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 on stack 3778 3778 3779 # the FPIAR holds the "current PC" of the fau 3779 # the FPIAR holds the "current PC" of the faulting instruction 3780 mov.l USER_FPIAR(%a6),EXC_E 3780 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 3781 3781 3782 mov.l EXC_EXTWPTR(%a6),%a0 3782 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 3783 addq.l &0x4,EXC_EXTWPTR(%a6) 3783 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 3784 bsr.l _imem_read_long 3784 bsr.l _imem_read_long # fetch the instruction words 3785 mov.l %d0,EXC_OPWORD(%a6) 3785 mov.l %d0,EXC_OPWORD(%a6) 3786 3786 3787 ############################################# 3787 ############################################################################## 3788 3788 3789 3789 3790 # here, we simply see if the operand in the f 3790 # here, we simply see if the operand in the fsave frame needs to be "unskewed". 3791 # this would be the case for opclass two oper 3791 # this would be the case for opclass two operations with a source zero 3792 # in the sgl or dbl format. 3792 # in the sgl or dbl format. 3793 lea FP_SRC(%a6),%a0 3793 lea FP_SRC(%a6),%a0 # pass: ptr to src op 3794 bsr.l fix_skewed_ops 3794 bsr.l fix_skewed_ops # fix src op 3795 3795 3796 fdz_exit: 3796 fdz_exit: 3797 fmovm.x EXC_FPREGS(%a6),&0xc0 3797 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 3798 fmovm.l USER_FPCR(%a6),%fpcr, 3798 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 3799 movm.l EXC_DREGS(%a6),&0x030 3799 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3800 3800 3801 frestore FP_SRC(%a6) 3801 frestore FP_SRC(%a6) 3802 3802 3803 unlk %a6 3803 unlk %a6 3804 bra.l _real_dz 3804 bra.l _real_dz 3805 3805 3806 ############################################# 3806 ######################################################################### 3807 # XDEF ************************************** 3807 # XDEF **************************************************************** # 3808 # _fpsp_fline(): 060FPSP entry point fo 3808 # _fpsp_fline(): 060FPSP entry point for "Line F emulator" exc. # 3809 # 3809 # # 3810 # This handler should be the first code 3810 # This handler should be the first code executed upon taking the # 3811 # "Line F Emulator" exception in an ope 3811 # "Line F Emulator" exception in an operating system. # 3812 # 3812 # # 3813 # XREF ************************************** 3813 # XREF **************************************************************** # 3814 # _fpsp_unimp() - handle "FP Unimplemen 3814 # _fpsp_unimp() - handle "FP Unimplemented" exceptions # 3815 # _real_fpu_disabled() - handle "FPU di 3815 # _real_fpu_disabled() - handle "FPU disabled" exceptions # 3816 # _real_fline() - handle "FLINE" except 3816 # _real_fline() - handle "FLINE" exceptions # 3817 # _imem_read_long() - read instruction 3817 # _imem_read_long() - read instruction longword # 3818 # 3818 # # 3819 # INPUT ************************************* 3819 # INPUT *************************************************************** # 3820 # - The system stack contains a "Line F 3820 # - The system stack contains a "Line F Emulator" exception # 3821 # stack frame. 3821 # stack frame. # 3822 # 3822 # # 3823 # OUTPUT ************************************ 3823 # OUTPUT ************************************************************** # 3824 # - The system stack is unchanged 3824 # - The system stack is unchanged # 3825 # 3825 # # 3826 # ALGORITHM ********************************* 3826 # ALGORITHM *********************************************************** # 3827 # When a "Line F Emulator" exception oc 3827 # When a "Line F Emulator" exception occurs, there are 3 possible # 3828 # exception types, denoted by the exception s 3828 # exception types, denoted by the exception stack frame format number: # 3829 # (1) FPU unimplemented instruction (6 3829 # (1) FPU unimplemented instruction (6 word stack frame) # 3830 # (2) FPU disabled (8 word stack frame) 3830 # (2) FPU disabled (8 word stack frame) # 3831 # (3) Line F (4 word stack frame) 3831 # (3) Line F (4 word stack frame) # 3832 # 3832 # # 3833 # This module determines which and fork 3833 # This module determines which and forks the flow off to the # 3834 # appropriate "callout" (for "disabled" and " 3834 # appropriate "callout" (for "disabled" and "Line F") or to the # 3835 # correct emulation code (for "FPU unimplemen 3835 # correct emulation code (for "FPU unimplemented"). # 3836 # This code also must check for "fmovec 3836 # This code also must check for "fmovecr" instructions w/ a # 3837 # non-zero <ea> field. These may get flagged 3837 # non-zero <ea> field. These may get flagged as "Line F" but should # 3838 # really be flagged as "FPU Unimplemented". ( 3838 # really be flagged as "FPU Unimplemented". (This is a "feature" on # 3839 # the '060. 3839 # the '060. # 3840 # 3840 # # 3841 ############################################# 3841 ######################################################################### 3842 3842 3843 global _fpsp_fline 3843 global _fpsp_fline 3844 _fpsp_fline: 3844 _fpsp_fline: 3845 3845 3846 # check to see if this exception is a "FP Uni 3846 # check to see if this exception is a "FP Unimplemented Instruction" 3847 # exception. if so, branch directly to that h 3847 # exception. if so, branch directly to that handler's entry point. 3848 cmpi.w 0x6(%sp),&0x202c 3848 cmpi.w 0x6(%sp),&0x202c 3849 beq.l _fpsp_unimp 3849 beq.l _fpsp_unimp 3850 3850 3851 # check to see if the FPU is disabled. if so, 3851 # check to see if the FPU is disabled. if so, jump to the OS entry 3852 # point for that condition. 3852 # point for that condition. 3853 cmpi.w 0x6(%sp),&0x402c 3853 cmpi.w 0x6(%sp),&0x402c 3854 beq.l _real_fpu_disabled 3854 beq.l _real_fpu_disabled 3855 3855 3856 # the exception was an "F-Line Illegal" excep 3856 # the exception was an "F-Line Illegal" exception. we check to see 3857 # if the F-Line instruction is an "fmovecr" w 3857 # if the F-Line instruction is an "fmovecr" w/ a non-zero <ea>. if 3858 # so, convert the F-Line exception stack fram 3858 # so, convert the F-Line exception stack frame to an FP Unimplemented 3859 # Instruction exception stack frame else bran 3859 # Instruction exception stack frame else branch to the OS entry 3860 # point for the F-Line exception handler. 3860 # point for the F-Line exception handler. 3861 link.w %a6,&-LOCAL_SIZE 3861 link.w %a6,&-LOCAL_SIZE # init stack frame 3862 3862 3863 movm.l &0x0303,EXC_DREGS(%a6 3863 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 3864 3864 3865 mov.l EXC_PC(%a6),EXC_EXTWP 3865 mov.l EXC_PC(%a6),EXC_EXTWPTR(%a6) 3866 mov.l EXC_EXTWPTR(%a6),%a0 3866 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 3867 addq.l &0x4,EXC_EXTWPTR(%a6) 3867 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 3868 bsr.l _imem_read_long 3868 bsr.l _imem_read_long # fetch instruction words 3869 3869 3870 bfextu %d0{&0:&10},%d1 3870 bfextu %d0{&0:&10},%d1 # is it an fmovecr? 3871 cmpi.w %d1,&0x03c8 3871 cmpi.w %d1,&0x03c8 3872 bne.b fline_fline 3872 bne.b fline_fline # no 3873 3873 3874 bfextu %d0{&16:&6},%d1 3874 bfextu %d0{&16:&6},%d1 # is it an fmovecr? 3875 cmpi.b %d1,&0x17 3875 cmpi.b %d1,&0x17 3876 bne.b fline_fline 3876 bne.b fline_fline # no 3877 3877 3878 # it's an fmovecr w/ a non-zero <ea> that has 3878 # it's an fmovecr w/ a non-zero <ea> that has entered through 3879 # the F-Line Illegal exception. 3879 # the F-Line Illegal exception. 3880 # so, we need to convert the F-Line exception 3880 # so, we need to convert the F-Line exception stack frame into an 3881 # FP Unimplemented Instruction stack frame an 3881 # FP Unimplemented Instruction stack frame and jump to that entry 3882 # point. 3882 # point. 3883 # 3883 # 3884 # but, if the FPU is disabled, then we need t 3884 # but, if the FPU is disabled, then we need to jump to the FPU disabled 3885 # entry point. 3885 # entry point. 3886 movc %pcr,%d0 3886 movc %pcr,%d0 3887 btst &0x1,%d0 3887 btst &0x1,%d0 3888 beq.b fline_fmovcr 3888 beq.b fline_fmovcr 3889 3889 3890 movm.l EXC_DREGS(%a6),&0x030 3890 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3891 3891 3892 unlk %a6 3892 unlk %a6 3893 3893 3894 sub.l &0x8,%sp 3894 sub.l &0x8,%sp # make room for "Next PC", <ea> 3895 mov.w 0x8(%sp),(%sp) 3895 mov.w 0x8(%sp),(%sp) 3896 mov.l 0xa(%sp),0x2(%sp) 3896 mov.l 0xa(%sp),0x2(%sp) # move "Current PC" 3897 mov.w &0x402c,0x6(%sp) 3897 mov.w &0x402c,0x6(%sp) 3898 mov.l 0x2(%sp),0xc(%sp) 3898 mov.l 0x2(%sp),0xc(%sp) 3899 addq.l &0x4,0x2(%sp) 3899 addq.l &0x4,0x2(%sp) # set "Next PC" 3900 3900 3901 bra.l _real_fpu_disabled 3901 bra.l _real_fpu_disabled 3902 3902 3903 fline_fmovcr: 3903 fline_fmovcr: 3904 movm.l EXC_DREGS(%a6),&0x030 3904 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3905 3905 3906 unlk %a6 3906 unlk %a6 3907 3907 3908 fmov.l 0x2(%sp),%fpiar 3908 fmov.l 0x2(%sp),%fpiar # set current PC 3909 addq.l &0x4,0x2(%sp) 3909 addq.l &0x4,0x2(%sp) # set Next PC 3910 3910 3911 mov.l (%sp),-(%sp) 3911 mov.l (%sp),-(%sp) 3912 mov.l 0x8(%sp),0x4(%sp) 3912 mov.l 0x8(%sp),0x4(%sp) 3913 mov.b &0x20,0x6(%sp) 3913 mov.b &0x20,0x6(%sp) 3914 3914 3915 bra.l _fpsp_unimp 3915 bra.l _fpsp_unimp 3916 3916 3917 fline_fline: 3917 fline_fline: 3918 movm.l EXC_DREGS(%a6),&0x030 3918 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 3919 3919 3920 unlk %a6 3920 unlk %a6 3921 3921 3922 bra.l _real_fline 3922 bra.l _real_fline 3923 3923 3924 ############################################# 3924 ######################################################################### 3925 # XDEF ************************************** 3925 # XDEF **************************************************************** # 3926 # _fpsp_unimp(): 060FPSP entry point fo 3926 # _fpsp_unimp(): 060FPSP entry point for FP "Unimplemented # 3927 # Instruction" exception 3927 # Instruction" exception. # 3928 # 3928 # # 3929 # This handler should be the first code 3929 # This handler should be the first code executed upon taking the # 3930 # FP Unimplemented Instruction exceptio 3930 # FP Unimplemented Instruction exception in an operating system. # 3931 # 3931 # # 3932 # XREF ************************************** 3932 # XREF **************************************************************** # 3933 # _imem_read_{word,long}() - read instr 3933 # _imem_read_{word,long}() - read instruction word/longword # 3934 # load_fop() - load src/dst ops from me 3934 # load_fop() - load src/dst ops from memory and/or FP regfile # 3935 # store_fpreg() - store opclass 0 or 2 3935 # store_fpreg() - store opclass 0 or 2 result to FP regfile # 3936 # tbl_trans - addr of table of emulatio 3936 # tbl_trans - addr of table of emulation routines for trnscndls # 3937 # _real_access() - "callout" for access 3937 # _real_access() - "callout" for access error exception # 3938 # _fpsp_done() - "callout" for exit; wo 3938 # _fpsp_done() - "callout" for exit; work all done # 3939 # _real_trace() - "callout" for Trace e 3939 # _real_trace() - "callout" for Trace enabled exception # 3940 # smovcr() - emulate "fmovecr" instruct 3940 # smovcr() - emulate "fmovecr" instruction # 3941 # funimp_skew() - adjust fsave src ops 3941 # funimp_skew() - adjust fsave src ops to "incorrect" value # 3942 # _ftrapcc() - emulate an "ftrapcc" ins 3942 # _ftrapcc() - emulate an "ftrapcc" instruction # 3943 # _fdbcc() - emulate an "fdbcc" instruc 3943 # _fdbcc() - emulate an "fdbcc" instruction # 3944 # _fscc() - emulate an "fscc" instructi 3944 # _fscc() - emulate an "fscc" instruction # 3945 # _real_trap() - "callout" for Trap exc 3945 # _real_trap() - "callout" for Trap exception # 3946 # _real_bsun() - "callout" for enabled 3946 # _real_bsun() - "callout" for enabled Bsun exception # 3947 # 3947 # # 3948 # INPUT ************************************* 3948 # INPUT *************************************************************** # 3949 # - The system stack contains the "Unim 3949 # - The system stack contains the "Unimplemented Instr" stk frame # 3950 # 3950 # # 3951 # OUTPUT ************************************ 3951 # OUTPUT ************************************************************** # 3952 # If access error: 3952 # If access error: # 3953 # - The system stack is changed to an a 3953 # - The system stack is changed to an access error stack frame # 3954 # If Trace exception enabled: 3954 # If Trace exception enabled: # 3955 # - The system stack is changed to a Tr 3955 # - The system stack is changed to a Trace exception stack frame # 3956 # Else: (normal case) 3956 # Else: (normal case) # 3957 # - Correct result has been stored as a 3957 # - Correct result has been stored as appropriate # 3958 # 3958 # # 3959 # ALGORITHM ********************************* 3959 # ALGORITHM *********************************************************** # 3960 # There are two main cases of instructi 3960 # There are two main cases of instructions that may enter here to # 3961 # be emulated: (1) the FPgen instructions, mo 3961 # be emulated: (1) the FPgen instructions, most of which were also # 3962 # unimplemented on the 040, and (2) "ftrapcc" 3962 # unimplemented on the 040, and (2) "ftrapcc", "fscc", and "fdbcc". # 3963 # For the first set, this handler calls 3963 # For the first set, this handler calls the routine load_fop() # 3964 # to load the source and destination (for dya 3964 # to load the source and destination (for dyadic) operands to be used # 3965 # for instruction emulation. The correct emul 3965 # for instruction emulation. The correct emulation routine is then # 3966 # chosen by decoding the instruction type and 3966 # chosen by decoding the instruction type and indexing into an # 3967 # emulation subroutine index table. After emu 3967 # emulation subroutine index table. After emulation returns, this # 3968 # handler checks to see if an exception shoul 3968 # handler checks to see if an exception should occur as a result of the # 3969 # FP instruction emulation. If so, then an FP 3969 # FP instruction emulation. If so, then an FP exception of the correct # 3970 # type is inserted into the FPU state frame u 3970 # type is inserted into the FPU state frame using the "frestore" # 3971 # instruction before exiting through _fpsp_do 3971 # instruction before exiting through _fpsp_done(). In either the # 3972 # exceptional or non-exceptional cases, we mu 3972 # exceptional or non-exceptional cases, we must check to see if the # 3973 # Trace exception is enabled. If so, then we 3973 # Trace exception is enabled. If so, then we must create a Trace # 3974 # exception frame from the current exception 3974 # exception frame from the current exception frame and exit through # 3975 # _real_trace(). 3975 # _real_trace(). # 3976 # For "fdbcc", "ftrapcc", and "fscc", t 3976 # For "fdbcc", "ftrapcc", and "fscc", the emulation subroutines # 3977 # _fdbcc(), _ftrapcc(), and _fscc() respectiv 3977 # _fdbcc(), _ftrapcc(), and _fscc() respectively are used. All three # 3978 # may flag that a BSUN exception should be ta 3978 # may flag that a BSUN exception should be taken. If so, then the # 3979 # current exception stack frame is converted 3979 # current exception stack frame is converted into a BSUN exception # 3980 # stack frame and an exit is made through _re 3980 # stack frame and an exit is made through _real_bsun(). If the # 3981 # instruction was "ftrapcc" and a Trap except 3981 # instruction was "ftrapcc" and a Trap exception should result, a Trap # 3982 # exception stack frame is created from the c 3982 # exception stack frame is created from the current frame and an exit # 3983 # is made through _real_trap(). If a Trace ex 3983 # is made through _real_trap(). If a Trace exception is pending, then # 3984 # a Trace exception frame is created from the 3984 # a Trace exception frame is created from the current frame and a jump # 3985 # is made to _real_trace(). Finally, if none 3985 # is made to _real_trace(). Finally, if none of these conditions exist, # 3986 # then the handler exits though the callout _ 3986 # then the handler exits though the callout _fpsp_done(). # 3987 # 3987 # # 3988 # In any of the above scenarios, if a _ 3988 # In any of the above scenarios, if a _mem_read() or _mem_write() # 3989 # "callout" returns a failing value, then an 3989 # "callout" returns a failing value, then an access error stack frame # 3990 # is created from the current stack frame and 3990 # is created from the current stack frame and an exit is made through # 3991 # _real_access(). 3991 # _real_access(). # 3992 # 3992 # # 3993 ############################################# 3993 ######################################################################### 3994 3994 3995 # 3995 # 3996 # FP UNIMPLEMENTED INSTRUCTION STACK FRAME: 3996 # FP UNIMPLEMENTED INSTRUCTION STACK FRAME: 3997 # 3997 # 3998 # ***************** 3998 # ***************** 3999 # * * => <ea> of fp unimp 3999 # * * => <ea> of fp unimp instr. 4000 # - EA - 4000 # - EA - 4001 # * * 4001 # * * 4002 # ***************** 4002 # ***************** 4003 # * 0x2 * 0x02c * => frame format and 4003 # * 0x2 * 0x02c * => frame format and vector offset(vector #11) 4004 # ***************** 4004 # ***************** 4005 # * * 4005 # * * 4006 # - Next PC - => PC of instr to e 4006 # - Next PC - => PC of instr to execute after exc handling 4007 # * * 4007 # * * 4008 # ***************** 4008 # ***************** 4009 # * SR * => SR at the time t 4009 # * SR * => SR at the time the exception was taken 4010 # ***************** 4010 # ***************** 4011 # 4011 # 4012 # Note: the !NULL bit does not get set in the 4012 # Note: the !NULL bit does not get set in the fsave frame when the 4013 # machine encounters an fp unimp exception. T 4013 # machine encounters an fp unimp exception. Therefore, it must be set 4014 # before leaving this handler. 4014 # before leaving this handler. 4015 # 4015 # 4016 global _fpsp_unimp 4016 global _fpsp_unimp 4017 _fpsp_unimp: 4017 _fpsp_unimp: 4018 4018 4019 link.w %a6,&-LOCAL_SIZE 4019 link.w %a6,&-LOCAL_SIZE # init stack frame 4020 4020 4021 movm.l &0x0303,EXC_DREGS(%a6 4021 movm.l &0x0303,EXC_DREGS(%a6) # save d0-d1/a0-a1 4022 fmovm.l %fpcr,%fpsr,%fpiar,US 4022 fmovm.l %fpcr,%fpsr,%fpiar,USER_FPCR(%a6) # save ctrl regs 4023 fmovm.x &0xc0,EXC_FPREGS(%a6) 4023 fmovm.x &0xc0,EXC_FPREGS(%a6) # save fp0-fp1 4024 4024 4025 btst &0x5,EXC_SR(%a6) 4025 btst &0x5,EXC_SR(%a6) # user mode exception? 4026 bne.b funimp_s 4026 bne.b funimp_s # no; supervisor mode 4027 4027 4028 # save the value of the user stack pointer on 4028 # save the value of the user stack pointer onto the stack frame 4029 funimp_u: 4029 funimp_u: 4030 mov.l %usp,%a0 4030 mov.l %usp,%a0 # fetch user stack pointer 4031 mov.l %a0,EXC_A7(%a6) 4031 mov.l %a0,EXC_A7(%a6) # store in stack frame 4032 bra.b funimp_cont 4032 bra.b funimp_cont 4033 4033 4034 # store the value of the supervisor stack poi 4034 # store the value of the supervisor stack pointer BEFORE the exc occurred. 4035 # old_sp is address just above stacked effect 4035 # old_sp is address just above stacked effective address. 4036 funimp_s: 4036 funimp_s: 4037 lea 4+EXC_EA(%a6),%a0 4037 lea 4+EXC_EA(%a6),%a0 # load old a7' 4038 mov.l %a0,EXC_A7(%a6) 4038 mov.l %a0,EXC_A7(%a6) # store a7' 4039 mov.l %a0,OLD_A7(%a6) 4039 mov.l %a0,OLD_A7(%a6) # make a copy 4040 4040 4041 funimp_cont: 4041 funimp_cont: 4042 4042 4043 # the FPIAR holds the "current PC" of the fau 4043 # the FPIAR holds the "current PC" of the faulting instruction. 4044 mov.l USER_FPIAR(%a6),EXC_E 4044 mov.l USER_FPIAR(%a6),EXC_EXTWPTR(%a6) 4045 4045 4046 mov.l EXC_EXTWPTR(%a6),%a0 4046 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 4047 addq.l &0x4,EXC_EXTWPTR(%a6) 4047 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 4048 bsr.l _imem_read_long 4048 bsr.l _imem_read_long # fetch the instruction words 4049 mov.l %d0,EXC_OPWORD(%a6) 4049 mov.l %d0,EXC_OPWORD(%a6) 4050 4050 4051 ############################################# 4051 ############################################################################ 4052 4052 4053 fmov.l &0x0,%fpcr 4053 fmov.l &0x0,%fpcr # clear FPCR 4054 fmov.l &0x0,%fpsr 4054 fmov.l &0x0,%fpsr # clear FPSR 4055 4055 4056 clr.b SPCOND_FLG(%a6) 4056 clr.b SPCOND_FLG(%a6) # clear "special case" flag 4057 4057 4058 # Divide the fp instructions into 8 types bas 4058 # Divide the fp instructions into 8 types based on the TYPE field in 4059 # bits 6-8 of the opword(classes 6,7 are unde 4059 # bits 6-8 of the opword(classes 6,7 are undefined). 4060 # (for the '060, only two types can take thi 4060 # (for the '060, only two types can take this exception) 4061 # bftst %d0{&7:&3} 4061 # bftst %d0{&7:&3} # test TYPE 4062 btst &22,%d0 4062 btst &22,%d0 # type 0 or 1 ? 4063 bne.w funimp_misc 4063 bne.w funimp_misc # type 1 4064 4064 4065 ######################################### 4065 ######################################### 4066 # TYPE == 0: General instructions # 4066 # TYPE == 0: General instructions # 4067 ######################################### 4067 ######################################### 4068 funimp_gen: 4068 funimp_gen: 4069 4069 4070 clr.b STORE_FLG(%a6) 4070 clr.b STORE_FLG(%a6) # clear "store result" flag 4071 4071 4072 # clear the ccode byte and exception status b 4072 # clear the ccode byte and exception status byte 4073 andi.l &0x00ff00ff,USER_FPSR 4073 andi.l &0x00ff00ff,USER_FPSR(%a6) 4074 4074 4075 bfextu %d0{&16:&6},%d1 4075 bfextu %d0{&16:&6},%d1 # extract upper 6 of cmdreg 4076 cmpi.b %d1,&0x17 4076 cmpi.b %d1,&0x17 # is op an fmovecr? 4077 beq.w funimp_fmovcr 4077 beq.w funimp_fmovcr # yes 4078 4078 4079 funimp_gen_op: 4079 funimp_gen_op: 4080 bsr.l _load_fop 4080 bsr.l _load_fop # load 4081 4081 4082 clr.l %d0 4082 clr.l %d0 4083 mov.b FPCR_MODE(%a6),%d0 4083 mov.b FPCR_MODE(%a6),%d0 # fetch rnd mode 4084 4084 4085 mov.b 1+EXC_CMDREG(%a6),%d1 4085 mov.b 1+EXC_CMDREG(%a6),%d1 4086 andi.w &0x003f,%d1 4086 andi.w &0x003f,%d1 # extract extension bits 4087 lsl.w &0x3,%d1 4087 lsl.w &0x3,%d1 # shift right 3 bits 4088 or.b STAG(%a6),%d1 4088 or.b STAG(%a6),%d1 # insert src optag bits 4089 4089 4090 lea FP_DST(%a6),%a1 4090 lea FP_DST(%a6),%a1 # pass dst ptr in a1 4091 lea FP_SRC(%a6),%a0 4091 lea FP_SRC(%a6),%a0 # pass src ptr in a0 4092 4092 4093 mov.w (tbl_trans.w,%pc,%d1. 4093 mov.w (tbl_trans.w,%pc,%d1.w*2),%d1 4094 jsr (tbl_trans.w,%pc,%d1. 4094 jsr (tbl_trans.w,%pc,%d1.w*1) # emulate 4095 4095 4096 funimp_fsave: 4096 funimp_fsave: 4097 mov.b FPCR_ENABLE(%a6),%d0 4097 mov.b FPCR_ENABLE(%a6),%d0 # fetch exceptions enabled 4098 bne.w funimp_ena 4098 bne.w funimp_ena # some are enabled 4099 4099 4100 funimp_store: 4100 funimp_store: 4101 bfextu EXC_CMDREG(%a6){&6:&3 4101 bfextu EXC_CMDREG(%a6){&6:&3},%d0 # fetch Dn 4102 bsr.l store_fpreg 4102 bsr.l store_fpreg # store result to fp regfile 4103 4103 4104 funimp_gen_exit: 4104 funimp_gen_exit: 4105 fmovm.x EXC_FP0(%a6),&0xc0 4105 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 4106 fmovm.l USER_FPCR(%a6),%fpcr, 4106 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 4107 movm.l EXC_DREGS(%a6),&0x030 4107 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4108 4108 4109 funimp_gen_exit_cmp: 4109 funimp_gen_exit_cmp: 4110 cmpi.b SPCOND_FLG(%a6),&mia7 4110 cmpi.b SPCOND_FLG(%a6),&mia7_flg # was the ea mode (sp)+ ? 4111 beq.b funimp_gen_exit_a7 4111 beq.b funimp_gen_exit_a7 # yes 4112 4112 4113 cmpi.b SPCOND_FLG(%a6),&mda7 4113 cmpi.b SPCOND_FLG(%a6),&mda7_flg # was the ea mode -(sp) ? 4114 beq.b funimp_gen_exit_a7 4114 beq.b funimp_gen_exit_a7 # yes 4115 4115 4116 funimp_gen_exit_cont: 4116 funimp_gen_exit_cont: 4117 unlk %a6 4117 unlk %a6 4118 4118 4119 funimp_gen_exit_cont2: 4119 funimp_gen_exit_cont2: 4120 btst &0x7,(%sp) 4120 btst &0x7,(%sp) # is trace on? 4121 beq.l _fpsp_done 4121 beq.l _fpsp_done # no 4122 4122 4123 # this catches a problem with the case where 4123 # this catches a problem with the case where an exception will be re-inserted 4124 # into the machine. the frestore has already 4124 # into the machine. the frestore has already been executed...so, the fmov.l 4125 # alone of the control register would trigger 4125 # alone of the control register would trigger an unwanted exception. 4126 # until I feel like fixing this, we'll sidest 4126 # until I feel like fixing this, we'll sidestep the exception. 4127 fsave -(%sp) 4127 fsave -(%sp) 4128 fmov.l %fpiar,0x14(%sp) 4128 fmov.l %fpiar,0x14(%sp) # "Current PC" is in FPIAR 4129 frestore (%sp)+ 4129 frestore (%sp)+ 4130 mov.w &0x2024,0x6(%sp) 4130 mov.w &0x2024,0x6(%sp) # stk fmt = 0x2; voff = 0x24 4131 bra.l _real_trace 4131 bra.l _real_trace 4132 4132 4133 funimp_gen_exit_a7: 4133 funimp_gen_exit_a7: 4134 btst &0x5,EXC_SR(%a6) 4134 btst &0x5,EXC_SR(%a6) # supervisor or user mode? 4135 bne.b funimp_gen_exit_a7_s 4135 bne.b funimp_gen_exit_a7_s # supervisor 4136 4136 4137 mov.l %a0,-(%sp) 4137 mov.l %a0,-(%sp) 4138 mov.l EXC_A7(%a6),%a0 4138 mov.l EXC_A7(%a6),%a0 4139 mov.l %a0,%usp 4139 mov.l %a0,%usp 4140 mov.l (%sp)+,%a0 4140 mov.l (%sp)+,%a0 4141 bra.b funimp_gen_exit_cont 4141 bra.b funimp_gen_exit_cont 4142 4142 4143 # if the instruction was executed from superv 4143 # if the instruction was executed from supervisor mode and the addressing 4144 # mode was (a7)+, then the stack frame for th 4144 # mode was (a7)+, then the stack frame for the rte must be shifted "up" 4145 # "n" bytes where "n" is the size of the src 4145 # "n" bytes where "n" is the size of the src operand type. 4146 # f<op>.{b,w,l,s,d,x,p} 4146 # f<op>.{b,w,l,s,d,x,p} 4147 funimp_gen_exit_a7_s: 4147 funimp_gen_exit_a7_s: 4148 mov.l %d0,-(%sp) 4148 mov.l %d0,-(%sp) # save d0 4149 mov.l EXC_A7(%a6),%d0 4149 mov.l EXC_A7(%a6),%d0 # load new a7' 4150 sub.l OLD_A7(%a6),%d0 4150 sub.l OLD_A7(%a6),%d0 # subtract old a7' 4151 mov.l 0x2+EXC_PC(%a6),(0x2+ 4151 mov.l 0x2+EXC_PC(%a6),(0x2+EXC_PC,%a6,%d0) # shift stack frame 4152 mov.l EXC_SR(%a6),(EXC_SR,% 4152 mov.l EXC_SR(%a6),(EXC_SR,%a6,%d0) # shift stack frame 4153 mov.w %d0,EXC_SR(%a6) 4153 mov.w %d0,EXC_SR(%a6) # store incr number 4154 mov.l (%sp)+,%d0 4154 mov.l (%sp)+,%d0 # restore d0 4155 4155 4156 unlk %a6 4156 unlk %a6 4157 4157 4158 add.w (%sp),%sp 4158 add.w (%sp),%sp # stack frame shifted 4159 bra.b funimp_gen_exit_cont2 4159 bra.b funimp_gen_exit_cont2 4160 4160 4161 ###################### 4161 ###################### 4162 # fmovecr.x #ccc,fpn # 4162 # fmovecr.x #ccc,fpn # 4163 ###################### 4163 ###################### 4164 funimp_fmovcr: 4164 funimp_fmovcr: 4165 clr.l %d0 4165 clr.l %d0 4166 mov.b FPCR_MODE(%a6),%d0 4166 mov.b FPCR_MODE(%a6),%d0 4167 mov.b 1+EXC_CMDREG(%a6),%d1 4167 mov.b 1+EXC_CMDREG(%a6),%d1 4168 andi.l &0x0000007f,%d1 4168 andi.l &0x0000007f,%d1 # pass rom offset in d1 4169 bsr.l smovcr 4169 bsr.l smovcr 4170 bra.w funimp_fsave 4170 bra.w funimp_fsave 4171 4171 4172 ############################################# 4172 ######################################################################### 4173 4173 4174 # 4174 # 4175 # the user has enabled some exceptions. we fi 4175 # the user has enabled some exceptions. we figure not to see this too 4176 # often so that's why it gets lower priority. 4176 # often so that's why it gets lower priority. 4177 # 4177 # 4178 funimp_ena: 4178 funimp_ena: 4179 4179 4180 # was an exception set that was also enabled? 4180 # was an exception set that was also enabled? 4181 and.b FPSR_EXCEPT(%a6),%d0 4181 and.b FPSR_EXCEPT(%a6),%d0 # keep only ones enabled and set 4182 bfffo %d0{&24:&8},%d0 4182 bfffo %d0{&24:&8},%d0 # find highest priority exception 4183 bne.b funimp_exc 4183 bne.b funimp_exc # at least one was set 4184 4184 4185 # no exception that was enabled was set BUT i 4185 # no exception that was enabled was set BUT if we got an exact overflow 4186 # and overflow wasn't enabled but inexact was 4186 # and overflow wasn't enabled but inexact was (yech!) then this is 4187 # an inexact exception; otherwise, return to 4187 # an inexact exception; otherwise, return to normal non-exception flow. 4188 btst &ovfl_bit,FPSR_EXCEPT 4188 btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur? 4189 beq.w funimp_store 4189 beq.w funimp_store # no; return to normal flow 4190 4190 4191 # the overflow w/ exact result happened but w 4191 # the overflow w/ exact result happened but was inexact set in the FPCR? 4192 funimp_ovfl: 4192 funimp_ovfl: 4193 btst &inex2_bit,FPCR_ENABL 4193 btst &inex2_bit,FPCR_ENABLE(%a6) # is inexact enabled? 4194 beq.w funimp_store 4194 beq.w funimp_store # no; return to normal flow 4195 bra.b funimp_exc_ovfl 4195 bra.b funimp_exc_ovfl # yes 4196 4196 4197 # some exception happened that was actually e 4197 # some exception happened that was actually enabled. 4198 # we'll insert this new exception into the FP 4198 # we'll insert this new exception into the FPU and then return. 4199 funimp_exc: 4199 funimp_exc: 4200 subi.l &24,%d0 4200 subi.l &24,%d0 # fix offset to be 0-8 4201 cmpi.b %d0,&0x6 4201 cmpi.b %d0,&0x6 # is exception INEX? 4202 bne.b funimp_exc_force 4202 bne.b funimp_exc_force # no 4203 4203 4204 # the enabled exception was inexact. so, if i 4204 # the enabled exception was inexact. so, if it occurs with an overflow 4205 # or underflow that was disabled, then we hav 4205 # or underflow that was disabled, then we have to force an overflow or 4206 # underflow frame. the eventual overflow or u 4206 # underflow frame. the eventual overflow or underflow handler will see that 4207 # it's actually an inexact and act appropriat 4207 # it's actually an inexact and act appropriately. this is the only easy 4208 # way to have the EXOP available for the enab 4208 # way to have the EXOP available for the enabled inexact handler when 4209 # a disabled overflow or underflow has also h 4209 # a disabled overflow or underflow has also happened. 4210 btst &ovfl_bit,FPSR_EXCEPT 4210 btst &ovfl_bit,FPSR_EXCEPT(%a6) # did overflow occur? 4211 bne.b funimp_exc_ovfl 4211 bne.b funimp_exc_ovfl # yes 4212 btst &unfl_bit,FPSR_EXCEPT 4212 btst &unfl_bit,FPSR_EXCEPT(%a6) # did underflow occur? 4213 bne.b funimp_exc_unfl 4213 bne.b funimp_exc_unfl # yes 4214 4214 4215 # force the fsave exception status bits to si 4215 # force the fsave exception status bits to signal an exception of the 4216 # appropriate type. don't forget to "skew" th 4216 # appropriate type. don't forget to "skew" the source operand in case we 4217 # "unskewed" the one the hardware initially g 4217 # "unskewed" the one the hardware initially gave us. 4218 funimp_exc_force: 4218 funimp_exc_force: 4219 mov.l %d0,-(%sp) 4219 mov.l %d0,-(%sp) # save d0 4220 bsr.l funimp_skew 4220 bsr.l funimp_skew # check for special case 4221 mov.l (%sp)+,%d0 4221 mov.l (%sp)+,%d0 # restore d0 4222 mov.w (tbl_funimp_except.b, 4222 mov.w (tbl_funimp_except.b,%pc,%d0.w*2),2+FP_SRC(%a6) 4223 bra.b funimp_gen_exit2 4223 bra.b funimp_gen_exit2 # exit with frestore 4224 4224 4225 tbl_funimp_except: 4225 tbl_funimp_except: 4226 short 0xe002, 0xe006, 0xe00 4226 short 0xe002, 0xe006, 0xe004, 0xe005 4227 short 0xe003, 0xe002, 0xe00 4227 short 0xe003, 0xe002, 0xe001, 0xe001 4228 4228 4229 # insert an overflow frame 4229 # insert an overflow frame 4230 funimp_exc_ovfl: 4230 funimp_exc_ovfl: 4231 bsr.l funimp_skew 4231 bsr.l funimp_skew # check for special case 4232 mov.w &0xe005,2+FP_SRC(%a6) 4232 mov.w &0xe005,2+FP_SRC(%a6) 4233 bra.b funimp_gen_exit2 4233 bra.b funimp_gen_exit2 4234 4234 4235 # insert an underflow frame 4235 # insert an underflow frame 4236 funimp_exc_unfl: 4236 funimp_exc_unfl: 4237 bsr.l funimp_skew 4237 bsr.l funimp_skew # check for special case 4238 mov.w &0xe003,2+FP_SRC(%a6) 4238 mov.w &0xe003,2+FP_SRC(%a6) 4239 4239 4240 # this is the general exit point for an enabl 4240 # this is the general exit point for an enabled exception that will be 4241 # restored into the machine for the instructi 4241 # restored into the machine for the instruction just emulated. 4242 funimp_gen_exit2: 4242 funimp_gen_exit2: 4243 fmovm.x EXC_FP0(%a6),&0xc0 4243 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 4244 fmovm.l USER_FPCR(%a6),%fpcr, 4244 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 4245 movm.l EXC_DREGS(%a6),&0x030 4245 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4246 4246 4247 frestore FP_SRC(%a6) 4247 frestore FP_SRC(%a6) # insert exceptional status 4248 4248 4249 bra.w funimp_gen_exit_cmp 4249 bra.w funimp_gen_exit_cmp 4250 4250 4251 ############################################# 4251 ############################################################################ 4252 4252 4253 # 4253 # 4254 # TYPE == 1: FDB<cc>, FS<cc>, FTRAP<cc> 4254 # TYPE == 1: FDB<cc>, FS<cc>, FTRAP<cc> 4255 # 4255 # 4256 # These instructions were implemented on the 4256 # These instructions were implemented on the '881/2 and '040 in hardware but 4257 # are emulated in software on the '060. 4257 # are emulated in software on the '060. 4258 # 4258 # 4259 funimp_misc: 4259 funimp_misc: 4260 bfextu %d0{&10:&3},%d1 4260 bfextu %d0{&10:&3},%d1 # extract mode field 4261 cmpi.b %d1,&0x1 4261 cmpi.b %d1,&0x1 # is it an fdb<cc>? 4262 beq.w funimp_fdbcc 4262 beq.w funimp_fdbcc # yes 4263 cmpi.b %d1,&0x7 4263 cmpi.b %d1,&0x7 # is it an fs<cc>? 4264 bne.w funimp_fscc 4264 bne.w funimp_fscc # yes 4265 bfextu %d0{&13:&3},%d1 4265 bfextu %d0{&13:&3},%d1 4266 cmpi.b %d1,&0x2 4266 cmpi.b %d1,&0x2 # is it an fs<cc>? 4267 blt.w funimp_fscc 4267 blt.w funimp_fscc # yes 4268 4268 4269 ######################### 4269 ######################### 4270 # ftrap<cc> # 4270 # ftrap<cc> # 4271 # ftrap<cc>.w #<data> # 4271 # ftrap<cc>.w #<data> # 4272 # ftrap<cc>.l #<data> # 4272 # ftrap<cc>.l #<data> # 4273 ######################### 4273 ######################### 4274 funimp_ftrapcc: 4274 funimp_ftrapcc: 4275 4275 4276 bsr.l _ftrapcc 4276 bsr.l _ftrapcc # FTRAP<cc>() 4277 4277 4278 cmpi.b SPCOND_FLG(%a6),&fbsu 4278 cmpi.b SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring? 4279 beq.w funimp_bsun 4279 beq.w funimp_bsun # yes 4280 4280 4281 cmpi.b SPCOND_FLG(%a6),&ftra 4281 cmpi.b SPCOND_FLG(%a6),&ftrapcc_flg # should a trap occur? 4282 bne.w funimp_done 4282 bne.w funimp_done # no 4283 4283 4284 # FP UNIMP FRAME TRAP FRAM 4284 # FP UNIMP FRAME TRAP FRAME 4285 # ***************** ************* 4285 # ***************** ***************** 4286 # ** <EA> ** ** Current P 4286 # ** <EA> ** ** Current PC ** 4287 # ***************** ************* 4287 # ***************** ***************** 4288 # * 0x2 * 0x02c * * 0x2 * 0x01 4288 # * 0x2 * 0x02c * * 0x2 * 0x01c * 4289 # ***************** ************* 4289 # ***************** ***************** 4290 # ** Next PC ** ** Next PC 4290 # ** Next PC ** ** Next PC ** 4291 # ***************** ************* 4291 # ***************** ***************** 4292 # * SR * * SR 4292 # * SR * * SR * 4293 # ***************** ************* 4293 # ***************** ***************** 4294 # (6 words) (6 words) 4294 # (6 words) (6 words) 4295 # 4295 # 4296 # the ftrapcc instruction should take a trap. 4296 # the ftrapcc instruction should take a trap. so, here we must create a 4297 # trap stack frame from an unimplemented fp i 4297 # trap stack frame from an unimplemented fp instruction stack frame and 4298 # jump to the user supplied entry point for t 4298 # jump to the user supplied entry point for the trap exception 4299 funimp_ftrapcc_tp: 4299 funimp_ftrapcc_tp: 4300 mov.l USER_FPIAR(%a6),EXC_E 4300 mov.l USER_FPIAR(%a6),EXC_EA(%a6) # Address = Current PC 4301 mov.w &0x201c,EXC_VOFF(%a6) 4301 mov.w &0x201c,EXC_VOFF(%a6) # Vector Offset = 0x01c 4302 4302 4303 fmovm.x EXC_FP0(%a6),&0xc0 4303 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 4304 fmovm.l USER_FPCR(%a6),%fpcr, 4304 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 4305 movm.l EXC_DREGS(%a6),&0x030 4305 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4306 4306 4307 unlk %a6 4307 unlk %a6 4308 bra.l _real_trap 4308 bra.l _real_trap 4309 4309 4310 ######################### 4310 ######################### 4311 # fdb<cc> Dn,<label> # 4311 # fdb<cc> Dn,<label> # 4312 ######################### 4312 ######################### 4313 funimp_fdbcc: 4313 funimp_fdbcc: 4314 4314 4315 mov.l EXC_EXTWPTR(%a6),%a0 4315 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 4316 addq.l &0x2,EXC_EXTWPTR(%a6) 4316 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 4317 bsr.l _imem_read_word 4317 bsr.l _imem_read_word # read displacement 4318 4318 4319 tst.l %d1 4319 tst.l %d1 # did ifetch fail? 4320 bne.w funimp_iacc 4320 bne.w funimp_iacc # yes 4321 4321 4322 ext.l %d0 4322 ext.l %d0 # sign extend displacement 4323 4323 4324 bsr.l _fdbcc 4324 bsr.l _fdbcc # FDB<cc>() 4325 4325 4326 cmpi.b SPCOND_FLG(%a6),&fbsu 4326 cmpi.b SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring? 4327 beq.w funimp_bsun 4327 beq.w funimp_bsun 4328 4328 4329 bra.w funimp_done 4329 bra.w funimp_done # branch to finish 4330 4330 4331 ################# 4331 ################# 4332 # fs<cc>.b <ea> # 4332 # fs<cc>.b <ea> # 4333 ################# 4333 ################# 4334 funimp_fscc: 4334 funimp_fscc: 4335 4335 4336 bsr.l _fscc 4336 bsr.l _fscc # FS<cc>() 4337 4337 4338 # I am assuming here that an "fs<cc>.b -(An)" 4338 # I am assuming here that an "fs<cc>.b -(An)" or "fs<cc>.b (An)+" instruction 4339 # does not need to update "An" before taking 4339 # does not need to update "An" before taking a bsun exception. 4340 cmpi.b SPCOND_FLG(%a6),&fbsu 4340 cmpi.b SPCOND_FLG(%a6),&fbsun_flg # is enabled bsun occurring? 4341 beq.w funimp_bsun 4341 beq.w funimp_bsun 4342 4342 4343 btst &0x5,EXC_SR(%a6) 4343 btst &0x5,EXC_SR(%a6) # yes; is it a user mode exception? 4344 bne.b funimp_fscc_s 4344 bne.b funimp_fscc_s # no 4345 4345 4346 funimp_fscc_u: 4346 funimp_fscc_u: 4347 mov.l EXC_A7(%a6),%a0 4347 mov.l EXC_A7(%a6),%a0 # yes; set new USP 4348 mov.l %a0,%usp 4348 mov.l %a0,%usp 4349 bra.w funimp_done 4349 bra.w funimp_done # branch to finish 4350 4350 4351 # remember, I'm assuming that post-increment 4351 # remember, I'm assuming that post-increment is bogus...(it IS!!!) 4352 # so, the least significant WORD of the stack 4352 # so, the least significant WORD of the stacked effective address got 4353 # overwritten by the "fs<cc> -(An)". We must 4353 # overwritten by the "fs<cc> -(An)". We must shift the stack frame "down" 4354 # so that the rte will work correctly without 4354 # so that the rte will work correctly without destroying the result. 4355 # even though the operation size is byte, the 4355 # even though the operation size is byte, the stack ptr is decr by 2. 4356 # 4356 # 4357 # remember, also, this instruction may be tra 4357 # remember, also, this instruction may be traced. 4358 funimp_fscc_s: 4358 funimp_fscc_s: 4359 cmpi.b SPCOND_FLG(%a6),&mda7 4359 cmpi.b SPCOND_FLG(%a6),&mda7_flg # was a7 modified? 4360 bne.w funimp_done 4360 bne.w funimp_done # no 4361 4361 4362 fmovm.x EXC_FP0(%a6),&0xc0 4362 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 4363 fmovm.l USER_FPCR(%a6),%fpcr, 4363 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 4364 movm.l EXC_DREGS(%a6),&0x030 4364 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4365 4365 4366 unlk %a6 4366 unlk %a6 4367 4367 4368 btst &0x7,(%sp) 4368 btst &0x7,(%sp) # is trace enabled? 4369 bne.b funimp_fscc_s_trace 4369 bne.b funimp_fscc_s_trace # yes 4370 4370 4371 subq.l &0x2,%sp 4371 subq.l &0x2,%sp 4372 mov.l 0x2(%sp),(%sp) 4372 mov.l 0x2(%sp),(%sp) # shift SR,hi(PC) "down" 4373 mov.l 0x6(%sp),0x4(%sp) 4373 mov.l 0x6(%sp),0x4(%sp) # shift lo(PC),voff "down" 4374 bra.l _fpsp_done 4374 bra.l _fpsp_done 4375 4375 4376 funimp_fscc_s_trace: 4376 funimp_fscc_s_trace: 4377 subq.l &0x2,%sp 4377 subq.l &0x2,%sp 4378 mov.l 0x2(%sp),(%sp) 4378 mov.l 0x2(%sp),(%sp) # shift SR,hi(PC) "down" 4379 mov.w 0x6(%sp),0x4(%sp) 4379 mov.w 0x6(%sp),0x4(%sp) # shift lo(PC) 4380 mov.w &0x2024,0x6(%sp) 4380 mov.w &0x2024,0x6(%sp) # fmt/voff = $2024 4381 fmov.l %fpiar,0x8(%sp) 4381 fmov.l %fpiar,0x8(%sp) # insert "current PC" 4382 4382 4383 bra.l _real_trace 4383 bra.l _real_trace 4384 4384 4385 # 4385 # 4386 # The ftrap<cc>, fs<cc>, or fdb<cc> is to tak 4386 # The ftrap<cc>, fs<cc>, or fdb<cc> is to take an enabled bsun. we must convert 4387 # the fp unimplemented instruction exception 4387 # the fp unimplemented instruction exception stack frame into a bsun stack frame, 4388 # restore a bsun exception into the machine, 4388 # restore a bsun exception into the machine, and branch to the user 4389 # supplied bsun hook. 4389 # supplied bsun hook. 4390 # 4390 # 4391 # FP UNIMP FRAME BSUN FRAME 4391 # FP UNIMP FRAME BSUN FRAME 4392 # ***************** ************* 4392 # ***************** ***************** 4393 # ** <EA> ** * 0x0 * 0x0c0 4393 # ** <EA> ** * 0x0 * 0x0c0 * 4394 # ***************** ************* 4394 # ***************** ***************** 4395 # * 0x2 * 0x02c * ** Current PC 4395 # * 0x2 * 0x02c * ** Current PC ** 4396 # ***************** ************* 4396 # ***************** ***************** 4397 # ** Next PC ** * SR 4397 # ** Next PC ** * SR * 4398 # ***************** ************* 4398 # ***************** ***************** 4399 # * SR * (4 words) 4399 # * SR * (4 words) 4400 # ***************** 4400 # ***************** 4401 # (6 words) 4401 # (6 words) 4402 # 4402 # 4403 funimp_bsun: 4403 funimp_bsun: 4404 mov.w &0x00c0,2+EXC_EA(%a6) 4404 mov.w &0x00c0,2+EXC_EA(%a6) # Fmt = 0x0; Vector Offset = 0x0c0 4405 mov.l USER_FPIAR(%a6),EXC_V 4405 mov.l USER_FPIAR(%a6),EXC_VOFF(%a6) # PC = Current PC 4406 mov.w EXC_SR(%a6),2+EXC_PC( 4406 mov.w EXC_SR(%a6),2+EXC_PC(%a6) # shift SR "up" 4407 4407 4408 mov.w &0xe000,2+FP_SRC(%a6) 4408 mov.w &0xe000,2+FP_SRC(%a6) # bsun exception enabled 4409 4409 4410 fmovm.x EXC_FP0(%a6),&0xc0 4410 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 4411 fmovm.l USER_FPCR(%a6),%fpcr, 4411 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 4412 movm.l EXC_DREGS(%a6),&0x030 4412 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4413 4413 4414 frestore FP_SRC(%a6) 4414 frestore FP_SRC(%a6) # restore bsun exception 4415 4415 4416 unlk %a6 4416 unlk %a6 4417 4417 4418 addq.l &0x4,%sp 4418 addq.l &0x4,%sp # erase sludge 4419 4419 4420 bra.l _real_bsun 4420 bra.l _real_bsun # branch to user bsun hook 4421 4421 4422 # 4422 # 4423 # all ftrapcc/fscc/fdbcc processing has been 4423 # all ftrapcc/fscc/fdbcc processing has been completed. unwind the stack frame 4424 # and return. 4424 # and return. 4425 # 4425 # 4426 # as usual, we have to check for trace mode b 4426 # as usual, we have to check for trace mode being on here. since instructions 4427 # modifying the supervisor stack frame don't 4427 # modifying the supervisor stack frame don't pass through here, this is a 4428 # relatively easy task. 4428 # relatively easy task. 4429 # 4429 # 4430 funimp_done: 4430 funimp_done: 4431 fmovm.x EXC_FP0(%a6),&0xc0 4431 fmovm.x EXC_FP0(%a6),&0xc0 # restore fp0-fp1 4432 fmovm.l USER_FPCR(%a6),%fpcr, 4432 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 4433 movm.l EXC_DREGS(%a6),&0x030 4433 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4434 4434 4435 unlk %a6 4435 unlk %a6 4436 4436 4437 btst &0x7,(%sp) 4437 btst &0x7,(%sp) # is trace enabled? 4438 bne.b funimp_trace 4438 bne.b funimp_trace # yes 4439 4439 4440 bra.l _fpsp_done 4440 bra.l _fpsp_done 4441 4441 4442 # FP UNIMP FRAME TRACE FRAM 4442 # FP UNIMP FRAME TRACE FRAME 4443 # ***************** ************* 4443 # ***************** ***************** 4444 # ** <EA> ** ** Current P 4444 # ** <EA> ** ** Current PC ** 4445 # ***************** ************* 4445 # ***************** ***************** 4446 # * 0x2 * 0x02c * * 0x2 * 0x02 4446 # * 0x2 * 0x02c * * 0x2 * 0x024 * 4447 # ***************** ************* 4447 # ***************** ***************** 4448 # ** Next PC ** ** Next PC 4448 # ** Next PC ** ** Next PC ** 4449 # ***************** ************* 4449 # ***************** ***************** 4450 # * SR * * SR 4450 # * SR * * SR * 4451 # ***************** ************* 4451 # ***************** ***************** 4452 # (6 words) (6 words) 4452 # (6 words) (6 words) 4453 # 4453 # 4454 # the fscc instruction should take a trace tr 4454 # the fscc instruction should take a trace trap. so, here we must create a 4455 # trace stack frame from an unimplemented fp 4455 # trace stack frame from an unimplemented fp instruction stack frame and 4456 # jump to the user supplied entry point for t 4456 # jump to the user supplied entry point for the trace exception 4457 funimp_trace: 4457 funimp_trace: 4458 fmov.l %fpiar,0x8(%sp) 4458 fmov.l %fpiar,0x8(%sp) # current PC is in fpiar 4459 mov.b &0x24,0x7(%sp) 4459 mov.b &0x24,0x7(%sp) # vector offset = 0x024 4460 4460 4461 bra.l _real_trace 4461 bra.l _real_trace 4462 4462 4463 ############################################# 4463 ################################################################ 4464 4464 4465 global tbl_trans 4465 global tbl_trans 4466 swbeg &0x1c0 4466 swbeg &0x1c0 4467 tbl_trans: 4467 tbl_trans: 4468 short tbl_trans - tbl_trans 4468 short tbl_trans - tbl_trans # $00-0 fmovecr all 4469 short tbl_trans - tbl_trans 4469 short tbl_trans - tbl_trans # $00-1 fmovecr all 4470 short tbl_trans - tbl_trans 4470 short tbl_trans - tbl_trans # $00-2 fmovecr all 4471 short tbl_trans - tbl_trans 4471 short tbl_trans - tbl_trans # $00-3 fmovecr all 4472 short tbl_trans - tbl_trans 4472 short tbl_trans - tbl_trans # $00-4 fmovecr all 4473 short tbl_trans - tbl_trans 4473 short tbl_trans - tbl_trans # $00-5 fmovecr all 4474 short tbl_trans - tbl_trans 4474 short tbl_trans - tbl_trans # $00-6 fmovecr all 4475 short tbl_trans - tbl_trans 4475 short tbl_trans - tbl_trans # $00-7 fmovecr all 4476 4476 4477 short tbl_trans - tbl_trans 4477 short tbl_trans - tbl_trans # $01-0 fint norm 4478 short tbl_trans - tbl_trans 4478 short tbl_trans - tbl_trans # $01-1 fint zero 4479 short tbl_trans - tbl_trans 4479 short tbl_trans - tbl_trans # $01-2 fint inf 4480 short tbl_trans - tbl_trans 4480 short tbl_trans - tbl_trans # $01-3 fint qnan 4481 short tbl_trans - tbl_trans 4481 short tbl_trans - tbl_trans # $01-5 fint denorm 4482 short tbl_trans - tbl_trans 4482 short tbl_trans - tbl_trans # $01-4 fint snan 4483 short tbl_trans - tbl_trans 4483 short tbl_trans - tbl_trans # $01-6 fint unnorm 4484 short tbl_trans - tbl_trans 4484 short tbl_trans - tbl_trans # $01-7 ERROR 4485 4485 4486 short ssinh - tbl_trans 4486 short ssinh - tbl_trans # $02-0 fsinh norm 4487 short src_zero - tbl_trans 4487 short src_zero - tbl_trans # $02-1 fsinh zero 4488 short src_inf - tbl_trans 4488 short src_inf - tbl_trans # $02-2 fsinh inf 4489 short src_qnan - tbl_trans 4489 short src_qnan - tbl_trans # $02-3 fsinh qnan 4490 short ssinhd - tbl_trans 4490 short ssinhd - tbl_trans # $02-5 fsinh denorm 4491 short src_snan - tbl_trans 4491 short src_snan - tbl_trans # $02-4 fsinh snan 4492 short tbl_trans - tbl_trans 4492 short tbl_trans - tbl_trans # $02-6 fsinh unnorm 4493 short tbl_trans - tbl_trans 4493 short tbl_trans - tbl_trans # $02-7 ERROR 4494 4494 4495 short tbl_trans - tbl_trans 4495 short tbl_trans - tbl_trans # $03-0 fintrz norm 4496 short tbl_trans - tbl_trans 4496 short tbl_trans - tbl_trans # $03-1 fintrz zero 4497 short tbl_trans - tbl_trans 4497 short tbl_trans - tbl_trans # $03-2 fintrz inf 4498 short tbl_trans - tbl_trans 4498 short tbl_trans - tbl_trans # $03-3 fintrz qnan 4499 short tbl_trans - tbl_trans 4499 short tbl_trans - tbl_trans # $03-5 fintrz denorm 4500 short tbl_trans - tbl_trans 4500 short tbl_trans - tbl_trans # $03-4 fintrz snan 4501 short tbl_trans - tbl_trans 4501 short tbl_trans - tbl_trans # $03-6 fintrz unnorm 4502 short tbl_trans - tbl_trans 4502 short tbl_trans - tbl_trans # $03-7 ERROR 4503 4503 4504 short tbl_trans - tbl_trans 4504 short tbl_trans - tbl_trans # $04-0 fsqrt norm 4505 short tbl_trans - tbl_trans 4505 short tbl_trans - tbl_trans # $04-1 fsqrt zero 4506 short tbl_trans - tbl_trans 4506 short tbl_trans - tbl_trans # $04-2 fsqrt inf 4507 short tbl_trans - tbl_trans 4507 short tbl_trans - tbl_trans # $04-3 fsqrt qnan 4508 short tbl_trans - tbl_trans 4508 short tbl_trans - tbl_trans # $04-5 fsqrt denorm 4509 short tbl_trans - tbl_trans 4509 short tbl_trans - tbl_trans # $04-4 fsqrt snan 4510 short tbl_trans - tbl_trans 4510 short tbl_trans - tbl_trans # $04-6 fsqrt unnorm 4511 short tbl_trans - tbl_trans 4511 short tbl_trans - tbl_trans # $04-7 ERROR 4512 4512 4513 short tbl_trans - tbl_trans 4513 short tbl_trans - tbl_trans # $05-0 ERROR 4514 short tbl_trans - tbl_trans 4514 short tbl_trans - tbl_trans # $05-1 ERROR 4515 short tbl_trans - tbl_trans 4515 short tbl_trans - tbl_trans # $05-2 ERROR 4516 short tbl_trans - tbl_trans 4516 short tbl_trans - tbl_trans # $05-3 ERROR 4517 short tbl_trans - tbl_trans 4517 short tbl_trans - tbl_trans # $05-4 ERROR 4518 short tbl_trans - tbl_trans 4518 short tbl_trans - tbl_trans # $05-5 ERROR 4519 short tbl_trans - tbl_trans 4519 short tbl_trans - tbl_trans # $05-6 ERROR 4520 short tbl_trans - tbl_trans 4520 short tbl_trans - tbl_trans # $05-7 ERROR 4521 4521 4522 short slognp1 - tbl_trans 4522 short slognp1 - tbl_trans # $06-0 flognp1 norm 4523 short src_zero - tbl_trans 4523 short src_zero - tbl_trans # $06-1 flognp1 zero 4524 short sopr_inf - tbl_trans 4524 short sopr_inf - tbl_trans # $06-2 flognp1 inf 4525 short src_qnan - tbl_trans 4525 short src_qnan - tbl_trans # $06-3 flognp1 qnan 4526 short slognp1d - tbl_trans 4526 short slognp1d - tbl_trans # $06-5 flognp1 denorm 4527 short src_snan - tbl_trans 4527 short src_snan - tbl_trans # $06-4 flognp1 snan 4528 short tbl_trans - tbl_trans 4528 short tbl_trans - tbl_trans # $06-6 flognp1 unnorm 4529 short tbl_trans - tbl_trans 4529 short tbl_trans - tbl_trans # $06-7 ERROR 4530 4530 4531 short tbl_trans - tbl_trans 4531 short tbl_trans - tbl_trans # $07-0 ERROR 4532 short tbl_trans - tbl_trans 4532 short tbl_trans - tbl_trans # $07-1 ERROR 4533 short tbl_trans - tbl_trans 4533 short tbl_trans - tbl_trans # $07-2 ERROR 4534 short tbl_trans - tbl_trans 4534 short tbl_trans - tbl_trans # $07-3 ERROR 4535 short tbl_trans - tbl_trans 4535 short tbl_trans - tbl_trans # $07-4 ERROR 4536 short tbl_trans - tbl_trans 4536 short tbl_trans - tbl_trans # $07-5 ERROR 4537 short tbl_trans - tbl_trans 4537 short tbl_trans - tbl_trans # $07-6 ERROR 4538 short tbl_trans - tbl_trans 4538 short tbl_trans - tbl_trans # $07-7 ERROR 4539 4539 4540 short setoxm1 - tbl_trans 4540 short setoxm1 - tbl_trans # $08-0 fetoxm1 norm 4541 short src_zero - tbl_trans 4541 short src_zero - tbl_trans # $08-1 fetoxm1 zero 4542 short setoxm1i - tbl_trans 4542 short setoxm1i - tbl_trans # $08-2 fetoxm1 inf 4543 short src_qnan - tbl_trans 4543 short src_qnan - tbl_trans # $08-3 fetoxm1 qnan 4544 short setoxm1d - tbl_trans 4544 short setoxm1d - tbl_trans # $08-5 fetoxm1 denorm 4545 short src_snan - tbl_trans 4545 short src_snan - tbl_trans # $08-4 fetoxm1 snan 4546 short tbl_trans - tbl_trans 4546 short tbl_trans - tbl_trans # $08-6 fetoxm1 unnorm 4547 short tbl_trans - tbl_trans 4547 short tbl_trans - tbl_trans # $08-7 ERROR 4548 4548 4549 short stanh - tbl_trans 4549 short stanh - tbl_trans # $09-0 ftanh norm 4550 short src_zero - tbl_trans 4550 short src_zero - tbl_trans # $09-1 ftanh zero 4551 short src_one - tbl_trans 4551 short src_one - tbl_trans # $09-2 ftanh inf 4552 short src_qnan - tbl_trans 4552 short src_qnan - tbl_trans # $09-3 ftanh qnan 4553 short stanhd - tbl_trans 4553 short stanhd - tbl_trans # $09-5 ftanh denorm 4554 short src_snan - tbl_trans 4554 short src_snan - tbl_trans # $09-4 ftanh snan 4555 short tbl_trans - tbl_trans 4555 short tbl_trans - tbl_trans # $09-6 ftanh unnorm 4556 short tbl_trans - tbl_trans 4556 short tbl_trans - tbl_trans # $09-7 ERROR 4557 4557 4558 short satan - tbl_trans 4558 short satan - tbl_trans # $0a-0 fatan norm 4559 short src_zero - tbl_trans 4559 short src_zero - tbl_trans # $0a-1 fatan zero 4560 short spi_2 - tbl_trans 4560 short spi_2 - tbl_trans # $0a-2 fatan inf 4561 short src_qnan - tbl_trans 4561 short src_qnan - tbl_trans # $0a-3 fatan qnan 4562 short satand - tbl_trans 4562 short satand - tbl_trans # $0a-5 fatan denorm 4563 short src_snan - tbl_trans 4563 short src_snan - tbl_trans # $0a-4 fatan snan 4564 short tbl_trans - tbl_trans 4564 short tbl_trans - tbl_trans # $0a-6 fatan unnorm 4565 short tbl_trans - tbl_trans 4565 short tbl_trans - tbl_trans # $0a-7 ERROR 4566 4566 4567 short tbl_trans - tbl_trans 4567 short tbl_trans - tbl_trans # $0b-0 ERROR 4568 short tbl_trans - tbl_trans 4568 short tbl_trans - tbl_trans # $0b-1 ERROR 4569 short tbl_trans - tbl_trans 4569 short tbl_trans - tbl_trans # $0b-2 ERROR 4570 short tbl_trans - tbl_trans 4570 short tbl_trans - tbl_trans # $0b-3 ERROR 4571 short tbl_trans - tbl_trans 4571 short tbl_trans - tbl_trans # $0b-4 ERROR 4572 short tbl_trans - tbl_trans 4572 short tbl_trans - tbl_trans # $0b-5 ERROR 4573 short tbl_trans - tbl_trans 4573 short tbl_trans - tbl_trans # $0b-6 ERROR 4574 short tbl_trans - tbl_trans 4574 short tbl_trans - tbl_trans # $0b-7 ERROR 4575 4575 4576 short sasin - tbl_trans 4576 short sasin - tbl_trans # $0c-0 fasin norm 4577 short src_zero - tbl_trans 4577 short src_zero - tbl_trans # $0c-1 fasin zero 4578 short t_operr - tbl_trans 4578 short t_operr - tbl_trans # $0c-2 fasin inf 4579 short src_qnan - tbl_trans 4579 short src_qnan - tbl_trans # $0c-3 fasin qnan 4580 short sasind - tbl_trans 4580 short sasind - tbl_trans # $0c-5 fasin denorm 4581 short src_snan - tbl_trans 4581 short src_snan - tbl_trans # $0c-4 fasin snan 4582 short tbl_trans - tbl_trans 4582 short tbl_trans - tbl_trans # $0c-6 fasin unnorm 4583 short tbl_trans - tbl_trans 4583 short tbl_trans - tbl_trans # $0c-7 ERROR 4584 4584 4585 short satanh - tbl_trans 4585 short satanh - tbl_trans # $0d-0 fatanh norm 4586 short src_zero - tbl_trans 4586 short src_zero - tbl_trans # $0d-1 fatanh zero 4587 short t_operr - tbl_trans 4587 short t_operr - tbl_trans # $0d-2 fatanh inf 4588 short src_qnan - tbl_trans 4588 short src_qnan - tbl_trans # $0d-3 fatanh qnan 4589 short satanhd - tbl_trans 4589 short satanhd - tbl_trans # $0d-5 fatanh denorm 4590 short src_snan - tbl_trans 4590 short src_snan - tbl_trans # $0d-4 fatanh snan 4591 short tbl_trans - tbl_trans 4591 short tbl_trans - tbl_trans # $0d-6 fatanh unnorm 4592 short tbl_trans - tbl_trans 4592 short tbl_trans - tbl_trans # $0d-7 ERROR 4593 4593 4594 short ssin - tbl_trans 4594 short ssin - tbl_trans # $0e-0 fsin norm 4595 short src_zero - tbl_trans 4595 short src_zero - tbl_trans # $0e-1 fsin zero 4596 short t_operr - tbl_trans 4596 short t_operr - tbl_trans # $0e-2 fsin inf 4597 short src_qnan - tbl_trans 4597 short src_qnan - tbl_trans # $0e-3 fsin qnan 4598 short ssind - tbl_trans 4598 short ssind - tbl_trans # $0e-5 fsin denorm 4599 short src_snan - tbl_trans 4599 short src_snan - tbl_trans # $0e-4 fsin snan 4600 short tbl_trans - tbl_trans 4600 short tbl_trans - tbl_trans # $0e-6 fsin unnorm 4601 short tbl_trans - tbl_trans 4601 short tbl_trans - tbl_trans # $0e-7 ERROR 4602 4602 4603 short stan - tbl_trans 4603 short stan - tbl_trans # $0f-0 ftan norm 4604 short src_zero - tbl_trans 4604 short src_zero - tbl_trans # $0f-1 ftan zero 4605 short t_operr - tbl_trans 4605 short t_operr - tbl_trans # $0f-2 ftan inf 4606 short src_qnan - tbl_trans 4606 short src_qnan - tbl_trans # $0f-3 ftan qnan 4607 short stand - tbl_trans 4607 short stand - tbl_trans # $0f-5 ftan denorm 4608 short src_snan - tbl_trans 4608 short src_snan - tbl_trans # $0f-4 ftan snan 4609 short tbl_trans - tbl_trans 4609 short tbl_trans - tbl_trans # $0f-6 ftan unnorm 4610 short tbl_trans - tbl_trans 4610 short tbl_trans - tbl_trans # $0f-7 ERROR 4611 4611 4612 short setox - tbl_trans 4612 short setox - tbl_trans # $10-0 fetox norm 4613 short ld_pone - tbl_trans 4613 short ld_pone - tbl_trans # $10-1 fetox zero 4614 short szr_inf - tbl_trans 4614 short szr_inf - tbl_trans # $10-2 fetox inf 4615 short src_qnan - tbl_trans 4615 short src_qnan - tbl_trans # $10-3 fetox qnan 4616 short setoxd - tbl_trans 4616 short setoxd - tbl_trans # $10-5 fetox denorm 4617 short src_snan - tbl_trans 4617 short src_snan - tbl_trans # $10-4 fetox snan 4618 short tbl_trans - tbl_trans 4618 short tbl_trans - tbl_trans # $10-6 fetox unnorm 4619 short tbl_trans - tbl_trans 4619 short tbl_trans - tbl_trans # $10-7 ERROR 4620 4620 4621 short stwotox - tbl_trans 4621 short stwotox - tbl_trans # $11-0 ftwotox norm 4622 short ld_pone - tbl_trans 4622 short ld_pone - tbl_trans # $11-1 ftwotox zero 4623 short szr_inf - tbl_trans 4623 short szr_inf - tbl_trans # $11-2 ftwotox inf 4624 short src_qnan - tbl_trans 4624 short src_qnan - tbl_trans # $11-3 ftwotox qnan 4625 short stwotoxd - tbl_trans 4625 short stwotoxd - tbl_trans # $11-5 ftwotox denorm 4626 short src_snan - tbl_trans 4626 short src_snan - tbl_trans # $11-4 ftwotox snan 4627 short tbl_trans - tbl_trans 4627 short tbl_trans - tbl_trans # $11-6 ftwotox unnorm 4628 short tbl_trans - tbl_trans 4628 short tbl_trans - tbl_trans # $11-7 ERROR 4629 4629 4630 short stentox - tbl_trans 4630 short stentox - tbl_trans # $12-0 ftentox norm 4631 short ld_pone - tbl_trans 4631 short ld_pone - tbl_trans # $12-1 ftentox zero 4632 short szr_inf - tbl_trans 4632 short szr_inf - tbl_trans # $12-2 ftentox inf 4633 short src_qnan - tbl_trans 4633 short src_qnan - tbl_trans # $12-3 ftentox qnan 4634 short stentoxd - tbl_trans 4634 short stentoxd - tbl_trans # $12-5 ftentox denorm 4635 short src_snan - tbl_trans 4635 short src_snan - tbl_trans # $12-4 ftentox snan 4636 short tbl_trans - tbl_trans 4636 short tbl_trans - tbl_trans # $12-6 ftentox unnorm 4637 short tbl_trans - tbl_trans 4637 short tbl_trans - tbl_trans # $12-7 ERROR 4638 4638 4639 short tbl_trans - tbl_trans 4639 short tbl_trans - tbl_trans # $13-0 ERROR 4640 short tbl_trans - tbl_trans 4640 short tbl_trans - tbl_trans # $13-1 ERROR 4641 short tbl_trans - tbl_trans 4641 short tbl_trans - tbl_trans # $13-2 ERROR 4642 short tbl_trans - tbl_trans 4642 short tbl_trans - tbl_trans # $13-3 ERROR 4643 short tbl_trans - tbl_trans 4643 short tbl_trans - tbl_trans # $13-4 ERROR 4644 short tbl_trans - tbl_trans 4644 short tbl_trans - tbl_trans # $13-5 ERROR 4645 short tbl_trans - tbl_trans 4645 short tbl_trans - tbl_trans # $13-6 ERROR 4646 short tbl_trans - tbl_trans 4646 short tbl_trans - tbl_trans # $13-7 ERROR 4647 4647 4648 short slogn - tbl_trans 4648 short slogn - tbl_trans # $14-0 flogn norm 4649 short t_dz2 - tbl_trans 4649 short t_dz2 - tbl_trans # $14-1 flogn zero 4650 short sopr_inf - tbl_trans 4650 short sopr_inf - tbl_trans # $14-2 flogn inf 4651 short src_qnan - tbl_trans 4651 short src_qnan - tbl_trans # $14-3 flogn qnan 4652 short slognd - tbl_trans 4652 short slognd - tbl_trans # $14-5 flogn denorm 4653 short src_snan - tbl_trans 4653 short src_snan - tbl_trans # $14-4 flogn snan 4654 short tbl_trans - tbl_trans 4654 short tbl_trans - tbl_trans # $14-6 flogn unnorm 4655 short tbl_trans - tbl_trans 4655 short tbl_trans - tbl_trans # $14-7 ERROR 4656 4656 4657 short slog10 - tbl_trans 4657 short slog10 - tbl_trans # $15-0 flog10 norm 4658 short t_dz2 - tbl_trans 4658 short t_dz2 - tbl_trans # $15-1 flog10 zero 4659 short sopr_inf - tbl_trans 4659 short sopr_inf - tbl_trans # $15-2 flog10 inf 4660 short src_qnan - tbl_trans 4660 short src_qnan - tbl_trans # $15-3 flog10 qnan 4661 short slog10d - tbl_trans 4661 short slog10d - tbl_trans # $15-5 flog10 denorm 4662 short src_snan - tbl_trans 4662 short src_snan - tbl_trans # $15-4 flog10 snan 4663 short tbl_trans - tbl_trans 4663 short tbl_trans - tbl_trans # $15-6 flog10 unnorm 4664 short tbl_trans - tbl_trans 4664 short tbl_trans - tbl_trans # $15-7 ERROR 4665 4665 4666 short slog2 - tbl_trans 4666 short slog2 - tbl_trans # $16-0 flog2 norm 4667 short t_dz2 - tbl_trans 4667 short t_dz2 - tbl_trans # $16-1 flog2 zero 4668 short sopr_inf - tbl_trans 4668 short sopr_inf - tbl_trans # $16-2 flog2 inf 4669 short src_qnan - tbl_trans 4669 short src_qnan - tbl_trans # $16-3 flog2 qnan 4670 short slog2d - tbl_trans 4670 short slog2d - tbl_trans # $16-5 flog2 denorm 4671 short src_snan - tbl_trans 4671 short src_snan - tbl_trans # $16-4 flog2 snan 4672 short tbl_trans - tbl_trans 4672 short tbl_trans - tbl_trans # $16-6 flog2 unnorm 4673 short tbl_trans - tbl_trans 4673 short tbl_trans - tbl_trans # $16-7 ERROR 4674 4674 4675 short tbl_trans - tbl_trans 4675 short tbl_trans - tbl_trans # $17-0 ERROR 4676 short tbl_trans - tbl_trans 4676 short tbl_trans - tbl_trans # $17-1 ERROR 4677 short tbl_trans - tbl_trans 4677 short tbl_trans - tbl_trans # $17-2 ERROR 4678 short tbl_trans - tbl_trans 4678 short tbl_trans - tbl_trans # $17-3 ERROR 4679 short tbl_trans - tbl_trans 4679 short tbl_trans - tbl_trans # $17-4 ERROR 4680 short tbl_trans - tbl_trans 4680 short tbl_trans - tbl_trans # $17-5 ERROR 4681 short tbl_trans - tbl_trans 4681 short tbl_trans - tbl_trans # $17-6 ERROR 4682 short tbl_trans - tbl_trans 4682 short tbl_trans - tbl_trans # $17-7 ERROR 4683 4683 4684 short tbl_trans - tbl_trans 4684 short tbl_trans - tbl_trans # $18-0 fabs norm 4685 short tbl_trans - tbl_trans 4685 short tbl_trans - tbl_trans # $18-1 fabs zero 4686 short tbl_trans - tbl_trans 4686 short tbl_trans - tbl_trans # $18-2 fabs inf 4687 short tbl_trans - tbl_trans 4687 short tbl_trans - tbl_trans # $18-3 fabs qnan 4688 short tbl_trans - tbl_trans 4688 short tbl_trans - tbl_trans # $18-5 fabs denorm 4689 short tbl_trans - tbl_trans 4689 short tbl_trans - tbl_trans # $18-4 fabs snan 4690 short tbl_trans - tbl_trans 4690 short tbl_trans - tbl_trans # $18-6 fabs unnorm 4691 short tbl_trans - tbl_trans 4691 short tbl_trans - tbl_trans # $18-7 ERROR 4692 4692 4693 short scosh - tbl_trans 4693 short scosh - tbl_trans # $19-0 fcosh norm 4694 short ld_pone - tbl_trans 4694 short ld_pone - tbl_trans # $19-1 fcosh zero 4695 short ld_pinf - tbl_trans 4695 short ld_pinf - tbl_trans # $19-2 fcosh inf 4696 short src_qnan - tbl_trans 4696 short src_qnan - tbl_trans # $19-3 fcosh qnan 4697 short scoshd - tbl_trans 4697 short scoshd - tbl_trans # $19-5 fcosh denorm 4698 short src_snan - tbl_trans 4698 short src_snan - tbl_trans # $19-4 fcosh snan 4699 short tbl_trans - tbl_trans 4699 short tbl_trans - tbl_trans # $19-6 fcosh unnorm 4700 short tbl_trans - tbl_trans 4700 short tbl_trans - tbl_trans # $19-7 ERROR 4701 4701 4702 short tbl_trans - tbl_trans 4702 short tbl_trans - tbl_trans # $1a-0 fneg norm 4703 short tbl_trans - tbl_trans 4703 short tbl_trans - tbl_trans # $1a-1 fneg zero 4704 short tbl_trans - tbl_trans 4704 short tbl_trans - tbl_trans # $1a-2 fneg inf 4705 short tbl_trans - tbl_trans 4705 short tbl_trans - tbl_trans # $1a-3 fneg qnan 4706 short tbl_trans - tbl_trans 4706 short tbl_trans - tbl_trans # $1a-5 fneg denorm 4707 short tbl_trans - tbl_trans 4707 short tbl_trans - tbl_trans # $1a-4 fneg snan 4708 short tbl_trans - tbl_trans 4708 short tbl_trans - tbl_trans # $1a-6 fneg unnorm 4709 short tbl_trans - tbl_trans 4709 short tbl_trans - tbl_trans # $1a-7 ERROR 4710 4710 4711 short tbl_trans - tbl_trans 4711 short tbl_trans - tbl_trans # $1b-0 ERROR 4712 short tbl_trans - tbl_trans 4712 short tbl_trans - tbl_trans # $1b-1 ERROR 4713 short tbl_trans - tbl_trans 4713 short tbl_trans - tbl_trans # $1b-2 ERROR 4714 short tbl_trans - tbl_trans 4714 short tbl_trans - tbl_trans # $1b-3 ERROR 4715 short tbl_trans - tbl_trans 4715 short tbl_trans - tbl_trans # $1b-4 ERROR 4716 short tbl_trans - tbl_trans 4716 short tbl_trans - tbl_trans # $1b-5 ERROR 4717 short tbl_trans - tbl_trans 4717 short tbl_trans - tbl_trans # $1b-6 ERROR 4718 short tbl_trans - tbl_trans 4718 short tbl_trans - tbl_trans # $1b-7 ERROR 4719 4719 4720 short sacos - tbl_trans 4720 short sacos - tbl_trans # $1c-0 facos norm 4721 short ld_ppi2 - tbl_trans 4721 short ld_ppi2 - tbl_trans # $1c-1 facos zero 4722 short t_operr - tbl_trans 4722 short t_operr - tbl_trans # $1c-2 facos inf 4723 short src_qnan - tbl_trans 4723 short src_qnan - tbl_trans # $1c-3 facos qnan 4724 short sacosd - tbl_trans 4724 short sacosd - tbl_trans # $1c-5 facos denorm 4725 short src_snan - tbl_trans 4725 short src_snan - tbl_trans # $1c-4 facos snan 4726 short tbl_trans - tbl_trans 4726 short tbl_trans - tbl_trans # $1c-6 facos unnorm 4727 short tbl_trans - tbl_trans 4727 short tbl_trans - tbl_trans # $1c-7 ERROR 4728 4728 4729 short scos - tbl_trans 4729 short scos - tbl_trans # $1d-0 fcos norm 4730 short ld_pone - tbl_trans 4730 short ld_pone - tbl_trans # $1d-1 fcos zero 4731 short t_operr - tbl_trans 4731 short t_operr - tbl_trans # $1d-2 fcos inf 4732 short src_qnan - tbl_trans 4732 short src_qnan - tbl_trans # $1d-3 fcos qnan 4733 short scosd - tbl_trans 4733 short scosd - tbl_trans # $1d-5 fcos denorm 4734 short src_snan - tbl_trans 4734 short src_snan - tbl_trans # $1d-4 fcos snan 4735 short tbl_trans - tbl_trans 4735 short tbl_trans - tbl_trans # $1d-6 fcos unnorm 4736 short tbl_trans - tbl_trans 4736 short tbl_trans - tbl_trans # $1d-7 ERROR 4737 4737 4738 short sgetexp - tbl_trans 4738 short sgetexp - tbl_trans # $1e-0 fgetexp norm 4739 short src_zero - tbl_trans 4739 short src_zero - tbl_trans # $1e-1 fgetexp zero 4740 short t_operr - tbl_trans 4740 short t_operr - tbl_trans # $1e-2 fgetexp inf 4741 short src_qnan - tbl_trans 4741 short src_qnan - tbl_trans # $1e-3 fgetexp qnan 4742 short sgetexpd - tbl_trans 4742 short sgetexpd - tbl_trans # $1e-5 fgetexp denorm 4743 short src_snan - tbl_trans 4743 short src_snan - tbl_trans # $1e-4 fgetexp snan 4744 short tbl_trans - tbl_trans 4744 short tbl_trans - tbl_trans # $1e-6 fgetexp unnorm 4745 short tbl_trans - tbl_trans 4745 short tbl_trans - tbl_trans # $1e-7 ERROR 4746 4746 4747 short sgetman - tbl_trans 4747 short sgetman - tbl_trans # $1f-0 fgetman norm 4748 short src_zero - tbl_trans 4748 short src_zero - tbl_trans # $1f-1 fgetman zero 4749 short t_operr - tbl_trans 4749 short t_operr - tbl_trans # $1f-2 fgetman inf 4750 short src_qnan - tbl_trans 4750 short src_qnan - tbl_trans # $1f-3 fgetman qnan 4751 short sgetmand - tbl_trans 4751 short sgetmand - tbl_trans # $1f-5 fgetman denorm 4752 short src_snan - tbl_trans 4752 short src_snan - tbl_trans # $1f-4 fgetman snan 4753 short tbl_trans - tbl_trans 4753 short tbl_trans - tbl_trans # $1f-6 fgetman unnorm 4754 short tbl_trans - tbl_trans 4754 short tbl_trans - tbl_trans # $1f-7 ERROR 4755 4755 4756 short tbl_trans - tbl_trans 4756 short tbl_trans - tbl_trans # $20-0 fdiv norm 4757 short tbl_trans - tbl_trans 4757 short tbl_trans - tbl_trans # $20-1 fdiv zero 4758 short tbl_trans - tbl_trans 4758 short tbl_trans - tbl_trans # $20-2 fdiv inf 4759 short tbl_trans - tbl_trans 4759 short tbl_trans - tbl_trans # $20-3 fdiv qnan 4760 short tbl_trans - tbl_trans 4760 short tbl_trans - tbl_trans # $20-5 fdiv denorm 4761 short tbl_trans - tbl_trans 4761 short tbl_trans - tbl_trans # $20-4 fdiv snan 4762 short tbl_trans - tbl_trans 4762 short tbl_trans - tbl_trans # $20-6 fdiv unnorm 4763 short tbl_trans - tbl_trans 4763 short tbl_trans - tbl_trans # $20-7 ERROR 4764 4764 4765 short smod_snorm - tbl_tran 4765 short smod_snorm - tbl_trans # $21-0 fmod norm 4766 short smod_szero - tbl_tran 4766 short smod_szero - tbl_trans # $21-1 fmod zero 4767 short smod_sinf - tbl_trans 4767 short smod_sinf - tbl_trans # $21-2 fmod inf 4768 short sop_sqnan - tbl_trans 4768 short sop_sqnan - tbl_trans # $21-3 fmod qnan 4769 short smod_sdnrm - tbl_tran 4769 short smod_sdnrm - tbl_trans # $21-5 fmod denorm 4770 short sop_ssnan - tbl_trans 4770 short sop_ssnan - tbl_trans # $21-4 fmod snan 4771 short tbl_trans - tbl_trans 4771 short tbl_trans - tbl_trans # $21-6 fmod unnorm 4772 short tbl_trans - tbl_trans 4772 short tbl_trans - tbl_trans # $21-7 ERROR 4773 4773 4774 short tbl_trans - tbl_trans 4774 short tbl_trans - tbl_trans # $22-0 fadd norm 4775 short tbl_trans - tbl_trans 4775 short tbl_trans - tbl_trans # $22-1 fadd zero 4776 short tbl_trans - tbl_trans 4776 short tbl_trans - tbl_trans # $22-2 fadd inf 4777 short tbl_trans - tbl_trans 4777 short tbl_trans - tbl_trans # $22-3 fadd qnan 4778 short tbl_trans - tbl_trans 4778 short tbl_trans - tbl_trans # $22-5 fadd denorm 4779 short tbl_trans - tbl_trans 4779 short tbl_trans - tbl_trans # $22-4 fadd snan 4780 short tbl_trans - tbl_trans 4780 short tbl_trans - tbl_trans # $22-6 fadd unnorm 4781 short tbl_trans - tbl_trans 4781 short tbl_trans - tbl_trans # $22-7 ERROR 4782 4782 4783 short tbl_trans - tbl_trans 4783 short tbl_trans - tbl_trans # $23-0 fmul norm 4784 short tbl_trans - tbl_trans 4784 short tbl_trans - tbl_trans # $23-1 fmul zero 4785 short tbl_trans - tbl_trans 4785 short tbl_trans - tbl_trans # $23-2 fmul inf 4786 short tbl_trans - tbl_trans 4786 short tbl_trans - tbl_trans # $23-3 fmul qnan 4787 short tbl_trans - tbl_trans 4787 short tbl_trans - tbl_trans # $23-5 fmul denorm 4788 short tbl_trans - tbl_trans 4788 short tbl_trans - tbl_trans # $23-4 fmul snan 4789 short tbl_trans - tbl_trans 4789 short tbl_trans - tbl_trans # $23-6 fmul unnorm 4790 short tbl_trans - tbl_trans 4790 short tbl_trans - tbl_trans # $23-7 ERROR 4791 4791 4792 short tbl_trans - tbl_trans 4792 short tbl_trans - tbl_trans # $24-0 fsgldiv norm 4793 short tbl_trans - tbl_trans 4793 short tbl_trans - tbl_trans # $24-1 fsgldiv zero 4794 short tbl_trans - tbl_trans 4794 short tbl_trans - tbl_trans # $24-2 fsgldiv inf 4795 short tbl_trans - tbl_trans 4795 short tbl_trans - tbl_trans # $24-3 fsgldiv qnan 4796 short tbl_trans - tbl_trans 4796 short tbl_trans - tbl_trans # $24-5 fsgldiv denorm 4797 short tbl_trans - tbl_trans 4797 short tbl_trans - tbl_trans # $24-4 fsgldiv snan 4798 short tbl_trans - tbl_trans 4798 short tbl_trans - tbl_trans # $24-6 fsgldiv unnorm 4799 short tbl_trans - tbl_trans 4799 short tbl_trans - tbl_trans # $24-7 ERROR 4800 4800 4801 short srem_snorm - tbl_tran 4801 short srem_snorm - tbl_trans # $25-0 frem norm 4802 short srem_szero - tbl_tran 4802 short srem_szero - tbl_trans # $25-1 frem zero 4803 short srem_sinf - tbl_trans 4803 short srem_sinf - tbl_trans # $25-2 frem inf 4804 short sop_sqnan - tbl_trans 4804 short sop_sqnan - tbl_trans # $25-3 frem qnan 4805 short srem_sdnrm - tbl_tran 4805 short srem_sdnrm - tbl_trans # $25-5 frem denorm 4806 short sop_ssnan - tbl_trans 4806 short sop_ssnan - tbl_trans # $25-4 frem snan 4807 short tbl_trans - tbl_trans 4807 short tbl_trans - tbl_trans # $25-6 frem unnorm 4808 short tbl_trans - tbl_trans 4808 short tbl_trans - tbl_trans # $25-7 ERROR 4809 4809 4810 short sscale_snorm - tbl_tr 4810 short sscale_snorm - tbl_trans # $26-0 fscale norm 4811 short sscale_szero - tbl_tr 4811 short sscale_szero - tbl_trans # $26-1 fscale zero 4812 short sscale_sinf - tbl_tra 4812 short sscale_sinf - tbl_trans # $26-2 fscale inf 4813 short sop_sqnan - tbl_trans 4813 short sop_sqnan - tbl_trans # $26-3 fscale qnan 4814 short sscale_sdnrm - tbl_tr 4814 short sscale_sdnrm - tbl_trans # $26-5 fscale denorm 4815 short sop_ssnan - tbl_trans 4815 short sop_ssnan - tbl_trans # $26-4 fscale snan 4816 short tbl_trans - tbl_trans 4816 short tbl_trans - tbl_trans # $26-6 fscale unnorm 4817 short tbl_trans - tbl_trans 4817 short tbl_trans - tbl_trans # $26-7 ERROR 4818 4818 4819 short tbl_trans - tbl_trans 4819 short tbl_trans - tbl_trans # $27-0 fsglmul norm 4820 short tbl_trans - tbl_trans 4820 short tbl_trans - tbl_trans # $27-1 fsglmul zero 4821 short tbl_trans - tbl_trans 4821 short tbl_trans - tbl_trans # $27-2 fsglmul inf 4822 short tbl_trans - tbl_trans 4822 short tbl_trans - tbl_trans # $27-3 fsglmul qnan 4823 short tbl_trans - tbl_trans 4823 short tbl_trans - tbl_trans # $27-5 fsglmul denorm 4824 short tbl_trans - tbl_trans 4824 short tbl_trans - tbl_trans # $27-4 fsglmul snan 4825 short tbl_trans - tbl_trans 4825 short tbl_trans - tbl_trans # $27-6 fsglmul unnorm 4826 short tbl_trans - tbl_trans 4826 short tbl_trans - tbl_trans # $27-7 ERROR 4827 4827 4828 short tbl_trans - tbl_trans 4828 short tbl_trans - tbl_trans # $28-0 fsub norm 4829 short tbl_trans - tbl_trans 4829 short tbl_trans - tbl_trans # $28-1 fsub zero 4830 short tbl_trans - tbl_trans 4830 short tbl_trans - tbl_trans # $28-2 fsub inf 4831 short tbl_trans - tbl_trans 4831 short tbl_trans - tbl_trans # $28-3 fsub qnan 4832 short tbl_trans - tbl_trans 4832 short tbl_trans - tbl_trans # $28-5 fsub denorm 4833 short tbl_trans - tbl_trans 4833 short tbl_trans - tbl_trans # $28-4 fsub snan 4834 short tbl_trans - tbl_trans 4834 short tbl_trans - tbl_trans # $28-6 fsub unnorm 4835 short tbl_trans - tbl_trans 4835 short tbl_trans - tbl_trans # $28-7 ERROR 4836 4836 4837 short tbl_trans - tbl_trans 4837 short tbl_trans - tbl_trans # $29-0 ERROR 4838 short tbl_trans - tbl_trans 4838 short tbl_trans - tbl_trans # $29-1 ERROR 4839 short tbl_trans - tbl_trans 4839 short tbl_trans - tbl_trans # $29-2 ERROR 4840 short tbl_trans - tbl_trans 4840 short tbl_trans - tbl_trans # $29-3 ERROR 4841 short tbl_trans - tbl_trans 4841 short tbl_trans - tbl_trans # $29-4 ERROR 4842 short tbl_trans - tbl_trans 4842 short tbl_trans - tbl_trans # $29-5 ERROR 4843 short tbl_trans - tbl_trans 4843 short tbl_trans - tbl_trans # $29-6 ERROR 4844 short tbl_trans - tbl_trans 4844 short tbl_trans - tbl_trans # $29-7 ERROR 4845 4845 4846 short tbl_trans - tbl_trans 4846 short tbl_trans - tbl_trans # $2a-0 ERROR 4847 short tbl_trans - tbl_trans 4847 short tbl_trans - tbl_trans # $2a-1 ERROR 4848 short tbl_trans - tbl_trans 4848 short tbl_trans - tbl_trans # $2a-2 ERROR 4849 short tbl_trans - tbl_trans 4849 short tbl_trans - tbl_trans # $2a-3 ERROR 4850 short tbl_trans - tbl_trans 4850 short tbl_trans - tbl_trans # $2a-4 ERROR 4851 short tbl_trans - tbl_trans 4851 short tbl_trans - tbl_trans # $2a-5 ERROR 4852 short tbl_trans - tbl_trans 4852 short tbl_trans - tbl_trans # $2a-6 ERROR 4853 short tbl_trans - tbl_trans 4853 short tbl_trans - tbl_trans # $2a-7 ERROR 4854 4854 4855 short tbl_trans - tbl_trans 4855 short tbl_trans - tbl_trans # $2b-0 ERROR 4856 short tbl_trans - tbl_trans 4856 short tbl_trans - tbl_trans # $2b-1 ERROR 4857 short tbl_trans - tbl_trans 4857 short tbl_trans - tbl_trans # $2b-2 ERROR 4858 short tbl_trans - tbl_trans 4858 short tbl_trans - tbl_trans # $2b-3 ERROR 4859 short tbl_trans - tbl_trans 4859 short tbl_trans - tbl_trans # $2b-4 ERROR 4860 short tbl_trans - tbl_trans 4860 short tbl_trans - tbl_trans # $2b-5 ERROR 4861 short tbl_trans - tbl_trans 4861 short tbl_trans - tbl_trans # $2b-6 ERROR 4862 short tbl_trans - tbl_trans 4862 short tbl_trans - tbl_trans # $2b-7 ERROR 4863 4863 4864 short tbl_trans - tbl_trans 4864 short tbl_trans - tbl_trans # $2c-0 ERROR 4865 short tbl_trans - tbl_trans 4865 short tbl_trans - tbl_trans # $2c-1 ERROR 4866 short tbl_trans - tbl_trans 4866 short tbl_trans - tbl_trans # $2c-2 ERROR 4867 short tbl_trans - tbl_trans 4867 short tbl_trans - tbl_trans # $2c-3 ERROR 4868 short tbl_trans - tbl_trans 4868 short tbl_trans - tbl_trans # $2c-4 ERROR 4869 short tbl_trans - tbl_trans 4869 short tbl_trans - tbl_trans # $2c-5 ERROR 4870 short tbl_trans - tbl_trans 4870 short tbl_trans - tbl_trans # $2c-6 ERROR 4871 short tbl_trans - tbl_trans 4871 short tbl_trans - tbl_trans # $2c-7 ERROR 4872 4872 4873 short tbl_trans - tbl_trans 4873 short tbl_trans - tbl_trans # $2d-0 ERROR 4874 short tbl_trans - tbl_trans 4874 short tbl_trans - tbl_trans # $2d-1 ERROR 4875 short tbl_trans - tbl_trans 4875 short tbl_trans - tbl_trans # $2d-2 ERROR 4876 short tbl_trans - tbl_trans 4876 short tbl_trans - tbl_trans # $2d-3 ERROR 4877 short tbl_trans - tbl_trans 4877 short tbl_trans - tbl_trans # $2d-4 ERROR 4878 short tbl_trans - tbl_trans 4878 short tbl_trans - tbl_trans # $2d-5 ERROR 4879 short tbl_trans - tbl_trans 4879 short tbl_trans - tbl_trans # $2d-6 ERROR 4880 short tbl_trans - tbl_trans 4880 short tbl_trans - tbl_trans # $2d-7 ERROR 4881 4881 4882 short tbl_trans - tbl_trans 4882 short tbl_trans - tbl_trans # $2e-0 ERROR 4883 short tbl_trans - tbl_trans 4883 short tbl_trans - tbl_trans # $2e-1 ERROR 4884 short tbl_trans - tbl_trans 4884 short tbl_trans - tbl_trans # $2e-2 ERROR 4885 short tbl_trans - tbl_trans 4885 short tbl_trans - tbl_trans # $2e-3 ERROR 4886 short tbl_trans - tbl_trans 4886 short tbl_trans - tbl_trans # $2e-4 ERROR 4887 short tbl_trans - tbl_trans 4887 short tbl_trans - tbl_trans # $2e-5 ERROR 4888 short tbl_trans - tbl_trans 4888 short tbl_trans - tbl_trans # $2e-6 ERROR 4889 short tbl_trans - tbl_trans 4889 short tbl_trans - tbl_trans # $2e-7 ERROR 4890 4890 4891 short tbl_trans - tbl_trans 4891 short tbl_trans - tbl_trans # $2f-0 ERROR 4892 short tbl_trans - tbl_trans 4892 short tbl_trans - tbl_trans # $2f-1 ERROR 4893 short tbl_trans - tbl_trans 4893 short tbl_trans - tbl_trans # $2f-2 ERROR 4894 short tbl_trans - tbl_trans 4894 short tbl_trans - tbl_trans # $2f-3 ERROR 4895 short tbl_trans - tbl_trans 4895 short tbl_trans - tbl_trans # $2f-4 ERROR 4896 short tbl_trans - tbl_trans 4896 short tbl_trans - tbl_trans # $2f-5 ERROR 4897 short tbl_trans - tbl_trans 4897 short tbl_trans - tbl_trans # $2f-6 ERROR 4898 short tbl_trans - tbl_trans 4898 short tbl_trans - tbl_trans # $2f-7 ERROR 4899 4899 4900 short ssincos - tbl_trans 4900 short ssincos - tbl_trans # $30-0 fsincos norm 4901 short ssincosz - tbl_trans 4901 short ssincosz - tbl_trans # $30-1 fsincos zero 4902 short ssincosi - tbl_trans 4902 short ssincosi - tbl_trans # $30-2 fsincos inf 4903 short ssincosqnan - tbl_tra 4903 short ssincosqnan - tbl_trans # $30-3 fsincos qnan 4904 short ssincosd - tbl_trans 4904 short ssincosd - tbl_trans # $30-5 fsincos denorm 4905 short ssincossnan - tbl_tra 4905 short ssincossnan - tbl_trans # $30-4 fsincos snan 4906 short tbl_trans - tbl_trans 4906 short tbl_trans - tbl_trans # $30-6 fsincos unnorm 4907 short tbl_trans - tbl_trans 4907 short tbl_trans - tbl_trans # $30-7 ERROR 4908 4908 4909 short ssincos - tbl_trans 4909 short ssincos - tbl_trans # $31-0 fsincos norm 4910 short ssincosz - tbl_trans 4910 short ssincosz - tbl_trans # $31-1 fsincos zero 4911 short ssincosi - tbl_trans 4911 short ssincosi - tbl_trans # $31-2 fsincos inf 4912 short ssincosqnan - tbl_tra 4912 short ssincosqnan - tbl_trans # $31-3 fsincos qnan 4913 short ssincosd - tbl_trans 4913 short ssincosd - tbl_trans # $31-5 fsincos denorm 4914 short ssincossnan - tbl_tra 4914 short ssincossnan - tbl_trans # $31-4 fsincos snan 4915 short tbl_trans - tbl_trans 4915 short tbl_trans - tbl_trans # $31-6 fsincos unnorm 4916 short tbl_trans - tbl_trans 4916 short tbl_trans - tbl_trans # $31-7 ERROR 4917 4917 4918 short ssincos - tbl_trans 4918 short ssincos - tbl_trans # $32-0 fsincos norm 4919 short ssincosz - tbl_trans 4919 short ssincosz - tbl_trans # $32-1 fsincos zero 4920 short ssincosi - tbl_trans 4920 short ssincosi - tbl_trans # $32-2 fsincos inf 4921 short ssincosqnan - tbl_tra 4921 short ssincosqnan - tbl_trans # $32-3 fsincos qnan 4922 short ssincosd - tbl_trans 4922 short ssincosd - tbl_trans # $32-5 fsincos denorm 4923 short ssincossnan - tbl_tra 4923 short ssincossnan - tbl_trans # $32-4 fsincos snan 4924 short tbl_trans - tbl_trans 4924 short tbl_trans - tbl_trans # $32-6 fsincos unnorm 4925 short tbl_trans - tbl_trans 4925 short tbl_trans - tbl_trans # $32-7 ERROR 4926 4926 4927 short ssincos - tbl_trans 4927 short ssincos - tbl_trans # $33-0 fsincos norm 4928 short ssincosz - tbl_trans 4928 short ssincosz - tbl_trans # $33-1 fsincos zero 4929 short ssincosi - tbl_trans 4929 short ssincosi - tbl_trans # $33-2 fsincos inf 4930 short ssincosqnan - tbl_tra 4930 short ssincosqnan - tbl_trans # $33-3 fsincos qnan 4931 short ssincosd - tbl_trans 4931 short ssincosd - tbl_trans # $33-5 fsincos denorm 4932 short ssincossnan - tbl_tra 4932 short ssincossnan - tbl_trans # $33-4 fsincos snan 4933 short tbl_trans - tbl_trans 4933 short tbl_trans - tbl_trans # $33-6 fsincos unnorm 4934 short tbl_trans - tbl_trans 4934 short tbl_trans - tbl_trans # $33-7 ERROR 4935 4935 4936 short ssincos - tbl_trans 4936 short ssincos - tbl_trans # $34-0 fsincos norm 4937 short ssincosz - tbl_trans 4937 short ssincosz - tbl_trans # $34-1 fsincos zero 4938 short ssincosi - tbl_trans 4938 short ssincosi - tbl_trans # $34-2 fsincos inf 4939 short ssincosqnan - tbl_tra 4939 short ssincosqnan - tbl_trans # $34-3 fsincos qnan 4940 short ssincosd - tbl_trans 4940 short ssincosd - tbl_trans # $34-5 fsincos denorm 4941 short ssincossnan - tbl_tra 4941 short ssincossnan - tbl_trans # $34-4 fsincos snan 4942 short tbl_trans - tbl_trans 4942 short tbl_trans - tbl_trans # $34-6 fsincos unnorm 4943 short tbl_trans - tbl_trans 4943 short tbl_trans - tbl_trans # $34-7 ERROR 4944 4944 4945 short ssincos - tbl_trans 4945 short ssincos - tbl_trans # $35-0 fsincos norm 4946 short ssincosz - tbl_trans 4946 short ssincosz - tbl_trans # $35-1 fsincos zero 4947 short ssincosi - tbl_trans 4947 short ssincosi - tbl_trans # $35-2 fsincos inf 4948 short ssincosqnan - tbl_tra 4948 short ssincosqnan - tbl_trans # $35-3 fsincos qnan 4949 short ssincosd - tbl_trans 4949 short ssincosd - tbl_trans # $35-5 fsincos denorm 4950 short ssincossnan - tbl_tra 4950 short ssincossnan - tbl_trans # $35-4 fsincos snan 4951 short tbl_trans - tbl_trans 4951 short tbl_trans - tbl_trans # $35-6 fsincos unnorm 4952 short tbl_trans - tbl_trans 4952 short tbl_trans - tbl_trans # $35-7 ERROR 4953 4953 4954 short ssincos - tbl_trans 4954 short ssincos - tbl_trans # $36-0 fsincos norm 4955 short ssincosz - tbl_trans 4955 short ssincosz - tbl_trans # $36-1 fsincos zero 4956 short ssincosi - tbl_trans 4956 short ssincosi - tbl_trans # $36-2 fsincos inf 4957 short ssincosqnan - tbl_tra 4957 short ssincosqnan - tbl_trans # $36-3 fsincos qnan 4958 short ssincosd - tbl_trans 4958 short ssincosd - tbl_trans # $36-5 fsincos denorm 4959 short ssincossnan - tbl_tra 4959 short ssincossnan - tbl_trans # $36-4 fsincos snan 4960 short tbl_trans - tbl_trans 4960 short tbl_trans - tbl_trans # $36-6 fsincos unnorm 4961 short tbl_trans - tbl_trans 4961 short tbl_trans - tbl_trans # $36-7 ERROR 4962 4962 4963 short ssincos - tbl_trans 4963 short ssincos - tbl_trans # $37-0 fsincos norm 4964 short ssincosz - tbl_trans 4964 short ssincosz - tbl_trans # $37-1 fsincos zero 4965 short ssincosi - tbl_trans 4965 short ssincosi - tbl_trans # $37-2 fsincos inf 4966 short ssincosqnan - tbl_tra 4966 short ssincosqnan - tbl_trans # $37-3 fsincos qnan 4967 short ssincosd - tbl_trans 4967 short ssincosd - tbl_trans # $37-5 fsincos denorm 4968 short ssincossnan - tbl_tra 4968 short ssincossnan - tbl_trans # $37-4 fsincos snan 4969 short tbl_trans - tbl_trans 4969 short tbl_trans - tbl_trans # $37-6 fsincos unnorm 4970 short tbl_trans - tbl_trans 4970 short tbl_trans - tbl_trans # $37-7 ERROR 4971 4971 4972 ########## 4972 ########## 4973 4973 4974 # the instruction fetch access for the displa 4974 # the instruction fetch access for the displacement word for the 4975 # fdbcc emulation failed. here, we create an 4975 # fdbcc emulation failed. here, we create an access error frame 4976 # from the current frame and branch to _real_ 4976 # from the current frame and branch to _real_access(). 4977 funimp_iacc: 4977 funimp_iacc: 4978 movm.l EXC_DREGS(%a6),&0x030 4978 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 4979 fmovm.l USER_FPCR(%a6),%fpcr, 4979 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 4980 fmovm.x EXC_FPREGS(%a6),&0xc0 4980 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 4981 4981 4982 mov.l USER_FPIAR(%a6),EXC_P 4982 mov.l USER_FPIAR(%a6),EXC_PC(%a6) # store current PC 4983 4983 4984 unlk %a6 4984 unlk %a6 4985 4985 4986 mov.l (%sp),-(%sp) 4986 mov.l (%sp),-(%sp) # store SR,hi(PC) 4987 mov.w 0x8(%sp),0x4(%sp) 4987 mov.w 0x8(%sp),0x4(%sp) # store lo(PC) 4988 mov.w &0x4008,0x6(%sp) 4988 mov.w &0x4008,0x6(%sp) # store voff 4989 mov.l 0x2(%sp),0x8(%sp) 4989 mov.l 0x2(%sp),0x8(%sp) # store EA 4990 mov.l &0x09428001,0xc(%sp) 4990 mov.l &0x09428001,0xc(%sp) # store FSLW 4991 4991 4992 btst &0x5,(%sp) 4992 btst &0x5,(%sp) # user or supervisor mode? 4993 beq.b funimp_iacc_end 4993 beq.b funimp_iacc_end # user 4994 bset &0x2,0xd(%sp) 4994 bset &0x2,0xd(%sp) # set supervisor TM bit 4995 4995 4996 funimp_iacc_end: 4996 funimp_iacc_end: 4997 bra.l _real_access 4997 bra.l _real_access 4998 4998 4999 ############################################# 4999 ######################################################################### 5000 # ssin(): computes the sine of a normaliz 5000 # ssin(): computes the sine of a normalized input # 5001 # ssind(): computes the sine of a denormal 5001 # ssind(): computes the sine of a denormalized input # 5002 # scos(): computes the cosine of a normal 5002 # scos(): computes the cosine of a normalized input # 5003 # scosd(): computes the cosine of a denorm 5003 # scosd(): computes the cosine of a denormalized input # 5004 # ssincos(): computes the sine and cosine of 5004 # ssincos(): computes the sine and cosine of a normalized input # 5005 # ssincosd(): computes the sine and cosine of 5005 # ssincosd(): computes the sine and cosine of a denormalized input # 5006 # 5006 # # 5007 # INPUT ************************************* 5007 # INPUT *************************************************************** # 5008 # a0 = pointer to extended precision in 5008 # a0 = pointer to extended precision input # 5009 # d0 = round precision,mode 5009 # d0 = round precision,mode # 5010 # 5010 # # 5011 # OUTPUT ************************************ 5011 # OUTPUT ************************************************************** # 5012 # fp0 = sin(X) or cos(X) 5012 # fp0 = sin(X) or cos(X) # 5013 # 5013 # # 5014 # For ssincos(X): 5014 # For ssincos(X): # 5015 # fp0 = sin(X) 5015 # fp0 = sin(X) # 5016 # fp1 = cos(X) 5016 # fp1 = cos(X) # 5017 # 5017 # # 5018 # ACCURACY and MONOTONICITY ***************** 5018 # ACCURACY and MONOTONICITY ******************************************* # 5019 # The returned result is within 1 ulp i 5019 # The returned result is within 1 ulp in 64 significant bit, i.e. # 5020 # within 0.5001 ulp to 53 bits if the r 5020 # within 0.5001 ulp to 53 bits if the result is subsequently # 5021 # rounded to double precision. The resu 5021 # rounded to double precision. The result is provably monotonic # 5022 # in double precision. 5022 # in double precision. # 5023 # 5023 # # 5024 # ALGORITHM ********************************* 5024 # ALGORITHM *********************************************************** # 5025 # 5025 # # 5026 # SIN and COS: 5026 # SIN and COS: # 5027 # 1. If SIN is invoked, set AdjN := 0; 5027 # 1. If SIN is invoked, set AdjN := 0; otherwise, set AdjN := 1. # 5028 # 5028 # # 5029 # 2. If |X| >= 15Pi or |X| < 2**(-40), 5029 # 2. If |X| >= 15Pi or |X| < 2**(-40), go to 7. # 5030 # 5030 # # 5031 # 3. Decompose X as X = N(Pi/2) + r whe 5031 # 3. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 5032 # k = N mod 4, so in particular 5032 # k = N mod 4, so in particular, k = 0,1,2,or 3. # 5033 # Overwrite k by k := k + AdjN. 5033 # Overwrite k by k := k + AdjN. # 5034 # 5034 # # 5035 # 4. If k is even, go to 6. 5035 # 4. If k is even, go to 6. # 5036 # 5036 # # 5037 # 5. (k is odd) Set j := (k-1)/2, sgn : 5037 # 5. (k is odd) Set j := (k-1)/2, sgn := (-1)**j. # 5038 # Return sgn*cos(r) where cos(r 5038 # Return sgn*cos(r) where cos(r) is approximated by an # 5039 # even polynomial in r, 1 + r*r 5039 # even polynomial in r, 1 + r*r*(B1+s*(B2+ ... + s*B8)), # 5040 # s = r*r. 5040 # s = r*r. # 5041 # Exit. 5041 # Exit. # 5042 # 5042 # # 5043 # 6. (k is even) Set j := k/2, sgn := ( 5043 # 6. (k is even) Set j := k/2, sgn := (-1)**j. Return sgn*sin(r) # 5044 # where sin(r) is approximated 5044 # where sin(r) is approximated by an odd polynomial in r # 5045 # r + r*s*(A1+s*(A2+ ... + s*A7 5045 # r + r*s*(A1+s*(A2+ ... + s*A7)), s = r*r. # 5046 # Exit. 5046 # Exit. # 5047 # 5047 # # 5048 # 7. If |X| > 1, go to 9. 5048 # 7. If |X| > 1, go to 9. # 5049 # 5049 # # 5050 # 8. (|X|<2**(-40)) If SIN is invoked, 5050 # 8. (|X|<2**(-40)) If SIN is invoked, return X; # 5051 # otherwise return 1. 5051 # otherwise return 1. # 5052 # 5052 # # 5053 # 9. Overwrite X by X := X rem 2Pi. Now 5053 # 9. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 5054 # go back to 3. 5054 # go back to 3. # 5055 # 5055 # # 5056 # SINCOS: 5056 # SINCOS: # 5057 # 1. If |X| >= 15Pi or |X| < 2**(-40), 5057 # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 5058 # 5058 # # 5059 # 2. Decompose X as X = N(Pi/2) + r whe 5059 # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 5060 # k = N mod 4, so in particular 5060 # k = N mod 4, so in particular, k = 0,1,2,or 3. # 5061 # 5061 # # 5062 # 3. If k is even, go to 5. 5062 # 3. If k is even, go to 5. # 5063 # 5063 # # 5064 # 4. (k is odd) Set j1 := (k-1)/2, j2 : 5064 # 4. (k is odd) Set j1 := (k-1)/2, j2 := j1 (EOR) (k mod 2), ie. # 5065 # j1 exclusive or with the l.s. 5065 # j1 exclusive or with the l.s.b. of k. # 5066 # sgn1 := (-1)**j1, sgn2 := (-1 5066 # sgn1 := (-1)**j1, sgn2 := (-1)**j2. # 5067 # SIN(X) = sgn1 * cos(r) and CO 5067 # SIN(X) = sgn1 * cos(r) and COS(X) = sgn2*sin(r) where # 5068 # sin(r) and cos(r) are compute 5068 # sin(r) and cos(r) are computed as odd and even # 5069 # polynomials in r, respectivel 5069 # polynomials in r, respectively. Exit # 5070 # 5070 # # 5071 # 5. (k is even) Set j1 := k/2, sgn1 := 5071 # 5. (k is even) Set j1 := k/2, sgn1 := (-1)**j1. # 5072 # SIN(X) = sgn1 * sin(r) and CO 5072 # SIN(X) = sgn1 * sin(r) and COS(X) = sgn1*cos(r) where # 5073 # sin(r) and cos(r) are compute 5073 # sin(r) and cos(r) are computed as odd and even # 5074 # polynomials in r, respectivel 5074 # polynomials in r, respectively. Exit # 5075 # 5075 # # 5076 # 6. If |X| > 1, go to 8. 5076 # 6. If |X| > 1, go to 8. # 5077 # 5077 # # 5078 # 7. (|X|<2**(-40)) SIN(X) = X and COS( 5078 # 7. (|X|<2**(-40)) SIN(X) = X and COS(X) = 1. Exit. # 5079 # 5079 # # 5080 # 8. Overwrite X by X := X rem 2Pi. Now 5080 # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, # 5081 # go back to 2. 5081 # go back to 2. # 5082 # 5082 # # 5083 ############################################# 5083 ######################################################################### 5084 5084 5085 SINA7: long 0xBD6AAA77,0xCCC994F5 5085 SINA7: long 0xBD6AAA77,0xCCC994F5 5086 SINA6: long 0x3DE61209,0x7AAE8DA1 5086 SINA6: long 0x3DE61209,0x7AAE8DA1 5087 SINA5: long 0xBE5AE645,0x2A118AE4 5087 SINA5: long 0xBE5AE645,0x2A118AE4 5088 SINA4: long 0x3EC71DE3,0xA5341531 5088 SINA4: long 0x3EC71DE3,0xA5341531 5089 SINA3: long 0xBF2A01A0,0x1A018B59 5089 SINA3: long 0xBF2A01A0,0x1A018B59,0x00000000,0x00000000 5090 SINA2: long 0x3FF80000,0x88888888 5090 SINA2: long 0x3FF80000,0x88888888,0x888859AF,0x00000000 5091 SINA1: long 0xBFFC0000,0xAAAAAAAA 5091 SINA1: long 0xBFFC0000,0xAAAAAAAA,0xAAAAAA99,0x00000000 5092 5092 5093 COSB8: long 0x3D2AC4D0,0xD6011EE3 5093 COSB8: long 0x3D2AC4D0,0xD6011EE3 5094 COSB7: long 0xBDA9396F,0x9F45AC19 5094 COSB7: long 0xBDA9396F,0x9F45AC19 5095 COSB6: long 0x3E21EED9,0x0612C972 5095 COSB6: long 0x3E21EED9,0x0612C972 5096 COSB5: long 0xBE927E4F,0xB79D9FCF 5096 COSB5: long 0xBE927E4F,0xB79D9FCF 5097 COSB4: long 0x3EFA01A0,0x1A01D423 5097 COSB4: long 0x3EFA01A0,0x1A01D423,0x00000000,0x00000000 5098 COSB3: long 0xBFF50000,0xB60B60B6 5098 COSB3: long 0xBFF50000,0xB60B60B6,0x0B61D438,0x00000000 5099 COSB2: long 0x3FFA0000,0xAAAAAAAA 5099 COSB2: long 0x3FFA0000,0xAAAAAAAA,0xAAAAAB5E 5100 COSB1: long 0xBF000000 5100 COSB1: long 0xBF000000 5101 5101 5102 set INARG,FP_SCR0 5102 set INARG,FP_SCR0 5103 5103 5104 set X,FP_SCR0 5104 set X,FP_SCR0 5105 # set XDCARE,X+2 5105 # set XDCARE,X+2 5106 set XFRAC,X+4 5106 set XFRAC,X+4 5107 5107 5108 set RPRIME,FP_SCR0 5108 set RPRIME,FP_SCR0 5109 set SPRIME,FP_SCR1 5109 set SPRIME,FP_SCR1 5110 5110 5111 set POSNEG1,L_SCR1 5111 set POSNEG1,L_SCR1 5112 set TWOTO63,L_SCR1 5112 set TWOTO63,L_SCR1 5113 5113 5114 set ENDFLAG,L_SCR2 5114 set ENDFLAG,L_SCR2 5115 set INT,L_SCR2 5115 set INT,L_SCR2 5116 5116 5117 set ADJN,L_SCR3 5117 set ADJN,L_SCR3 5118 5118 5119 ############################################ 5119 ############################################ 5120 global ssin 5120 global ssin 5121 ssin: 5121 ssin: 5122 mov.l &0,ADJN(%a6) 5122 mov.l &0,ADJN(%a6) # yes; SET ADJN TO 0 5123 bra.b SINBGN 5123 bra.b SINBGN 5124 5124 5125 ############################################ 5125 ############################################ 5126 global scos 5126 global scos 5127 scos: 5127 scos: 5128 mov.l &1,ADJN(%a6) 5128 mov.l &1,ADJN(%a6) # yes; SET ADJN TO 1 5129 5129 5130 ############################################ 5130 ############################################ 5131 SINBGN: 5131 SINBGN: 5132 #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL 5132 #--SAVE FPCR, FP1. CHECK IF |X| IS TOO SMALL OR LARGE 5133 5133 5134 fmov.x (%a0),%fp0 5134 fmov.x (%a0),%fp0 # LOAD INPUT 5135 fmov.x %fp0,X(%a6) 5135 fmov.x %fp0,X(%a6) # save input at X 5136 5136 5137 # "COMPACTIFY" X 5137 # "COMPACTIFY" X 5138 mov.l (%a0),%d1 5138 mov.l (%a0),%d1 # put exp in hi word 5139 mov.w 4(%a0),%d1 5139 mov.w 4(%a0),%d1 # fetch hi(man) 5140 and.l &0x7FFFFFFF,%d1 5140 and.l &0x7FFFFFFF,%d1 # strip sign 5141 5141 5142 cmpi.l %d1,&0x3FD78000 5142 cmpi.l %d1,&0x3FD78000 # is |X| >= 2**(-40)? 5143 bge.b SOK1 5143 bge.b SOK1 # no 5144 bra.w SINSM 5144 bra.w SINSM # yes; input is very small 5145 5145 5146 SOK1: 5146 SOK1: 5147 cmp.l %d1,&0x4004BC7E 5147 cmp.l %d1,&0x4004BC7E # is |X| < 15 PI? 5148 blt.b SINMAIN 5148 blt.b SINMAIN # no 5149 bra.w SREDUCEX 5149 bra.w SREDUCEX # yes; input is very large 5150 5150 5151 #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5151 #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5152 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LO 5152 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 5153 SINMAIN: 5153 SINMAIN: 5154 fmov.x %fp0,%fp1 5154 fmov.x %fp0,%fp1 5155 fmul.d TWOBYPI(%pc),%fp1 5155 fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 5156 5156 5157 lea PITBL+0x200(%pc),%a1 5157 lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 5158 5158 5159 fmov.l %fp1,INT(%a6) 5159 fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 5160 5160 5161 mov.l INT(%a6),%d1 5161 mov.l INT(%a6),%d1 # make a copy of N 5162 asl.l &4,%d1 5162 asl.l &4,%d1 # N *= 16 5163 add.l %d1,%a1 5163 add.l %d1,%a1 # tbl_addr = a1 + (N*16) 5164 5164 5165 # A1 IS THE ADDRESS OF N*PIBY2 5165 # A1 IS THE ADDRESS OF N*PIBY2 5166 # ...WHICH IS IN TWO PIECES Y1 & Y2 5166 # ...WHICH IS IN TWO PIECES Y1 & Y2 5167 fsub.x (%a1)+,%fp0 5167 fsub.x (%a1)+,%fp0 # X-Y1 5168 fsub.s (%a1),%fp0 5168 fsub.s (%a1),%fp0 # fp0 = R = (X-Y1)-Y2 5169 5169 5170 SINCONT: 5170 SINCONT: 5171 #--continuation from REDUCEX 5171 #--continuation from REDUCEX 5172 5172 5173 #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS 5173 #--GET N+ADJN AND SEE IF SIN(R) OR COS(R) IS NEEDED 5174 mov.l INT(%a6),%d1 5174 mov.l INT(%a6),%d1 5175 add.l ADJN(%a6),%d1 5175 add.l ADJN(%a6),%d1 # SEE IF D0 IS ODD OR EVEN 5176 ror.l &1,%d1 5176 ror.l &1,%d1 # D0 WAS ODD IFF D0 IS NEGATIVE 5177 cmp.l %d1,&0 5177 cmp.l %d1,&0 5178 blt.w COSPOLY 5178 blt.w COSPOLY 5179 5179 5180 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN 5180 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 5181 #--THEN WE RETURN SGN*SIN(R). SGN*SIN(R 5181 #--THEN WE RETURN SGN*SIN(R). SGN*SIN(R) IS COMPUTED BY 5182 #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + 5182 #--R' + R'*S*(A1 + S(A2 + S(A3 + S(A4 + ... + SA7)))), WHERE 5183 #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN A 5183 #--R' = SGN*R, S=R*R. THIS CAN BE REWRITTEN AS 5184 #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T 5184 #--R' + R'*S*( [A1+T(A3+T(A5+TA7))] + [S(A2+T(A4+TA6))]) 5185 #--WHERE T=S*S. 5185 #--WHERE T=S*S. 5186 #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUB 5186 #--NOTE THAT A3 THROUGH A7 ARE STORED IN DOUBLE PRECISION 5187 #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FOR 5187 #--WHILE A1 AND A2 ARE IN DOUBLE-EXTENDED FORMAT. 5188 SINPOLY: 5188 SINPOLY: 5189 fmovm.x &0x0c,-(%sp) 5189 fmovm.x &0x0c,-(%sp) # save fp2/fp3 5190 5190 5191 fmov.x %fp0,X(%a6) 5191 fmov.x %fp0,X(%a6) # X IS R 5192 fmul.x %fp0,%fp0 5192 fmul.x %fp0,%fp0 # FP0 IS S 5193 5193 5194 fmov.d SINA7(%pc),%fp3 5194 fmov.d SINA7(%pc),%fp3 5195 fmov.d SINA6(%pc),%fp2 5195 fmov.d SINA6(%pc),%fp2 5196 5196 5197 fmov.x %fp0,%fp1 5197 fmov.x %fp0,%fp1 5198 fmul.x %fp1,%fp1 5198 fmul.x %fp1,%fp1 # FP1 IS T 5199 5199 5200 ror.l &1,%d1 5200 ror.l &1,%d1 5201 and.l &0x80000000,%d1 5201 and.l &0x80000000,%d1 5202 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION 5202 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION 5203 eor.l %d1,X(%a6) 5203 eor.l %d1,X(%a6) # X IS NOW R'= SGN*R 5204 5204 5205 fmul.x %fp1,%fp3 5205 fmul.x %fp1,%fp3 # TA7 5206 fmul.x %fp1,%fp2 5206 fmul.x %fp1,%fp2 # TA6 5207 5207 5208 fadd.d SINA5(%pc),%fp3 5208 fadd.d SINA5(%pc),%fp3 # A5+TA7 5209 fadd.d SINA4(%pc),%fp2 5209 fadd.d SINA4(%pc),%fp2 # A4+TA6 5210 5210 5211 fmul.x %fp1,%fp3 5211 fmul.x %fp1,%fp3 # T(A5+TA7) 5212 fmul.x %fp1,%fp2 5212 fmul.x %fp1,%fp2 # T(A4+TA6) 5213 5213 5214 fadd.d SINA3(%pc),%fp3 5214 fadd.d SINA3(%pc),%fp3 # A3+T(A5+TA7) 5215 fadd.x SINA2(%pc),%fp2 5215 fadd.x SINA2(%pc),%fp2 # A2+T(A4+TA6) 5216 5216 5217 fmul.x %fp3,%fp1 5217 fmul.x %fp3,%fp1 # T(A3+T(A5+TA7)) 5218 5218 5219 fmul.x %fp0,%fp2 5219 fmul.x %fp0,%fp2 # S(A2+T(A4+TA6)) 5220 fadd.x SINA1(%pc),%fp1 5220 fadd.x SINA1(%pc),%fp1 # A1+T(A3+T(A5+TA7)) 5221 fmul.x X(%a6),%fp0 5221 fmul.x X(%a6),%fp0 # R'*S 5222 5222 5223 fadd.x %fp2,%fp1 5223 fadd.x %fp2,%fp1 # [A1+T(A3+T(A5+TA7))]+[S(A2+T(A4+TA6))] 5224 5224 5225 fmul.x %fp1,%fp0 5225 fmul.x %fp1,%fp0 # SIN(R')-R' 5226 5226 5227 fmovm.x (%sp)+,&0x30 5227 fmovm.x (%sp)+,&0x30 # restore fp2/fp3 5228 5228 5229 fmov.l %d0,%fpcr 5229 fmov.l %d0,%fpcr # restore users round mode,prec 5230 fadd.x X(%a6),%fp0 5230 fadd.x X(%a6),%fp0 # last inst - possible exception set 5231 bra t_inx2 5231 bra t_inx2 5232 5232 5233 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN 5233 #--LET J BE THE LEAST SIG. BIT OF D0, LET SGN := (-1)**J. 5234 #--THEN WE RETURN SGN*COS(R). SGN*COS(R 5234 #--THEN WE RETURN SGN*COS(R). SGN*COS(R) IS COMPUTED BY 5235 #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + 5235 #--SGN + S'*(B1 + S(B2 + S(B3 + S(B4 + ... + SB8)))), WHERE 5236 #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN 5236 #--S=R*R AND S'=SGN*S. THIS CAN BE REWRITTEN AS 5237 #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B 5237 #--SGN + S'*([B1+T(B3+T(B5+TB7))] + [S(B2+T(B4+T(B6+TB8)))]) 5238 #--WHERE T=S*S. 5238 #--WHERE T=S*S. 5239 #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUB 5239 #--NOTE THAT B4 THROUGH B8 ARE STORED IN DOUBLE PRECISION 5240 #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FOR 5240 #--WHILE B2 AND B3 ARE IN DOUBLE-EXTENDED FORMAT, B1 IS -1/2 5241 #--AND IS THEREFORE STORED AS SINGLE PRECISIO 5241 #--AND IS THEREFORE STORED AS SINGLE PRECISION. 5242 COSPOLY: 5242 COSPOLY: 5243 fmovm.x &0x0c,-(%sp) 5243 fmovm.x &0x0c,-(%sp) # save fp2/fp3 5244 5244 5245 fmul.x %fp0,%fp0 5245 fmul.x %fp0,%fp0 # FP0 IS S 5246 5246 5247 fmov.d COSB8(%pc),%fp2 5247 fmov.d COSB8(%pc),%fp2 5248 fmov.d COSB7(%pc),%fp3 5248 fmov.d COSB7(%pc),%fp3 5249 5249 5250 fmov.x %fp0,%fp1 5250 fmov.x %fp0,%fp1 5251 fmul.x %fp1,%fp1 5251 fmul.x %fp1,%fp1 # FP1 IS T 5252 5252 5253 fmov.x %fp0,X(%a6) 5253 fmov.x %fp0,X(%a6) # X IS S 5254 ror.l &1,%d1 5254 ror.l &1,%d1 5255 and.l &0x80000000,%d1 5255 and.l &0x80000000,%d1 5256 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION 5256 # ...LEAST SIG. BIT OF D0 IN SIGN POSITION 5257 5257 5258 fmul.x %fp1,%fp2 5258 fmul.x %fp1,%fp2 # TB8 5259 5259 5260 eor.l %d1,X(%a6) 5260 eor.l %d1,X(%a6) # X IS NOW S'= SGN*S 5261 and.l &0x80000000,%d1 5261 and.l &0x80000000,%d1 5262 5262 5263 fmul.x %fp1,%fp3 5263 fmul.x %fp1,%fp3 # TB7 5264 5264 5265 or.l &0x3F800000,%d1 5265 or.l &0x3F800000,%d1 # D0 IS SGN IN SINGLE 5266 mov.l %d1,POSNEG1(%a6) 5266 mov.l %d1,POSNEG1(%a6) 5267 5267 5268 fadd.d COSB6(%pc),%fp2 5268 fadd.d COSB6(%pc),%fp2 # B6+TB8 5269 fadd.d COSB5(%pc),%fp3 5269 fadd.d COSB5(%pc),%fp3 # B5+TB7 5270 5270 5271 fmul.x %fp1,%fp2 5271 fmul.x %fp1,%fp2 # T(B6+TB8) 5272 fmul.x %fp1,%fp3 5272 fmul.x %fp1,%fp3 # T(B5+TB7) 5273 5273 5274 fadd.d COSB4(%pc),%fp2 5274 fadd.d COSB4(%pc),%fp2 # B4+T(B6+TB8) 5275 fadd.x COSB3(%pc),%fp3 5275 fadd.x COSB3(%pc),%fp3 # B3+T(B5+TB7) 5276 5276 5277 fmul.x %fp1,%fp2 5277 fmul.x %fp1,%fp2 # T(B4+T(B6+TB8)) 5278 fmul.x %fp3,%fp1 5278 fmul.x %fp3,%fp1 # T(B3+T(B5+TB7)) 5279 5279 5280 fadd.x COSB2(%pc),%fp2 5280 fadd.x COSB2(%pc),%fp2 # B2+T(B4+T(B6+TB8)) 5281 fadd.s COSB1(%pc),%fp1 5281 fadd.s COSB1(%pc),%fp1 # B1+T(B3+T(B5+TB7)) 5282 5282 5283 fmul.x %fp2,%fp0 5283 fmul.x %fp2,%fp0 # S(B2+T(B4+T(B6+TB8))) 5284 5284 5285 fadd.x %fp1,%fp0 5285 fadd.x %fp1,%fp0 5286 5286 5287 fmul.x X(%a6),%fp0 5287 fmul.x X(%a6),%fp0 5288 5288 5289 fmovm.x (%sp)+,&0x30 5289 fmovm.x (%sp)+,&0x30 # restore fp2/fp3 5290 5290 5291 fmov.l %d0,%fpcr 5291 fmov.l %d0,%fpcr # restore users round mode,prec 5292 fadd.s POSNEG1(%a6),%fp0 5292 fadd.s POSNEG1(%a6),%fp0 # last inst - possible exception set 5293 bra t_inx2 5293 bra t_inx2 5294 5294 5295 ############################################# 5295 ############################################## 5296 5296 5297 # SINe: Big OR Small? 5297 # SINe: Big OR Small? 5298 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT 5298 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 5299 #--IF |X| < 2**(-40), RETURN X OR 1. 5299 #--IF |X| < 2**(-40), RETURN X OR 1. 5300 SINBORS: 5300 SINBORS: 5301 cmp.l %d1,&0x3FFF8000 5301 cmp.l %d1,&0x3FFF8000 5302 bgt.l SREDUCEX 5302 bgt.l SREDUCEX 5303 5303 5304 SINSM: 5304 SINSM: 5305 mov.l ADJN(%a6),%d1 5305 mov.l ADJN(%a6),%d1 5306 cmp.l %d1,&0 5306 cmp.l %d1,&0 5307 bgt.b COSTINY 5307 bgt.b COSTINY 5308 5308 5309 # here, the operation may underflow iff the p 5309 # here, the operation may underflow iff the precision is sgl or dbl. 5310 # extended denorms are handled through anothe 5310 # extended denorms are handled through another entry point. 5311 SINTINY: 5311 SINTINY: 5312 # mov.w &0x0000,XDCARE(%a6) 5312 # mov.w &0x0000,XDCARE(%a6) # JUST IN CASE 5313 5313 5314 fmov.l %d0,%fpcr 5314 fmov.l %d0,%fpcr # restore users round mode,prec 5315 mov.b &FMOV_OP,%d1 5315 mov.b &FMOV_OP,%d1 # last inst is MOVE 5316 fmov.x X(%a6),%fp0 5316 fmov.x X(%a6),%fp0 # last inst - possible exception set 5317 bra t_catch 5317 bra t_catch 5318 5318 5319 COSTINY: 5319 COSTINY: 5320 fmov.s &0x3F800000,%fp0 5320 fmov.s &0x3F800000,%fp0 # fp0 = 1.0 5321 fmov.l %d0,%fpcr 5321 fmov.l %d0,%fpcr # restore users round mode,prec 5322 fadd.s &0x80800000,%fp0 5322 fadd.s &0x80800000,%fp0 # last inst - possible exception set 5323 bra t_pinx2 5323 bra t_pinx2 5324 5324 5325 ############################################# 5325 ################################################ 5326 global ssind 5326 global ssind 5327 #--SIN(X) = X FOR DENORMALIZED X 5327 #--SIN(X) = X FOR DENORMALIZED X 5328 ssind: 5328 ssind: 5329 bra t_extdnrm 5329 bra t_extdnrm 5330 5330 5331 ############################################ 5331 ############################################ 5332 global scosd 5332 global scosd 5333 #--COS(X) = 1 FOR DENORMALIZED X 5333 #--COS(X) = 1 FOR DENORMALIZED X 5334 scosd: 5334 scosd: 5335 fmov.s &0x3F800000,%fp0 5335 fmov.s &0x3F800000,%fp0 # fp0 = 1.0 5336 bra t_pinx2 5336 bra t_pinx2 5337 5337 5338 ############################################# 5338 ################################################## 5339 5339 5340 global ssincos 5340 global ssincos 5341 ssincos: 5341 ssincos: 5342 #--SET ADJN TO 4 5342 #--SET ADJN TO 4 5343 mov.l &4,ADJN(%a6) 5343 mov.l &4,ADJN(%a6) 5344 5344 5345 fmov.x (%a0),%fp0 5345 fmov.x (%a0),%fp0 # LOAD INPUT 5346 fmov.x %fp0,X(%a6) 5346 fmov.x %fp0,X(%a6) 5347 5347 5348 mov.l (%a0),%d1 5348 mov.l (%a0),%d1 5349 mov.w 4(%a0),%d1 5349 mov.w 4(%a0),%d1 5350 and.l &0x7FFFFFFF,%d1 5350 and.l &0x7FFFFFFF,%d1 # COMPACTIFY X 5351 5351 5352 cmp.l %d1,&0x3FD78000 5352 cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 5353 bge.b SCOK1 5353 bge.b SCOK1 5354 bra.w SCSM 5354 bra.w SCSM 5355 5355 5356 SCOK1: 5356 SCOK1: 5357 cmp.l %d1,&0x4004BC7E 5357 cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 5358 blt.b SCMAIN 5358 blt.b SCMAIN 5359 bra.w SREDUCEX 5359 bra.w SREDUCEX 5360 5360 5361 5361 5362 #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5362 #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5363 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LO 5363 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 5364 SCMAIN: 5364 SCMAIN: 5365 fmov.x %fp0,%fp1 5365 fmov.x %fp0,%fp1 5366 5366 5367 fmul.d TWOBYPI(%pc),%fp1 5367 fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 5368 5368 5369 lea PITBL+0x200(%pc),%a1 5369 lea PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 5370 5370 5371 fmov.l %fp1,INT(%a6) 5371 fmov.l %fp1,INT(%a6) # CONVERT TO INTEGER 5372 5372 5373 mov.l INT(%a6),%d1 5373 mov.l INT(%a6),%d1 5374 asl.l &4,%d1 5374 asl.l &4,%d1 5375 add.l %d1,%a1 5375 add.l %d1,%a1 # ADDRESS OF N*PIBY2, IN Y1, Y2 5376 5376 5377 fsub.x (%a1)+,%fp0 5377 fsub.x (%a1)+,%fp0 # X-Y1 5378 fsub.s (%a1),%fp0 5378 fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 5379 5379 5380 SCCONT: 5380 SCCONT: 5381 #--continuation point from REDUCEX 5381 #--continuation point from REDUCEX 5382 5382 5383 mov.l INT(%a6),%d1 5383 mov.l INT(%a6),%d1 5384 ror.l &1,%d1 5384 ror.l &1,%d1 5385 cmp.l %d1,&0 5385 cmp.l %d1,&0 # D0 < 0 IFF N IS ODD 5386 bge.w NEVEN 5386 bge.w NEVEN 5387 5387 5388 SNODD: 5388 SNODD: 5389 #--REGISTERS SAVED SO FAR: D0, A0, FP2. 5389 #--REGISTERS SAVED SO FAR: D0, A0, FP2. 5390 fmovm.x &0x04,-(%sp) 5390 fmovm.x &0x04,-(%sp) # save fp2 5391 5391 5392 fmov.x %fp0,RPRIME(%a6) 5392 fmov.x %fp0,RPRIME(%a6) 5393 fmul.x %fp0,%fp0 5393 fmul.x %fp0,%fp0 # FP0 IS S = R*R 5394 fmov.d SINA7(%pc),%fp1 5394 fmov.d SINA7(%pc),%fp1 # A7 5395 fmov.d COSB8(%pc),%fp2 5395 fmov.d COSB8(%pc),%fp2 # B8 5396 fmul.x %fp0,%fp1 5396 fmul.x %fp0,%fp1 # SA7 5397 fmul.x %fp0,%fp2 5397 fmul.x %fp0,%fp2 # SB8 5398 5398 5399 mov.l %d2,-(%sp) 5399 mov.l %d2,-(%sp) 5400 mov.l %d1,%d2 5400 mov.l %d1,%d2 5401 ror.l &1,%d2 5401 ror.l &1,%d2 5402 and.l &0x80000000,%d2 5402 and.l &0x80000000,%d2 5403 eor.l %d1,%d2 5403 eor.l %d1,%d2 5404 and.l &0x80000000,%d2 5404 and.l &0x80000000,%d2 5405 5405 5406 fadd.d SINA6(%pc),%fp1 5406 fadd.d SINA6(%pc),%fp1 # A6+SA7 5407 fadd.d COSB7(%pc),%fp2 5407 fadd.d COSB7(%pc),%fp2 # B7+SB8 5408 5408 5409 fmul.x %fp0,%fp1 5409 fmul.x %fp0,%fp1 # S(A6+SA7) 5410 eor.l %d2,RPRIME(%a6) 5410 eor.l %d2,RPRIME(%a6) 5411 mov.l (%sp)+,%d2 5411 mov.l (%sp)+,%d2 5412 fmul.x %fp0,%fp2 5412 fmul.x %fp0,%fp2 # S(B7+SB8) 5413 ror.l &1,%d1 5413 ror.l &1,%d1 5414 and.l &0x80000000,%d1 5414 and.l &0x80000000,%d1 5415 mov.l &0x3F800000,POSNEG1(% 5415 mov.l &0x3F800000,POSNEG1(%a6) 5416 eor.l %d1,POSNEG1(%a6) 5416 eor.l %d1,POSNEG1(%a6) 5417 5417 5418 fadd.d SINA5(%pc),%fp1 5418 fadd.d SINA5(%pc),%fp1 # A5+S(A6+SA7) 5419 fadd.d COSB6(%pc),%fp2 5419 fadd.d COSB6(%pc),%fp2 # B6+S(B7+SB8) 5420 5420 5421 fmul.x %fp0,%fp1 5421 fmul.x %fp0,%fp1 # S(A5+S(A6+SA7)) 5422 fmul.x %fp0,%fp2 5422 fmul.x %fp0,%fp2 # S(B6+S(B7+SB8)) 5423 fmov.x %fp0,SPRIME(%a6) 5423 fmov.x %fp0,SPRIME(%a6) 5424 5424 5425 fadd.d SINA4(%pc),%fp1 5425 fadd.d SINA4(%pc),%fp1 # A4+S(A5+S(A6+SA7)) 5426 eor.l %d1,SPRIME(%a6) 5426 eor.l %d1,SPRIME(%a6) 5427 fadd.d COSB5(%pc),%fp2 5427 fadd.d COSB5(%pc),%fp2 # B5+S(B6+S(B7+SB8)) 5428 5428 5429 fmul.x %fp0,%fp1 5429 fmul.x %fp0,%fp1 # S(A4+...) 5430 fmul.x %fp0,%fp2 5430 fmul.x %fp0,%fp2 # S(B5+...) 5431 5431 5432 fadd.d SINA3(%pc),%fp1 5432 fadd.d SINA3(%pc),%fp1 # A3+S(A4+...) 5433 fadd.d COSB4(%pc),%fp2 5433 fadd.d COSB4(%pc),%fp2 # B4+S(B5+...) 5434 5434 5435 fmul.x %fp0,%fp1 5435 fmul.x %fp0,%fp1 # S(A3+...) 5436 fmul.x %fp0,%fp2 5436 fmul.x %fp0,%fp2 # S(B4+...) 5437 5437 5438 fadd.x SINA2(%pc),%fp1 5438 fadd.x SINA2(%pc),%fp1 # A2+S(A3+...) 5439 fadd.x COSB3(%pc),%fp2 5439 fadd.x COSB3(%pc),%fp2 # B3+S(B4+...) 5440 5440 5441 fmul.x %fp0,%fp1 5441 fmul.x %fp0,%fp1 # S(A2+...) 5442 fmul.x %fp0,%fp2 5442 fmul.x %fp0,%fp2 # S(B3+...) 5443 5443 5444 fadd.x SINA1(%pc),%fp1 5444 fadd.x SINA1(%pc),%fp1 # A1+S(A2+...) 5445 fadd.x COSB2(%pc),%fp2 5445 fadd.x COSB2(%pc),%fp2 # B2+S(B3+...) 5446 5446 5447 fmul.x %fp0,%fp1 5447 fmul.x %fp0,%fp1 # S(A1+...) 5448 fmul.x %fp2,%fp0 5448 fmul.x %fp2,%fp0 # S(B2+...) 5449 5449 5450 fmul.x RPRIME(%a6),%fp1 5450 fmul.x RPRIME(%a6),%fp1 # R'S(A1+...) 5451 fadd.s COSB1(%pc),%fp0 5451 fadd.s COSB1(%pc),%fp0 # B1+S(B2...) 5452 fmul.x SPRIME(%a6),%fp0 5452 fmul.x SPRIME(%a6),%fp0 # S'(B1+S(B2+...)) 5453 5453 5454 fmovm.x (%sp)+,&0x20 5454 fmovm.x (%sp)+,&0x20 # restore fp2 5455 5455 5456 fmov.l %d0,%fpcr 5456 fmov.l %d0,%fpcr 5457 fadd.x RPRIME(%a6),%fp1 5457 fadd.x RPRIME(%a6),%fp1 # COS(X) 5458 bsr sto_cos 5458 bsr sto_cos # store cosine result 5459 fadd.s POSNEG1(%a6),%fp0 5459 fadd.s POSNEG1(%a6),%fp0 # SIN(X) 5460 bra t_inx2 5460 bra t_inx2 5461 5461 5462 NEVEN: 5462 NEVEN: 5463 #--REGISTERS SAVED SO FAR: FP2. 5463 #--REGISTERS SAVED SO FAR: FP2. 5464 fmovm.x &0x04,-(%sp) 5464 fmovm.x &0x04,-(%sp) # save fp2 5465 5465 5466 fmov.x %fp0,RPRIME(%a6) 5466 fmov.x %fp0,RPRIME(%a6) 5467 fmul.x %fp0,%fp0 5467 fmul.x %fp0,%fp0 # FP0 IS S = R*R 5468 5468 5469 fmov.d COSB8(%pc),%fp1 5469 fmov.d COSB8(%pc),%fp1 # B8 5470 fmov.d SINA7(%pc),%fp2 5470 fmov.d SINA7(%pc),%fp2 # A7 5471 5471 5472 fmul.x %fp0,%fp1 5472 fmul.x %fp0,%fp1 # SB8 5473 fmov.x %fp0,SPRIME(%a6) 5473 fmov.x %fp0,SPRIME(%a6) 5474 fmul.x %fp0,%fp2 5474 fmul.x %fp0,%fp2 # SA7 5475 5475 5476 ror.l &1,%d1 5476 ror.l &1,%d1 5477 and.l &0x80000000,%d1 5477 and.l &0x80000000,%d1 5478 5478 5479 fadd.d COSB7(%pc),%fp1 5479 fadd.d COSB7(%pc),%fp1 # B7+SB8 5480 fadd.d SINA6(%pc),%fp2 5480 fadd.d SINA6(%pc),%fp2 # A6+SA7 5481 5481 5482 eor.l %d1,RPRIME(%a6) 5482 eor.l %d1,RPRIME(%a6) 5483 eor.l %d1,SPRIME(%a6) 5483 eor.l %d1,SPRIME(%a6) 5484 5484 5485 fmul.x %fp0,%fp1 5485 fmul.x %fp0,%fp1 # S(B7+SB8) 5486 5486 5487 or.l &0x3F800000,%d1 5487 or.l &0x3F800000,%d1 5488 mov.l %d1,POSNEG1(%a6) 5488 mov.l %d1,POSNEG1(%a6) 5489 5489 5490 fmul.x %fp0,%fp2 5490 fmul.x %fp0,%fp2 # S(A6+SA7) 5491 5491 5492 fadd.d COSB6(%pc),%fp1 5492 fadd.d COSB6(%pc),%fp1 # B6+S(B7+SB8) 5493 fadd.d SINA5(%pc),%fp2 5493 fadd.d SINA5(%pc),%fp2 # A5+S(A6+SA7) 5494 5494 5495 fmul.x %fp0,%fp1 5495 fmul.x %fp0,%fp1 # S(B6+S(B7+SB8)) 5496 fmul.x %fp0,%fp2 5496 fmul.x %fp0,%fp2 # S(A5+S(A6+SA7)) 5497 5497 5498 fadd.d COSB5(%pc),%fp1 5498 fadd.d COSB5(%pc),%fp1 # B5+S(B6+S(B7+SB8)) 5499 fadd.d SINA4(%pc),%fp2 5499 fadd.d SINA4(%pc),%fp2 # A4+S(A5+S(A6+SA7)) 5500 5500 5501 fmul.x %fp0,%fp1 5501 fmul.x %fp0,%fp1 # S(B5+...) 5502 fmul.x %fp0,%fp2 5502 fmul.x %fp0,%fp2 # S(A4+...) 5503 5503 5504 fadd.d COSB4(%pc),%fp1 5504 fadd.d COSB4(%pc),%fp1 # B4+S(B5+...) 5505 fadd.d SINA3(%pc),%fp2 5505 fadd.d SINA3(%pc),%fp2 # A3+S(A4+...) 5506 5506 5507 fmul.x %fp0,%fp1 5507 fmul.x %fp0,%fp1 # S(B4+...) 5508 fmul.x %fp0,%fp2 5508 fmul.x %fp0,%fp2 # S(A3+...) 5509 5509 5510 fadd.x COSB3(%pc),%fp1 5510 fadd.x COSB3(%pc),%fp1 # B3+S(B4+...) 5511 fadd.x SINA2(%pc),%fp2 5511 fadd.x SINA2(%pc),%fp2 # A2+S(A3+...) 5512 5512 5513 fmul.x %fp0,%fp1 5513 fmul.x %fp0,%fp1 # S(B3+...) 5514 fmul.x %fp0,%fp2 5514 fmul.x %fp0,%fp2 # S(A2+...) 5515 5515 5516 fadd.x COSB2(%pc),%fp1 5516 fadd.x COSB2(%pc),%fp1 # B2+S(B3+...) 5517 fadd.x SINA1(%pc),%fp2 5517 fadd.x SINA1(%pc),%fp2 # A1+S(A2+...) 5518 5518 5519 fmul.x %fp0,%fp1 5519 fmul.x %fp0,%fp1 # S(B2+...) 5520 fmul.x %fp2,%fp0 5520 fmul.x %fp2,%fp0 # s(a1+...) 5521 5521 5522 5522 5523 fadd.s COSB1(%pc),%fp1 5523 fadd.s COSB1(%pc),%fp1 # B1+S(B2...) 5524 fmul.x RPRIME(%a6),%fp0 5524 fmul.x RPRIME(%a6),%fp0 # R'S(A1+...) 5525 fmul.x SPRIME(%a6),%fp1 5525 fmul.x SPRIME(%a6),%fp1 # S'(B1+S(B2+...)) 5526 5526 5527 fmovm.x (%sp)+,&0x20 5527 fmovm.x (%sp)+,&0x20 # restore fp2 5528 5528 5529 fmov.l %d0,%fpcr 5529 fmov.l %d0,%fpcr 5530 fadd.s POSNEG1(%a6),%fp1 5530 fadd.s POSNEG1(%a6),%fp1 # COS(X) 5531 bsr sto_cos 5531 bsr sto_cos # store cosine result 5532 fadd.x RPRIME(%a6),%fp0 5532 fadd.x RPRIME(%a6),%fp0 # SIN(X) 5533 bra t_inx2 5533 bra t_inx2 5534 5534 5535 ############################################# 5535 ################################################ 5536 5536 5537 SCBORS: 5537 SCBORS: 5538 cmp.l %d1,&0x3FFF8000 5538 cmp.l %d1,&0x3FFF8000 5539 bgt.w SREDUCEX 5539 bgt.w SREDUCEX 5540 5540 5541 ############################################# 5541 ################################################ 5542 5542 5543 SCSM: 5543 SCSM: 5544 # mov.w &0x0000,XDCARE(%a6) 5544 # mov.w &0x0000,XDCARE(%a6) 5545 fmov.s &0x3F800000,%fp1 5545 fmov.s &0x3F800000,%fp1 5546 5546 5547 fmov.l %d0,%fpcr 5547 fmov.l %d0,%fpcr 5548 fsub.s &0x00800000,%fp1 5548 fsub.s &0x00800000,%fp1 5549 bsr sto_cos 5549 bsr sto_cos # store cosine result 5550 fmov.l %fpcr,%d0 5550 fmov.l %fpcr,%d0 # d0 must have fpcr,too 5551 mov.b &FMOV_OP,%d1 5551 mov.b &FMOV_OP,%d1 # last inst is MOVE 5552 fmov.x X(%a6),%fp0 5552 fmov.x X(%a6),%fp0 5553 bra t_catch 5553 bra t_catch 5554 5554 5555 ############################################# 5555 ############################################## 5556 5556 5557 global ssincosd 5557 global ssincosd 5558 #--SIN AND COS OF X FOR DENORMALIZED X 5558 #--SIN AND COS OF X FOR DENORMALIZED X 5559 ssincosd: 5559 ssincosd: 5560 mov.l %d0,-(%sp) 5560 mov.l %d0,-(%sp) # save d0 5561 fmov.s &0x3F800000,%fp1 5561 fmov.s &0x3F800000,%fp1 5562 bsr sto_cos 5562 bsr sto_cos # store cosine result 5563 mov.l (%sp)+,%d0 5563 mov.l (%sp)+,%d0 # restore d0 5564 bra t_extdnrm 5564 bra t_extdnrm 5565 5565 5566 ############################################ 5566 ############################################ 5567 5567 5568 #--WHEN REDUCEX IS USED, THE CODE WILL INEVIT 5568 #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 5569 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FA 5569 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 5570 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN 5570 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 5571 SREDUCEX: 5571 SREDUCEX: 5572 fmovm.x &0x3c,-(%sp) 5572 fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 5573 mov.l %d2,-(%sp) 5573 mov.l %d2,-(%sp) # save d2 5574 fmov.s &0x00000000,%fp1 5574 fmov.s &0x00000000,%fp1 # fp1 = 0 5575 5575 5576 #--If compact form of abs(arg) in d0=$7ffefff 5576 #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 5577 #--there is a danger of unwanted overflow in 5577 #--there is a danger of unwanted overflow in first LOOP iteration. In this 5578 #--case, reduce argument by one remainder ste 5578 #--case, reduce argument by one remainder step to make subsequent reduction 5579 #--safe. 5579 #--safe. 5580 cmp.l %d1,&0x7ffeffff 5580 cmp.l %d1,&0x7ffeffff # is arg dangerously large? 5581 bne.b SLOOP 5581 bne.b SLOOP # no 5582 5582 5583 # yes; create 2**16383*PI/2 5583 # yes; create 2**16383*PI/2 5584 mov.w &0x7ffe,FP_SCR0_EX(%a 5584 mov.w &0x7ffe,FP_SCR0_EX(%a6) 5585 mov.l &0xc90fdaa2,FP_SCR0_H 5585 mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 5586 clr.l FP_SCR0_LO(%a6) 5586 clr.l FP_SCR0_LO(%a6) 5587 5587 5588 # create low half of 2**16383*PI/2 at FP_SCR1 5588 # create low half of 2**16383*PI/2 at FP_SCR1 5589 mov.w &0x7fdc,FP_SCR1_EX(%a 5589 mov.w &0x7fdc,FP_SCR1_EX(%a6) 5590 mov.l &0x85a308d3,FP_SCR1_H 5590 mov.l &0x85a308d3,FP_SCR1_HI(%a6) 5591 clr.l FP_SCR1_LO(%a6) 5591 clr.l FP_SCR1_LO(%a6) 5592 5592 5593 ftest.x %fp0 5593 ftest.x %fp0 # test sign of argument 5594 fblt.w sred_neg 5594 fblt.w sred_neg 5595 5595 5596 or.b &0x80,FP_SCR0_EX(%a6) 5596 or.b &0x80,FP_SCR0_EX(%a6) # positive arg 5597 or.b &0x80,FP_SCR1_EX(%a6) 5597 or.b &0x80,FP_SCR1_EX(%a6) 5598 sred_neg: 5598 sred_neg: 5599 fadd.x FP_SCR0(%a6),%fp0 5599 fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 5600 fmov.x %fp0,%fp1 5600 fmov.x %fp0,%fp1 # save high result in fp1 5601 fadd.x FP_SCR1(%a6),%fp0 5601 fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 5602 fsub.x %fp0,%fp1 5602 fsub.x %fp0,%fp1 # determine low component of result 5603 fadd.x FP_SCR1(%a6),%fp1 5603 fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 5604 5604 5605 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X RE 5605 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 5606 #--integer quotient will be stored in N 5606 #--integer quotient will be stored in N 5607 #--Intermeditate remainder is 66-bit long; (R 5607 #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 5608 SLOOP: 5608 SLOOP: 5609 fmov.x %fp0,INARG(%a6) 5609 fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 5610 mov.w INARG(%a6),%d1 5610 mov.w INARG(%a6),%d1 5611 mov.l %d1,%a1 5611 mov.l %d1,%a1 # save a copy of D0 5612 and.l &0x00007FFF,%d1 5612 and.l &0x00007FFF,%d1 5613 sub.l &0x00003FFF,%d1 5613 sub.l &0x00003FFF,%d1 # d0 = K 5614 cmp.l %d1,&28 5614 cmp.l %d1,&28 5615 ble.b SLASTLOOP 5615 ble.b SLASTLOOP 5616 SCONTLOOP: 5616 SCONTLOOP: 5617 sub.l &27,%d1 5617 sub.l &27,%d1 # d0 = L := K-27 5618 mov.b &0,ENDFLAG(%a6) 5618 mov.b &0,ENDFLAG(%a6) 5619 bra.b SWORK 5619 bra.b SWORK 5620 SLASTLOOP: 5620 SLASTLOOP: 5621 clr.l %d1 5621 clr.l %d1 # d0 = L := 0 5622 mov.b &1,ENDFLAG(%a6) 5622 mov.b &1,ENDFLAG(%a6) 5623 5623 5624 SWORK: 5624 SWORK: 5625 #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L 5625 #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 5626 #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 5626 #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 5627 5627 5628 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(6 5628 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 5629 #--2**L * (PIby2_1), 2**L * (PIby2_2) 5629 #--2**L * (PIby2_1), 2**L * (PIby2_2) 5630 5630 5631 mov.l &0x00003FFE,%d2 5631 mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 5632 sub.l %d1,%d2 5632 sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 5633 5633 5634 mov.l &0xA2F9836E,FP_SCR0_H 5634 mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 5635 mov.l &0x4E44152A,FP_SCR0_L 5635 mov.l &0x4E44152A,FP_SCR0_LO(%a6) 5636 mov.w %d2,FP_SCR0_EX(%a6) 5636 mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 5637 5637 5638 fmov.x %fp0,%fp2 5638 fmov.x %fp0,%fp2 5639 fmul.x FP_SCR0(%a6),%fp2 5639 fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 5640 5640 5641 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED T 5641 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 5642 #--FLOATING POINT FORMAT, THE TWO FMOVE'S 5642 #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 5643 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT 5643 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 5644 #--(SIGN(INARG)*2**63 + FP2) - SIGN(I 5644 #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 5645 #--US THE DESIRED VALUE IN FLOATING POINT. 5645 #--US THE DESIRED VALUE IN FLOATING POINT. 5646 mov.l %a1,%d2 5646 mov.l %a1,%d2 5647 swap %d2 5647 swap %d2 5648 and.l &0x80000000,%d2 5648 and.l &0x80000000,%d2 5649 or.l &0x5F000000,%d2 5649 or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 5650 mov.l %d2,TWOTO63(%a6) 5650 mov.l %d2,TWOTO63(%a6) 5651 fadd.s TWOTO63(%a6),%fp2 5651 fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 5652 fsub.s TWOTO63(%a6),%fp2 5652 fsub.s TWOTO63(%a6),%fp2 # fp2 = N 5653 # fint.x %fp2 5653 # fint.x %fp2 5654 5654 5655 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 5655 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 5656 mov.l %d1,%d2 5656 mov.l %d1,%d2 # d2 = L 5657 5657 5658 add.l &0x00003FFF,%d2 5658 add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 5659 mov.w %d2,FP_SCR0_EX(%a6) 5659 mov.w %d2,FP_SCR0_EX(%a6) 5660 mov.l &0xC90FDAA2,FP_SCR0_H 5660 mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 5661 clr.l FP_SCR0_LO(%a6) 5661 clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 5662 5662 5663 add.l &0x00003FDD,%d1 5663 add.l &0x00003FDD,%d1 5664 mov.w %d1,FP_SCR1_EX(%a6) 5664 mov.w %d1,FP_SCR1_EX(%a6) 5665 mov.l &0x85A308D3,FP_SCR1_H 5665 mov.l &0x85A308D3,FP_SCR1_HI(%a6) 5666 clr.l FP_SCR1_LO(%a6) 5666 clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 5667 5667 5668 mov.b ENDFLAG(%a6),%d1 5668 mov.b ENDFLAG(%a6),%d1 5669 5669 5670 #--We are now ready to perform (R+r) - N*P1 - 5670 #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 5671 #--P2 = 2**(L) * Piby2_2 5671 #--P2 = 2**(L) * Piby2_2 5672 fmov.x %fp2,%fp4 5672 fmov.x %fp2,%fp4 # fp4 = N 5673 fmul.x FP_SCR0(%a6),%fp4 5673 fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 5674 fmov.x %fp2,%fp5 5674 fmov.x %fp2,%fp5 # fp5 = N 5675 fmul.x FP_SCR1(%a6),%fp5 5675 fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 5676 fmov.x %fp4,%fp3 5676 fmov.x %fp4,%fp3 # fp3 = W = N*P1 5677 5677 5678 #--we want P+p = W+w but |p| <= half ulp of 5678 #--we want P+p = W+w but |p| <= half ulp of P 5679 #--Then, we need to compute A := R-P and 5679 #--Then, we need to compute A := R-P and a := r-p 5680 fadd.x %fp5,%fp3 5680 fadd.x %fp5,%fp3 # fp3 = P 5681 fsub.x %fp3,%fp4 5681 fsub.x %fp3,%fp4 # fp4 = W-P 5682 5682 5683 fsub.x %fp3,%fp0 5683 fsub.x %fp3,%fp0 # fp0 = A := R - P 5684 fadd.x %fp5,%fp4 5684 fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 5685 5685 5686 fmov.x %fp0,%fp3 5686 fmov.x %fp0,%fp3 # fp3 = A 5687 fsub.x %fp4,%fp1 5687 fsub.x %fp4,%fp1 # fp1 = a := r - p 5688 5688 5689 #--Now we need to normalize (A,a) to "new (R 5689 #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 5690 #--|r| <= half ulp of R. 5690 #--|r| <= half ulp of R. 5691 fadd.x %fp1,%fp0 5691 fadd.x %fp1,%fp0 # fp0 = R := A+a 5692 #--No need to calculate r if this is the last 5692 #--No need to calculate r if this is the last loop 5693 cmp.b %d1,&0 5693 cmp.b %d1,&0 5694 bgt.w SRESTORE 5694 bgt.w SRESTORE 5695 5695 5696 #--Need to calculate r 5696 #--Need to calculate r 5697 fsub.x %fp0,%fp3 5697 fsub.x %fp0,%fp3 # fp3 = A-R 5698 fadd.x %fp3,%fp1 5698 fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 5699 bra.w SLOOP 5699 bra.w SLOOP 5700 5700 5701 SRESTORE: 5701 SRESTORE: 5702 fmov.l %fp2,INT(%a6) 5702 fmov.l %fp2,INT(%a6) 5703 mov.l (%sp)+,%d2 5703 mov.l (%sp)+,%d2 # restore d2 5704 fmovm.x (%sp)+,&0x3c 5704 fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 5705 5705 5706 mov.l ADJN(%a6),%d1 5706 mov.l ADJN(%a6),%d1 5707 cmp.l %d1,&4 5707 cmp.l %d1,&4 5708 5708 5709 blt.w SINCONT 5709 blt.w SINCONT 5710 bra.w SCCONT 5710 bra.w SCCONT 5711 5711 5712 ############################################# 5712 ######################################################################### 5713 # stan(): computes the tangent of a normaliz 5713 # stan(): computes the tangent of a normalized input # 5714 # stand(): computes the tangent of a denormal 5714 # stand(): computes the tangent of a denormalized input # 5715 # 5715 # # 5716 # INPUT ************************************* 5716 # INPUT *************************************************************** # 5717 # a0 = pointer to extended precision in 5717 # a0 = pointer to extended precision input # 5718 # d0 = round precision,mode 5718 # d0 = round precision,mode # 5719 # 5719 # # 5720 # OUTPUT ************************************ 5720 # OUTPUT ************************************************************** # 5721 # fp0 = tan(X) 5721 # fp0 = tan(X) # 5722 # 5722 # # 5723 # ACCURACY and MONOTONICITY ***************** 5723 # ACCURACY and MONOTONICITY ******************************************* # 5724 # The returned result is within 3 ulp i 5724 # The returned result is within 3 ulp in 64 significant bit, i.e. # 5725 # within 0.5001 ulp to 53 bits if the r 5725 # within 0.5001 ulp to 53 bits if the result is subsequently # 5726 # rounded to double precision. The resu 5726 # rounded to double precision. The result is provably monotonic # 5727 # in double precision. 5727 # in double precision. # 5728 # 5728 # # 5729 # ALGORITHM ********************************* 5729 # ALGORITHM *********************************************************** # 5730 # 5730 # # 5731 # 1. If |X| >= 15Pi or |X| < 2**(-40), 5731 # 1. If |X| >= 15Pi or |X| < 2**(-40), go to 6. # 5732 # 5732 # # 5733 # 2. Decompose X as X = N(Pi/2) + r whe 5733 # 2. Decompose X as X = N(Pi/2) + r where |r| <= Pi/4. Let # 5734 # k = N mod 2, so in particular 5734 # k = N mod 2, so in particular, k = 0 or 1. # 5735 # 5735 # # 5736 # 3. If k is odd, go to 5. 5736 # 3. If k is odd, go to 5. # 5737 # 5737 # # 5738 # 4. (k is even) Tan(X) = tan(r) and ta 5738 # 4. (k is even) Tan(X) = tan(r) and tan(r) is approximated by a # 5739 # rational function U/V where 5739 # rational function U/V where # 5740 # U = r + r*s*(P1 + s*(P2 + s*P 5740 # U = r + r*s*(P1 + s*(P2 + s*P3)), and # 5741 # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 5741 # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r. # 5742 # Exit. 5742 # Exit. # 5743 # 5743 # # 5744 # 4. (k is odd) Tan(X) = -cot(r). Since 5744 # 4. (k is odd) Tan(X) = -cot(r). Since tan(r) is approximated by # 5745 # a rational function U/V where 5745 # a rational function U/V where # 5746 # U = r + r*s*(P1 + s*(P2 + s*P 5746 # U = r + r*s*(P1 + s*(P2 + s*P3)), and # 5747 # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 5747 # V = 1 + s*(Q1 + s*(Q2 + s*(Q3 + s*Q4))), s = r*r, # 5748 # -Cot(r) = -V/U. Exit. 5748 # -Cot(r) = -V/U. Exit. # 5749 # 5749 # # 5750 # 6. If |X| > 1, go to 8. 5750 # 6. If |X| > 1, go to 8. # 5751 # 5751 # # 5752 # 7. (|X|<2**(-40)) Tan(X) = X. Exit. 5752 # 7. (|X|<2**(-40)) Tan(X) = X. Exit. # 5753 # 5753 # # 5754 # 8. Overwrite X by X := X rem 2Pi. Now 5754 # 8. Overwrite X by X := X rem 2Pi. Now that |X| <= Pi, go back # 5755 # to 2. 5755 # to 2. # 5756 # 5756 # # 5757 ############################################# 5757 ######################################################################### 5758 5758 5759 TANQ4: 5759 TANQ4: 5760 long 0x3EA0B759,0xF50F8688 5760 long 0x3EA0B759,0xF50F8688 5761 TANP3: 5761 TANP3: 5762 long 0xBEF2BAA5,0xA8924F04 5762 long 0xBEF2BAA5,0xA8924F04 5763 5763 5764 TANQ3: 5764 TANQ3: 5765 long 0xBF346F59,0xB39BA65F 5765 long 0xBF346F59,0xB39BA65F,0x00000000,0x00000000 5766 5766 5767 TANP2: 5767 TANP2: 5768 long 0x3FF60000,0xE073D3FC 5768 long 0x3FF60000,0xE073D3FC,0x199C4A00,0x00000000 5769 5769 5770 TANQ2: 5770 TANQ2: 5771 long 0x3FF90000,0xD23CD684 5771 long 0x3FF90000,0xD23CD684,0x15D95FA1,0x00000000 5772 5772 5773 TANP1: 5773 TANP1: 5774 long 0xBFFC0000,0x8895A6C5 5774 long 0xBFFC0000,0x8895A6C5,0xFB423BCA,0x00000000 5775 5775 5776 TANQ1: 5776 TANQ1: 5777 long 0xBFFD0000,0xEEF57E0D 5777 long 0xBFFD0000,0xEEF57E0D,0xA84BC8CE,0x00000000 5778 5778 5779 INVTWOPI: 5779 INVTWOPI: 5780 long 0x3FFC0000,0xA2F9836E 5780 long 0x3FFC0000,0xA2F9836E,0x4E44152A,0x00000000 5781 5781 5782 TWOPI1: 5782 TWOPI1: 5783 long 0x40010000,0xC90FDAA2 5783 long 0x40010000,0xC90FDAA2,0x00000000,0x00000000 5784 TWOPI2: 5784 TWOPI2: 5785 long 0x3FDF0000,0x85A308D4 5785 long 0x3FDF0000,0x85A308D4,0x00000000,0x00000000 5786 5786 5787 #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM 5787 #--N*PI/2, -32 <= N <= 32, IN A LEADING TERM IN EXT. AND TRAILING 5788 #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, 5788 #--TERM IN SGL. NOTE THAT PI IS 64-BIT LONG, THUS N*PI/2 IS AT 5789 #--MOST 69 BITS LONG. 5789 #--MOST 69 BITS LONG. 5790 # global PITBL 5790 # global PITBL 5791 PITBL: 5791 PITBL: 5792 long 0xC0040000,0xC90FDAA2 5792 long 0xC0040000,0xC90FDAA2,0x2168C235,0x21800000 5793 long 0xC0040000,0xC2C75BCD 5793 long 0xC0040000,0xC2C75BCD,0x105D7C23,0xA0D00000 5794 long 0xC0040000,0xBC7EDCF7 5794 long 0xC0040000,0xBC7EDCF7,0xFF523611,0xA1E80000 5795 long 0xC0040000,0xB6365E22 5795 long 0xC0040000,0xB6365E22,0xEE46F000,0x21480000 5796 long 0xC0040000,0xAFEDDF4D 5796 long 0xC0040000,0xAFEDDF4D,0xDD3BA9EE,0xA1200000 5797 long 0xC0040000,0xA9A56078 5797 long 0xC0040000,0xA9A56078,0xCC3063DD,0x21FC0000 5798 long 0xC0040000,0xA35CE1A3 5798 long 0xC0040000,0xA35CE1A3,0xBB251DCB,0x21100000 5799 long 0xC0040000,0x9D1462CE 5799 long 0xC0040000,0x9D1462CE,0xAA19D7B9,0xA1580000 5800 long 0xC0040000,0x96CBE3F9 5800 long 0xC0040000,0x96CBE3F9,0x990E91A8,0x21E00000 5801 long 0xC0040000,0x90836524 5801 long 0xC0040000,0x90836524,0x88034B96,0x20B00000 5802 long 0xC0040000,0x8A3AE64F 5802 long 0xC0040000,0x8A3AE64F,0x76F80584,0xA1880000 5803 long 0xC0040000,0x83F2677A 5803 long 0xC0040000,0x83F2677A,0x65ECBF73,0x21C40000 5804 long 0xC0030000,0xFB53D14A 5804 long 0xC0030000,0xFB53D14A,0xA9C2F2C2,0x20000000 5805 long 0xC0030000,0xEEC2D3A0 5805 long 0xC0030000,0xEEC2D3A0,0x87AC669F,0x21380000 5806 long 0xC0030000,0xE231D5F6 5806 long 0xC0030000,0xE231D5F6,0x6595DA7B,0xA1300000 5807 long 0xC0030000,0xD5A0D84C 5807 long 0xC0030000,0xD5A0D84C,0x437F4E58,0x9FC00000 5808 long 0xC0030000,0xC90FDAA2 5808 long 0xC0030000,0xC90FDAA2,0x2168C235,0x21000000 5809 long 0xC0030000,0xBC7EDCF7 5809 long 0xC0030000,0xBC7EDCF7,0xFF523611,0xA1680000 5810 long 0xC0030000,0xAFEDDF4D 5810 long 0xC0030000,0xAFEDDF4D,0xDD3BA9EE,0xA0A00000 5811 long 0xC0030000,0xA35CE1A3 5811 long 0xC0030000,0xA35CE1A3,0xBB251DCB,0x20900000 5812 long 0xC0030000,0x96CBE3F9 5812 long 0xC0030000,0x96CBE3F9,0x990E91A8,0x21600000 5813 long 0xC0030000,0x8A3AE64F 5813 long 0xC0030000,0x8A3AE64F,0x76F80584,0xA1080000 5814 long 0xC0020000,0xFB53D14A 5814 long 0xC0020000,0xFB53D14A,0xA9C2F2C2,0x1F800000 5815 long 0xC0020000,0xE231D5F6 5815 long 0xC0020000,0xE231D5F6,0x6595DA7B,0xA0B00000 5816 long 0xC0020000,0xC90FDAA2 5816 long 0xC0020000,0xC90FDAA2,0x2168C235,0x20800000 5817 long 0xC0020000,0xAFEDDF4D 5817 long 0xC0020000,0xAFEDDF4D,0xDD3BA9EE,0xA0200000 5818 long 0xC0020000,0x96CBE3F9 5818 long 0xC0020000,0x96CBE3F9,0x990E91A8,0x20E00000 5819 long 0xC0010000,0xFB53D14A 5819 long 0xC0010000,0xFB53D14A,0xA9C2F2C2,0x1F000000 5820 long 0xC0010000,0xC90FDAA2 5820 long 0xC0010000,0xC90FDAA2,0x2168C235,0x20000000 5821 long 0xC0010000,0x96CBE3F9 5821 long 0xC0010000,0x96CBE3F9,0x990E91A8,0x20600000 5822 long 0xC0000000,0xC90FDAA2 5822 long 0xC0000000,0xC90FDAA2,0x2168C235,0x1F800000 5823 long 0xBFFF0000,0xC90FDAA2 5823 long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x1F000000 5824 long 0x00000000,0x00000000 5824 long 0x00000000,0x00000000,0x00000000,0x00000000 5825 long 0x3FFF0000,0xC90FDAA2 5825 long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x9F000000 5826 long 0x40000000,0xC90FDAA2 5826 long 0x40000000,0xC90FDAA2,0x2168C235,0x9F800000 5827 long 0x40010000,0x96CBE3F9 5827 long 0x40010000,0x96CBE3F9,0x990E91A8,0xA0600000 5828 long 0x40010000,0xC90FDAA2 5828 long 0x40010000,0xC90FDAA2,0x2168C235,0xA0000000 5829 long 0x40010000,0xFB53D14A 5829 long 0x40010000,0xFB53D14A,0xA9C2F2C2,0x9F000000 5830 long 0x40020000,0x96CBE3F9 5830 long 0x40020000,0x96CBE3F9,0x990E91A8,0xA0E00000 5831 long 0x40020000,0xAFEDDF4D 5831 long 0x40020000,0xAFEDDF4D,0xDD3BA9EE,0x20200000 5832 long 0x40020000,0xC90FDAA2 5832 long 0x40020000,0xC90FDAA2,0x2168C235,0xA0800000 5833 long 0x40020000,0xE231D5F6 5833 long 0x40020000,0xE231D5F6,0x6595DA7B,0x20B00000 5834 long 0x40020000,0xFB53D14A 5834 long 0x40020000,0xFB53D14A,0xA9C2F2C2,0x9F800000 5835 long 0x40030000,0x8A3AE64F 5835 long 0x40030000,0x8A3AE64F,0x76F80584,0x21080000 5836 long 0x40030000,0x96CBE3F9 5836 long 0x40030000,0x96CBE3F9,0x990E91A8,0xA1600000 5837 long 0x40030000,0xA35CE1A3 5837 long 0x40030000,0xA35CE1A3,0xBB251DCB,0xA0900000 5838 long 0x40030000,0xAFEDDF4D 5838 long 0x40030000,0xAFEDDF4D,0xDD3BA9EE,0x20A00000 5839 long 0x40030000,0xBC7EDCF7 5839 long 0x40030000,0xBC7EDCF7,0xFF523611,0x21680000 5840 long 0x40030000,0xC90FDAA2 5840 long 0x40030000,0xC90FDAA2,0x2168C235,0xA1000000 5841 long 0x40030000,0xD5A0D84C 5841 long 0x40030000,0xD5A0D84C,0x437F4E58,0x1FC00000 5842 long 0x40030000,0xE231D5F6 5842 long 0x40030000,0xE231D5F6,0x6595DA7B,0x21300000 5843 long 0x40030000,0xEEC2D3A0 5843 long 0x40030000,0xEEC2D3A0,0x87AC669F,0xA1380000 5844 long 0x40030000,0xFB53D14A 5844 long 0x40030000,0xFB53D14A,0xA9C2F2C2,0xA0000000 5845 long 0x40040000,0x83F2677A 5845 long 0x40040000,0x83F2677A,0x65ECBF73,0xA1C40000 5846 long 0x40040000,0x8A3AE64F 5846 long 0x40040000,0x8A3AE64F,0x76F80584,0x21880000 5847 long 0x40040000,0x90836524 5847 long 0x40040000,0x90836524,0x88034B96,0xA0B00000 5848 long 0x40040000,0x96CBE3F9 5848 long 0x40040000,0x96CBE3F9,0x990E91A8,0xA1E00000 5849 long 0x40040000,0x9D1462CE 5849 long 0x40040000,0x9D1462CE,0xAA19D7B9,0x21580000 5850 long 0x40040000,0xA35CE1A3 5850 long 0x40040000,0xA35CE1A3,0xBB251DCB,0xA1100000 5851 long 0x40040000,0xA9A56078 5851 long 0x40040000,0xA9A56078,0xCC3063DD,0xA1FC0000 5852 long 0x40040000,0xAFEDDF4D 5852 long 0x40040000,0xAFEDDF4D,0xDD3BA9EE,0x21200000 5853 long 0x40040000,0xB6365E22 5853 long 0x40040000,0xB6365E22,0xEE46F000,0xA1480000 5854 long 0x40040000,0xBC7EDCF7 5854 long 0x40040000,0xBC7EDCF7,0xFF523611,0x21E80000 5855 long 0x40040000,0xC2C75BCD 5855 long 0x40040000,0xC2C75BCD,0x105D7C23,0x20D00000 5856 long 0x40040000,0xC90FDAA2 5856 long 0x40040000,0xC90FDAA2,0x2168C235,0xA1800000 5857 5857 5858 set INARG,FP_SCR0 5858 set INARG,FP_SCR0 5859 5859 5860 set TWOTO63,L_SCR1 5860 set TWOTO63,L_SCR1 5861 set INT,L_SCR1 5861 set INT,L_SCR1 5862 set ENDFLAG,L_SCR2 5862 set ENDFLAG,L_SCR2 5863 5863 5864 global stan 5864 global stan 5865 stan: 5865 stan: 5866 fmov.x (%a0),%fp0 5866 fmov.x (%a0),%fp0 # LOAD INPUT 5867 5867 5868 mov.l (%a0),%d1 5868 mov.l (%a0),%d1 5869 mov.w 4(%a0),%d1 5869 mov.w 4(%a0),%d1 5870 and.l &0x7FFFFFFF,%d1 5870 and.l &0x7FFFFFFF,%d1 5871 5871 5872 cmp.l %d1,&0x3FD78000 5872 cmp.l %d1,&0x3FD78000 # |X| >= 2**(-40)? 5873 bge.b TANOK1 5873 bge.b TANOK1 5874 bra.w TANSM 5874 bra.w TANSM 5875 TANOK1: 5875 TANOK1: 5876 cmp.l %d1,&0x4004BC7E 5876 cmp.l %d1,&0x4004BC7E # |X| < 15 PI? 5877 blt.b TANMAIN 5877 blt.b TANMAIN 5878 bra.w REDUCEX 5878 bra.w REDUCEX 5879 5879 5880 TANMAIN: 5880 TANMAIN: 5881 #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5881 #--THIS IS THE USUAL CASE, |X| <= 15 PI. 5882 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LO 5882 #--THE ARGUMENT REDUCTION IS DONE BY TABLE LOOK UP. 5883 fmov.x %fp0,%fp1 5883 fmov.x %fp0,%fp1 5884 fmul.d TWOBYPI(%pc),%fp1 5884 fmul.d TWOBYPI(%pc),%fp1 # X*2/PI 5885 5885 5886 lea.l PITBL+0x200(%pc),%a1 5886 lea.l PITBL+0x200(%pc),%a1 # TABLE OF N*PI/2, N = -32,...,32 5887 5887 5888 fmov.l %fp1,%d1 5888 fmov.l %fp1,%d1 # CONVERT TO INTEGER 5889 5889 5890 asl.l &4,%d1 5890 asl.l &4,%d1 5891 add.l %d1,%a1 5891 add.l %d1,%a1 # ADDRESS N*PIBY2 IN Y1, Y2 5892 5892 5893 fsub.x (%a1)+,%fp0 5893 fsub.x (%a1)+,%fp0 # X-Y1 5894 5894 5895 fsub.s (%a1),%fp0 5895 fsub.s (%a1),%fp0 # FP0 IS R = (X-Y1)-Y2 5896 5896 5897 ror.l &5,%d1 5897 ror.l &5,%d1 5898 and.l &0x80000000,%d1 5898 and.l &0x80000000,%d1 # D0 WAS ODD IFF D0 < 0 5899 5899 5900 TANCONT: 5900 TANCONT: 5901 fmovm.x &0x0c,-(%sp) 5901 fmovm.x &0x0c,-(%sp) # save fp2,fp3 5902 5902 5903 cmp.l %d1,&0 5903 cmp.l %d1,&0 5904 blt.w NODD 5904 blt.w NODD 5905 5905 5906 fmov.x %fp0,%fp1 5906 fmov.x %fp0,%fp1 5907 fmul.x %fp1,%fp1 5907 fmul.x %fp1,%fp1 # S = R*R 5908 5908 5909 fmov.d TANQ4(%pc),%fp3 5909 fmov.d TANQ4(%pc),%fp3 5910 fmov.d TANP3(%pc),%fp2 5910 fmov.d TANP3(%pc),%fp2 5911 5911 5912 fmul.x %fp1,%fp3 5912 fmul.x %fp1,%fp3 # SQ4 5913 fmul.x %fp1,%fp2 5913 fmul.x %fp1,%fp2 # SP3 5914 5914 5915 fadd.d TANQ3(%pc),%fp3 5915 fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 5916 fadd.x TANP2(%pc),%fp2 5916 fadd.x TANP2(%pc),%fp2 # P2+SP3 5917 5917 5918 fmul.x %fp1,%fp3 5918 fmul.x %fp1,%fp3 # S(Q3+SQ4) 5919 fmul.x %fp1,%fp2 5919 fmul.x %fp1,%fp2 # S(P2+SP3) 5920 5920 5921 fadd.x TANQ2(%pc),%fp3 5921 fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 5922 fadd.x TANP1(%pc),%fp2 5922 fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 5923 5923 5924 fmul.x %fp1,%fp3 5924 fmul.x %fp1,%fp3 # S(Q2+S(Q3+SQ4)) 5925 fmul.x %fp1,%fp2 5925 fmul.x %fp1,%fp2 # S(P1+S(P2+SP3)) 5926 5926 5927 fadd.x TANQ1(%pc),%fp3 5927 fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 5928 fmul.x %fp0,%fp2 5928 fmul.x %fp0,%fp2 # RS(P1+S(P2+SP3)) 5929 5929 5930 fmul.x %fp3,%fp1 5930 fmul.x %fp3,%fp1 # S(Q1+S(Q2+S(Q3+SQ4))) 5931 5931 5932 fadd.x %fp2,%fp0 5932 fadd.x %fp2,%fp0 # R+RS(P1+S(P2+SP3)) 5933 5933 5934 fadd.s &0x3F800000,%fp1 5934 fadd.s &0x3F800000,%fp1 # 1+S(Q1+...) 5935 5935 5936 fmovm.x (%sp)+,&0x30 5936 fmovm.x (%sp)+,&0x30 # restore fp2,fp3 5937 5937 5938 fmov.l %d0,%fpcr 5938 fmov.l %d0,%fpcr # restore users round mode,prec 5939 fdiv.x %fp1,%fp0 5939 fdiv.x %fp1,%fp0 # last inst - possible exception set 5940 bra t_inx2 5940 bra t_inx2 5941 5941 5942 NODD: 5942 NODD: 5943 fmov.x %fp0,%fp1 5943 fmov.x %fp0,%fp1 5944 fmul.x %fp0,%fp0 5944 fmul.x %fp0,%fp0 # S = R*R 5945 5945 5946 fmov.d TANQ4(%pc),%fp3 5946 fmov.d TANQ4(%pc),%fp3 5947 fmov.d TANP3(%pc),%fp2 5947 fmov.d TANP3(%pc),%fp2 5948 5948 5949 fmul.x %fp0,%fp3 5949 fmul.x %fp0,%fp3 # SQ4 5950 fmul.x %fp0,%fp2 5950 fmul.x %fp0,%fp2 # SP3 5951 5951 5952 fadd.d TANQ3(%pc),%fp3 5952 fadd.d TANQ3(%pc),%fp3 # Q3+SQ4 5953 fadd.x TANP2(%pc),%fp2 5953 fadd.x TANP2(%pc),%fp2 # P2+SP3 5954 5954 5955 fmul.x %fp0,%fp3 5955 fmul.x %fp0,%fp3 # S(Q3+SQ4) 5956 fmul.x %fp0,%fp2 5956 fmul.x %fp0,%fp2 # S(P2+SP3) 5957 5957 5958 fadd.x TANQ2(%pc),%fp3 5958 fadd.x TANQ2(%pc),%fp3 # Q2+S(Q3+SQ4) 5959 fadd.x TANP1(%pc),%fp2 5959 fadd.x TANP1(%pc),%fp2 # P1+S(P2+SP3) 5960 5960 5961 fmul.x %fp0,%fp3 5961 fmul.x %fp0,%fp3 # S(Q2+S(Q3+SQ4)) 5962 fmul.x %fp0,%fp2 5962 fmul.x %fp0,%fp2 # S(P1+S(P2+SP3)) 5963 5963 5964 fadd.x TANQ1(%pc),%fp3 5964 fadd.x TANQ1(%pc),%fp3 # Q1+S(Q2+S(Q3+SQ4)) 5965 fmul.x %fp1,%fp2 5965 fmul.x %fp1,%fp2 # RS(P1+S(P2+SP3)) 5966 5966 5967 fmul.x %fp3,%fp0 5967 fmul.x %fp3,%fp0 # S(Q1+S(Q2+S(Q3+SQ4))) 5968 5968 5969 fadd.x %fp2,%fp1 5969 fadd.x %fp2,%fp1 # R+RS(P1+S(P2+SP3)) 5970 fadd.s &0x3F800000,%fp0 5970 fadd.s &0x3F800000,%fp0 # 1+S(Q1+...) 5971 5971 5972 fmovm.x (%sp)+,&0x30 5972 fmovm.x (%sp)+,&0x30 # restore fp2,fp3 5973 5973 5974 fmov.x %fp1,-(%sp) 5974 fmov.x %fp1,-(%sp) 5975 eor.l &0x80000000,(%sp) 5975 eor.l &0x80000000,(%sp) 5976 5976 5977 fmov.l %d0,%fpcr 5977 fmov.l %d0,%fpcr # restore users round mode,prec 5978 fdiv.x (%sp)+,%fp0 5978 fdiv.x (%sp)+,%fp0 # last inst - possible exception set 5979 bra t_inx2 5979 bra t_inx2 5980 5980 5981 TANBORS: 5981 TANBORS: 5982 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT 5982 #--IF |X| > 15PI, WE USE THE GENERAL ARGUMENT REDUCTION. 5983 #--IF |X| < 2**(-40), RETURN X OR 1. 5983 #--IF |X| < 2**(-40), RETURN X OR 1. 5984 cmp.l %d1,&0x3FFF8000 5984 cmp.l %d1,&0x3FFF8000 5985 bgt.b REDUCEX 5985 bgt.b REDUCEX 5986 5986 5987 TANSM: 5987 TANSM: 5988 fmov.x %fp0,-(%sp) 5988 fmov.x %fp0,-(%sp) 5989 fmov.l %d0,%fpcr 5989 fmov.l %d0,%fpcr # restore users round mode,prec 5990 mov.b &FMOV_OP,%d1 5990 mov.b &FMOV_OP,%d1 # last inst is MOVE 5991 fmov.x (%sp)+,%fp0 5991 fmov.x (%sp)+,%fp0 # last inst - posibble exception set 5992 bra t_catch 5992 bra t_catch 5993 5993 5994 global stand 5994 global stand 5995 #--TAN(X) = X FOR DENORMALIZED X 5995 #--TAN(X) = X FOR DENORMALIZED X 5996 stand: 5996 stand: 5997 bra t_extdnrm 5997 bra t_extdnrm 5998 5998 5999 #--WHEN REDUCEX IS USED, THE CODE WILL INEVIT 5999 #--WHEN REDUCEX IS USED, THE CODE WILL INEVITABLY BE SLOW. 6000 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FA 6000 #--THIS REDUCTION METHOD, HOWEVER, IS MUCH FASTER THAN USING 6001 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN 6001 #--THE REMAINDER INSTRUCTION WHICH IS NOW IN SOFTWARE. 6002 REDUCEX: 6002 REDUCEX: 6003 fmovm.x &0x3c,-(%sp) 6003 fmovm.x &0x3c,-(%sp) # save {fp2-fp5} 6004 mov.l %d2,-(%sp) 6004 mov.l %d2,-(%sp) # save d2 6005 fmov.s &0x00000000,%fp1 6005 fmov.s &0x00000000,%fp1 # fp1 = 0 6006 6006 6007 #--If compact form of abs(arg) in d0=$7ffefff 6007 #--If compact form of abs(arg) in d0=$7ffeffff, argument is so large that 6008 #--there is a danger of unwanted overflow in 6008 #--there is a danger of unwanted overflow in first LOOP iteration. In this 6009 #--case, reduce argument by one remainder ste 6009 #--case, reduce argument by one remainder step to make subsequent reduction 6010 #--safe. 6010 #--safe. 6011 cmp.l %d1,&0x7ffeffff 6011 cmp.l %d1,&0x7ffeffff # is arg dangerously large? 6012 bne.b LOOP 6012 bne.b LOOP # no 6013 6013 6014 # yes; create 2**16383*PI/2 6014 # yes; create 2**16383*PI/2 6015 mov.w &0x7ffe,FP_SCR0_EX(%a 6015 mov.w &0x7ffe,FP_SCR0_EX(%a6) 6016 mov.l &0xc90fdaa2,FP_SCR0_H 6016 mov.l &0xc90fdaa2,FP_SCR0_HI(%a6) 6017 clr.l FP_SCR0_LO(%a6) 6017 clr.l FP_SCR0_LO(%a6) 6018 6018 6019 # create low half of 2**16383*PI/2 at FP_SCR1 6019 # create low half of 2**16383*PI/2 at FP_SCR1 6020 mov.w &0x7fdc,FP_SCR1_EX(%a 6020 mov.w &0x7fdc,FP_SCR1_EX(%a6) 6021 mov.l &0x85a308d3,FP_SCR1_H 6021 mov.l &0x85a308d3,FP_SCR1_HI(%a6) 6022 clr.l FP_SCR1_LO(%a6) 6022 clr.l FP_SCR1_LO(%a6) 6023 6023 6024 ftest.x %fp0 6024 ftest.x %fp0 # test sign of argument 6025 fblt.w red_neg 6025 fblt.w red_neg 6026 6026 6027 or.b &0x80,FP_SCR0_EX(%a6) 6027 or.b &0x80,FP_SCR0_EX(%a6) # positive arg 6028 or.b &0x80,FP_SCR1_EX(%a6) 6028 or.b &0x80,FP_SCR1_EX(%a6) 6029 red_neg: 6029 red_neg: 6030 fadd.x FP_SCR0(%a6),%fp0 6030 fadd.x FP_SCR0(%a6),%fp0 # high part of reduction is exact 6031 fmov.x %fp0,%fp1 6031 fmov.x %fp0,%fp1 # save high result in fp1 6032 fadd.x FP_SCR1(%a6),%fp0 6032 fadd.x FP_SCR1(%a6),%fp0 # low part of reduction 6033 fsub.x %fp0,%fp1 6033 fsub.x %fp0,%fp1 # determine low component of result 6034 fadd.x FP_SCR1(%a6),%fp1 6034 fadd.x FP_SCR1(%a6),%fp1 # fp0/fp1 are reduced argument. 6035 6035 6036 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X RE 6036 #--ON ENTRY, FP0 IS X, ON RETURN, FP0 IS X REM PI/2, |X| <= PI/4. 6037 #--integer quotient will be stored in N 6037 #--integer quotient will be stored in N 6038 #--Intermeditate remainder is 66-bit long; (R 6038 #--Intermeditate remainder is 66-bit long; (R,r) in (FP0,FP1) 6039 LOOP: 6039 LOOP: 6040 fmov.x %fp0,INARG(%a6) 6040 fmov.x %fp0,INARG(%a6) # +-2**K * F, 1 <= F < 2 6041 mov.w INARG(%a6),%d1 6041 mov.w INARG(%a6),%d1 6042 mov.l %d1,%a1 6042 mov.l %d1,%a1 # save a copy of D0 6043 and.l &0x00007FFF,%d1 6043 and.l &0x00007FFF,%d1 6044 sub.l &0x00003FFF,%d1 6044 sub.l &0x00003FFF,%d1 # d0 = K 6045 cmp.l %d1,&28 6045 cmp.l %d1,&28 6046 ble.b LASTLOOP 6046 ble.b LASTLOOP 6047 CONTLOOP: 6047 CONTLOOP: 6048 sub.l &27,%d1 6048 sub.l &27,%d1 # d0 = L := K-27 6049 mov.b &0,ENDFLAG(%a6) 6049 mov.b &0,ENDFLAG(%a6) 6050 bra.b WORK 6050 bra.b WORK 6051 LASTLOOP: 6051 LASTLOOP: 6052 clr.l %d1 6052 clr.l %d1 # d0 = L := 0 6053 mov.b &1,ENDFLAG(%a6) 6053 mov.b &1,ENDFLAG(%a6) 6054 6054 6055 WORK: 6055 WORK: 6056 #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L 6056 #--FIND THE REMAINDER OF (R,r) W.R.T. 2**L * (PI/2). L IS SO CHOSEN 6057 #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 6057 #--THAT INT( X * (2/PI) / 2**(L) ) < 2**29. 6058 6058 6059 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(6 6059 #--CREATE 2**(-L) * (2/PI), SIGN(INARG)*2**(63), 6060 #--2**L * (PIby2_1), 2**L * (PIby2_2) 6060 #--2**L * (PIby2_1), 2**L * (PIby2_2) 6061 6061 6062 mov.l &0x00003FFE,%d2 6062 mov.l &0x00003FFE,%d2 # BIASED EXP OF 2/PI 6063 sub.l %d1,%d2 6063 sub.l %d1,%d2 # BIASED EXP OF 2**(-L)*(2/PI) 6064 6064 6065 mov.l &0xA2F9836E,FP_SCR0_H 6065 mov.l &0xA2F9836E,FP_SCR0_HI(%a6) 6066 mov.l &0x4E44152A,FP_SCR0_L 6066 mov.l &0x4E44152A,FP_SCR0_LO(%a6) 6067 mov.w %d2,FP_SCR0_EX(%a6) 6067 mov.w %d2,FP_SCR0_EX(%a6) # FP_SCR0 = 2**(-L)*(2/PI) 6068 6068 6069 fmov.x %fp0,%fp2 6069 fmov.x %fp0,%fp2 6070 fmul.x FP_SCR0(%a6),%fp2 6070 fmul.x FP_SCR0(%a6),%fp2 # fp2 = X * 2**(-L)*(2/PI) 6071 6071 6072 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED T 6072 #--WE MUST NOW FIND INT(FP2). SINCE WE NEED THIS VALUE IN 6073 #--FLOATING POINT FORMAT, THE TWO FMOVE'S 6073 #--FLOATING POINT FORMAT, THE TWO FMOVE'S FMOVE.L FP <--> N 6074 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT 6074 #--WILL BE TOO INEFFICIENT. THE WAY AROUND IT IS THAT 6075 #--(SIGN(INARG)*2**63 + FP2) - SIGN(I 6075 #--(SIGN(INARG)*2**63 + FP2) - SIGN(INARG)*2**63 WILL GIVE 6076 #--US THE DESIRED VALUE IN FLOATING POINT. 6076 #--US THE DESIRED VALUE IN FLOATING POINT. 6077 mov.l %a1,%d2 6077 mov.l %a1,%d2 6078 swap %d2 6078 swap %d2 6079 and.l &0x80000000,%d2 6079 and.l &0x80000000,%d2 6080 or.l &0x5F000000,%d2 6080 or.l &0x5F000000,%d2 # d2 = SIGN(INARG)*2**63 IN SGL 6081 mov.l %d2,TWOTO63(%a6) 6081 mov.l %d2,TWOTO63(%a6) 6082 fadd.s TWOTO63(%a6),%fp2 6082 fadd.s TWOTO63(%a6),%fp2 # THE FRACTIONAL PART OF FP1 IS ROUNDED 6083 fsub.s TWOTO63(%a6),%fp2 6083 fsub.s TWOTO63(%a6),%fp2 # fp2 = N 6084 # fintrz.x %fp2,%fp2 6084 # fintrz.x %fp2,%fp2 6085 6085 6086 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 6086 #--CREATING 2**(L)*Piby2_1 and 2**(L)*Piby2_2 6087 mov.l %d1,%d2 6087 mov.l %d1,%d2 # d2 = L 6088 6088 6089 add.l &0x00003FFF,%d2 6089 add.l &0x00003FFF,%d2 # BIASED EXP OF 2**L * (PI/2) 6090 mov.w %d2,FP_SCR0_EX(%a6) 6090 mov.w %d2,FP_SCR0_EX(%a6) 6091 mov.l &0xC90FDAA2,FP_SCR0_H 6091 mov.l &0xC90FDAA2,FP_SCR0_HI(%a6) 6092 clr.l FP_SCR0_LO(%a6) 6092 clr.l FP_SCR0_LO(%a6) # FP_SCR0 = 2**(L) * Piby2_1 6093 6093 6094 add.l &0x00003FDD,%d1 6094 add.l &0x00003FDD,%d1 6095 mov.w %d1,FP_SCR1_EX(%a6) 6095 mov.w %d1,FP_SCR1_EX(%a6) 6096 mov.l &0x85A308D3,FP_SCR1_H 6096 mov.l &0x85A308D3,FP_SCR1_HI(%a6) 6097 clr.l FP_SCR1_LO(%a6) 6097 clr.l FP_SCR1_LO(%a6) # FP_SCR1 = 2**(L) * Piby2_2 6098 6098 6099 mov.b ENDFLAG(%a6),%d1 6099 mov.b ENDFLAG(%a6),%d1 6100 6100 6101 #--We are now ready to perform (R+r) - N*P1 - 6101 #--We are now ready to perform (R+r) - N*P1 - N*P2, P1 = 2**(L) * Piby2_1 and 6102 #--P2 = 2**(L) * Piby2_2 6102 #--P2 = 2**(L) * Piby2_2 6103 fmov.x %fp2,%fp4 6103 fmov.x %fp2,%fp4 # fp4 = N 6104 fmul.x FP_SCR0(%a6),%fp4 6104 fmul.x FP_SCR0(%a6),%fp4 # fp4 = W = N*P1 6105 fmov.x %fp2,%fp5 6105 fmov.x %fp2,%fp5 # fp5 = N 6106 fmul.x FP_SCR1(%a6),%fp5 6106 fmul.x FP_SCR1(%a6),%fp5 # fp5 = w = N*P2 6107 fmov.x %fp4,%fp3 6107 fmov.x %fp4,%fp3 # fp3 = W = N*P1 6108 6108 6109 #--we want P+p = W+w but |p| <= half ulp of 6109 #--we want P+p = W+w but |p| <= half ulp of P 6110 #--Then, we need to compute A := R-P and 6110 #--Then, we need to compute A := R-P and a := r-p 6111 fadd.x %fp5,%fp3 6111 fadd.x %fp5,%fp3 # fp3 = P 6112 fsub.x %fp3,%fp4 6112 fsub.x %fp3,%fp4 # fp4 = W-P 6113 6113 6114 fsub.x %fp3,%fp0 6114 fsub.x %fp3,%fp0 # fp0 = A := R - P 6115 fadd.x %fp5,%fp4 6115 fadd.x %fp5,%fp4 # fp4 = p = (W-P)+w 6116 6116 6117 fmov.x %fp0,%fp3 6117 fmov.x %fp0,%fp3 # fp3 = A 6118 fsub.x %fp4,%fp1 6118 fsub.x %fp4,%fp1 # fp1 = a := r - p 6119 6119 6120 #--Now we need to normalize (A,a) to "new (R 6120 #--Now we need to normalize (A,a) to "new (R,r)" where R+r = A+a but 6121 #--|r| <= half ulp of R. 6121 #--|r| <= half ulp of R. 6122 fadd.x %fp1,%fp0 6122 fadd.x %fp1,%fp0 # fp0 = R := A+a 6123 #--No need to calculate r if this is the last 6123 #--No need to calculate r if this is the last loop 6124 cmp.b %d1,&0 6124 cmp.b %d1,&0 6125 bgt.w RESTORE 6125 bgt.w RESTORE 6126 6126 6127 #--Need to calculate r 6127 #--Need to calculate r 6128 fsub.x %fp0,%fp3 6128 fsub.x %fp0,%fp3 # fp3 = A-R 6129 fadd.x %fp3,%fp1 6129 fadd.x %fp3,%fp1 # fp1 = r := (A-R)+a 6130 bra.w LOOP 6130 bra.w LOOP 6131 6131 6132 RESTORE: 6132 RESTORE: 6133 fmov.l %fp2,INT(%a6) 6133 fmov.l %fp2,INT(%a6) 6134 mov.l (%sp)+,%d2 6134 mov.l (%sp)+,%d2 # restore d2 6135 fmovm.x (%sp)+,&0x3c 6135 fmovm.x (%sp)+,&0x3c # restore {fp2-fp5} 6136 6136 6137 mov.l INT(%a6),%d1 6137 mov.l INT(%a6),%d1 6138 ror.l &1,%d1 6138 ror.l &1,%d1 6139 6139 6140 bra.w TANCONT 6140 bra.w TANCONT 6141 6141 6142 ############################################# 6142 ######################################################################### 6143 # satan(): computes the arctangent of a norm 6143 # satan(): computes the arctangent of a normalized number # 6144 # satand(): computes the arctangent of a deno 6144 # satand(): computes the arctangent of a denormalized number # 6145 # 6145 # # 6146 # INPUT ************************************* 6146 # INPUT *************************************************************** # 6147 # a0 = pointer to extended precision in 6147 # a0 = pointer to extended precision input # 6148 # d0 = round precision,mode 6148 # d0 = round precision,mode # 6149 # 6149 # # 6150 # OUTPUT ************************************ 6150 # OUTPUT ************************************************************** # 6151 # fp0 = arctan(X) 6151 # fp0 = arctan(X) # 6152 # 6152 # # 6153 # ACCURACY and MONOTONICITY ***************** 6153 # ACCURACY and MONOTONICITY ******************************************* # 6154 # The returned result is within 2 ulps 6154 # The returned result is within 2 ulps in 64 significant bit, # 6155 # i.e. within 0.5001 ulp to 53 bits if 6155 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6156 # rounded to double precision. The resu 6156 # rounded to double precision. The result is provably monotonic # 6157 # in double precision. 6157 # in double precision. # 6158 # 6158 # # 6159 # ALGORITHM ********************************* 6159 # ALGORITHM *********************************************************** # 6160 # Step 1. If |X| >= 16 or |X| < 1/16, g 6160 # Step 1. If |X| >= 16 or |X| < 1/16, go to Step 5. # 6161 # 6161 # # 6162 # Step 2. Let X = sgn * 2**k * 1.xxxxxx 6162 # Step 2. Let X = sgn * 2**k * 1.xxxxxxxx...x. # 6163 # Note that k = -4, -3,..., or 6163 # Note that k = -4, -3,..., or 3. # 6164 # Define F = sgn * 2**k * 1.xxx 6164 # Define F = sgn * 2**k * 1.xxxx1, i.e. the first 5 # 6165 # significant bits of X with a 6165 # significant bits of X with a bit-1 attached at the 6-th # 6166 # bit position. Define u to be 6166 # bit position. Define u to be u = (X-F) / (1 + X*F). # 6167 # 6167 # # 6168 # Step 3. Approximate arctan(u) by a po 6168 # Step 3. Approximate arctan(u) by a polynomial poly. # 6169 # 6169 # # 6170 # Step 4. Return arctan(F) + poly, arct 6170 # Step 4. Return arctan(F) + poly, arctan(F) is fetched from a # 6171 # table of values calculated be 6171 # table of values calculated beforehand. Exit. # 6172 # 6172 # # 6173 # Step 5. If |X| >= 16, go to Step 7. 6173 # Step 5. If |X| >= 16, go to Step 7. # 6174 # 6174 # # 6175 # Step 6. Approximate arctan(X) by an o 6175 # Step 6. Approximate arctan(X) by an odd polynomial in X. Exit. # 6176 # 6176 # # 6177 # Step 7. Define X' = -1/X. Approximate 6177 # Step 7. Define X' = -1/X. Approximate arctan(X') by an odd # 6178 # polynomial in X'. 6178 # polynomial in X'. # 6179 # Arctan(X) = sign(X)*Pi/2 + ar 6179 # Arctan(X) = sign(X)*Pi/2 + arctan(X'). Exit. # 6180 # 6180 # # 6181 ############################################# 6181 ######################################################################### 6182 6182 6183 ATANA3: long 0xBFF6687E,0x314987D8 6183 ATANA3: long 0xBFF6687E,0x314987D8 6184 ATANA2: long 0x4002AC69,0x34A26DB3 6184 ATANA2: long 0x4002AC69,0x34A26DB3 6185 ATANA1: long 0xBFC2476F,0x4E1DA28E 6185 ATANA1: long 0xBFC2476F,0x4E1DA28E 6186 6186 6187 ATANB6: long 0x3FB34444,0x7F876989 6187 ATANB6: long 0x3FB34444,0x7F876989 6188 ATANB5: long 0xBFB744EE,0x7FAF45DB 6188 ATANB5: long 0xBFB744EE,0x7FAF45DB 6189 ATANB4: long 0x3FBC71C6,0x46940220 6189 ATANB4: long 0x3FBC71C6,0x46940220 6190 ATANB3: long 0xBFC24924,0x921872F9 6190 ATANB3: long 0xBFC24924,0x921872F9 6191 ATANB2: long 0x3FC99999,0x99998FA9 6191 ATANB2: long 0x3FC99999,0x99998FA9 6192 ATANB1: long 0xBFD55555,0x55555555 6192 ATANB1: long 0xBFD55555,0x55555555 6193 6193 6194 ATANC5: long 0xBFB70BF3,0x98539E6A 6194 ATANC5: long 0xBFB70BF3,0x98539E6A 6195 ATANC4: long 0x3FBC7187,0x962D1D7D 6195 ATANC4: long 0x3FBC7187,0x962D1D7D 6196 ATANC3: long 0xBFC24924,0x827107B8 6196 ATANC3: long 0xBFC24924,0x827107B8 6197 ATANC2: long 0x3FC99999,0x9996263E 6197 ATANC2: long 0x3FC99999,0x9996263E 6198 ATANC1: long 0xBFD55555,0x55555536 6198 ATANC1: long 0xBFD55555,0x55555536 6199 6199 6200 PPIBY2: long 0x3FFF0000,0xC90FDAA2 6200 PPIBY2: long 0x3FFF0000,0xC90FDAA2,0x2168C235,0x00000000 6201 NPIBY2: long 0xBFFF0000,0xC90FDAA2 6201 NPIBY2: long 0xBFFF0000,0xC90FDAA2,0x2168C235,0x00000000 6202 6202 6203 PTINY: long 0x00010000,0x80000000 6203 PTINY: long 0x00010000,0x80000000,0x00000000,0x00000000 6204 NTINY: long 0x80010000,0x80000000 6204 NTINY: long 0x80010000,0x80000000,0x00000000,0x00000000 6205 6205 6206 ATANTBL: 6206 ATANTBL: 6207 long 0x3FFB0000,0x83D152C5 6207 long 0x3FFB0000,0x83D152C5,0x060B7A51,0x00000000 6208 long 0x3FFB0000,0x8BC85445 6208 long 0x3FFB0000,0x8BC85445,0x65498B8B,0x00000000 6209 long 0x3FFB0000,0x93BE4060 6209 long 0x3FFB0000,0x93BE4060,0x17626B0D,0x00000000 6210 long 0x3FFB0000,0x9BB3078D 6210 long 0x3FFB0000,0x9BB3078D,0x35AEC202,0x00000000 6211 long 0x3FFB0000,0xA3A69A52 6211 long 0x3FFB0000,0xA3A69A52,0x5DDCE7DE,0x00000000 6212 long 0x3FFB0000,0xAB98E943 6212 long 0x3FFB0000,0xAB98E943,0x62765619,0x00000000 6213 long 0x3FFB0000,0xB389E502 6213 long 0x3FFB0000,0xB389E502,0xF9C59862,0x00000000 6214 long 0x3FFB0000,0xBB797E43 6214 long 0x3FFB0000,0xBB797E43,0x6B09E6FB,0x00000000 6215 long 0x3FFB0000,0xC367A5C7 6215 long 0x3FFB0000,0xC367A5C7,0x39E5F446,0x00000000 6216 long 0x3FFB0000,0xCB544C61 6216 long 0x3FFB0000,0xCB544C61,0xCFF7D5C6,0x00000000 6217 long 0x3FFB0000,0xD33F62F8 6217 long 0x3FFB0000,0xD33F62F8,0x2488533E,0x00000000 6218 long 0x3FFB0000,0xDB28DA81 6218 long 0x3FFB0000,0xDB28DA81,0x62404C77,0x00000000 6219 long 0x3FFB0000,0xE310A407 6219 long 0x3FFB0000,0xE310A407,0x8AD34F18,0x00000000 6220 long 0x3FFB0000,0xEAF6B0A8 6220 long 0x3FFB0000,0xEAF6B0A8,0x188EE1EB,0x00000000 6221 long 0x3FFB0000,0xF2DAF194 6221 long 0x3FFB0000,0xF2DAF194,0x9DBE79D5,0x00000000 6222 long 0x3FFB0000,0xFABD5813 6222 long 0x3FFB0000,0xFABD5813,0x61D47E3E,0x00000000 6223 long 0x3FFC0000,0x8346AC21 6223 long 0x3FFC0000,0x8346AC21,0x0959ECC4,0x00000000 6224 long 0x3FFC0000,0x8B232A08 6224 long 0x3FFC0000,0x8B232A08,0x304282D8,0x00000000 6225 long 0x3FFC0000,0x92FB70B8 6225 long 0x3FFC0000,0x92FB70B8,0xD29AE2F9,0x00000000 6226 long 0x3FFC0000,0x9ACF476F 6226 long 0x3FFC0000,0x9ACF476F,0x5CCD1CB4,0x00000000 6227 long 0x3FFC0000,0xA29E7630 6227 long 0x3FFC0000,0xA29E7630,0x4954F23F,0x00000000 6228 long 0x3FFC0000,0xAA68C5D0 6228 long 0x3FFC0000,0xAA68C5D0,0x8AB85230,0x00000000 6229 long 0x3FFC0000,0xB22DFFFD 6229 long 0x3FFC0000,0xB22DFFFD,0x9D539F83,0x00000000 6230 long 0x3FFC0000,0xB9EDEF45 6230 long 0x3FFC0000,0xB9EDEF45,0x3E900EA5,0x00000000 6231 long 0x3FFC0000,0xC1A85F1C 6231 long 0x3FFC0000,0xC1A85F1C,0xC75E3EA5,0x00000000 6232 long 0x3FFC0000,0xC95D1BE8 6232 long 0x3FFC0000,0xC95D1BE8,0x28138DE6,0x00000000 6233 long 0x3FFC0000,0xD10BF300 6233 long 0x3FFC0000,0xD10BF300,0x840D2DE4,0x00000000 6234 long 0x3FFC0000,0xD8B4B2BA 6234 long 0x3FFC0000,0xD8B4B2BA,0x6BC05E7A,0x00000000 6235 long 0x3FFC0000,0xE0572A6B 6235 long 0x3FFC0000,0xE0572A6B,0xB42335F6,0x00000000 6236 long 0x3FFC0000,0xE7F32A70 6236 long 0x3FFC0000,0xE7F32A70,0xEA9CAA8F,0x00000000 6237 long 0x3FFC0000,0xEF888432 6237 long 0x3FFC0000,0xEF888432,0x64ECEFAA,0x00000000 6238 long 0x3FFC0000,0xF7170A28 6238 long 0x3FFC0000,0xF7170A28,0xECC06666,0x00000000 6239 long 0x3FFD0000,0x812FD288 6239 long 0x3FFD0000,0x812FD288,0x332DAD32,0x00000000 6240 long 0x3FFD0000,0x88A8D1B1 6240 long 0x3FFD0000,0x88A8D1B1,0x218E4D64,0x00000000 6241 long 0x3FFD0000,0x9012AB3F 6241 long 0x3FFD0000,0x9012AB3F,0x23E4AEE8,0x00000000 6242 long 0x3FFD0000,0x976CC3D4 6242 long 0x3FFD0000,0x976CC3D4,0x11E7F1B9,0x00000000 6243 long 0x3FFD0000,0x9EB68949 6243 long 0x3FFD0000,0x9EB68949,0x3889A227,0x00000000 6244 long 0x3FFD0000,0xA5EF72C3 6244 long 0x3FFD0000,0xA5EF72C3,0x4487361B,0x00000000 6245 long 0x3FFD0000,0xAD1700BA 6245 long 0x3FFD0000,0xAD1700BA,0xF07A7227,0x00000000 6246 long 0x3FFD0000,0xB42CBCFA 6246 long 0x3FFD0000,0xB42CBCFA,0xFD37EFB7,0x00000000 6247 long 0x3FFD0000,0xBB303A94 6247 long 0x3FFD0000,0xBB303A94,0x0BA80F89,0x00000000 6248 long 0x3FFD0000,0xC22115C6 6248 long 0x3FFD0000,0xC22115C6,0xFCAEBBAF,0x00000000 6249 long 0x3FFD0000,0xC8FEF3E6 6249 long 0x3FFD0000,0xC8FEF3E6,0x86331221,0x00000000 6250 long 0x3FFD0000,0xCFC98330 6250 long 0x3FFD0000,0xCFC98330,0xB4000C70,0x00000000 6251 long 0x3FFD0000,0xD6807AA1 6251 long 0x3FFD0000,0xD6807AA1,0x102C5BF9,0x00000000 6252 long 0x3FFD0000,0xDD2399BC 6252 long 0x3FFD0000,0xDD2399BC,0x31252AA3,0x00000000 6253 long 0x3FFD0000,0xE3B2A855 6253 long 0x3FFD0000,0xE3B2A855,0x6B8FC517,0x00000000 6254 long 0x3FFD0000,0xEA2D764F 6254 long 0x3FFD0000,0xEA2D764F,0x64315989,0x00000000 6255 long 0x3FFD0000,0xF3BF5BF8 6255 long 0x3FFD0000,0xF3BF5BF8,0xBAD1A21D,0x00000000 6256 long 0x3FFE0000,0x801CE39E 6256 long 0x3FFE0000,0x801CE39E,0x0D205C9A,0x00000000 6257 long 0x3FFE0000,0x8630A2DA 6257 long 0x3FFE0000,0x8630A2DA,0xDA1ED066,0x00000000 6258 long 0x3FFE0000,0x8C1AD445 6258 long 0x3FFE0000,0x8C1AD445,0xF3E09B8C,0x00000000 6259 long 0x3FFE0000,0x91DB8F16 6259 long 0x3FFE0000,0x91DB8F16,0x64F350E2,0x00000000 6260 long 0x3FFE0000,0x97731420 6260 long 0x3FFE0000,0x97731420,0x365E538C,0x00000000 6261 long 0x3FFE0000,0x9CE1C8E6 6261 long 0x3FFE0000,0x9CE1C8E6,0xA0B8CDBA,0x00000000 6262 long 0x3FFE0000,0xA22832DB 6262 long 0x3FFE0000,0xA22832DB,0xCADAAE09,0x00000000 6263 long 0x3FFE0000,0xA746F2DD 6263 long 0x3FFE0000,0xA746F2DD,0xB7602294,0x00000000 6264 long 0x3FFE0000,0xAC3EC0FB 6264 long 0x3FFE0000,0xAC3EC0FB,0x997DD6A2,0x00000000 6265 long 0x3FFE0000,0xB110688A 6265 long 0x3FFE0000,0xB110688A,0xEBDC6F6A,0x00000000 6266 long 0x3FFE0000,0xB5BCC490 6266 long 0x3FFE0000,0xB5BCC490,0x59ECC4B0,0x00000000 6267 long 0x3FFE0000,0xBA44BC7D 6267 long 0x3FFE0000,0xBA44BC7D,0xD470782F,0x00000000 6268 long 0x3FFE0000,0xBEA94144 6268 long 0x3FFE0000,0xBEA94144,0xFD049AAC,0x00000000 6269 long 0x3FFE0000,0xC2EB4ABB 6269 long 0x3FFE0000,0xC2EB4ABB,0x661628B6,0x00000000 6270 long 0x3FFE0000,0xC70BD54C 6270 long 0x3FFE0000,0xC70BD54C,0xE602EE14,0x00000000 6271 long 0x3FFE0000,0xCD000549 6271 long 0x3FFE0000,0xCD000549,0xADEC7159,0x00000000 6272 long 0x3FFE0000,0xD48457D2 6272 long 0x3FFE0000,0xD48457D2,0xD8EA4EA3,0x00000000 6273 long 0x3FFE0000,0xDB948DA7 6273 long 0x3FFE0000,0xDB948DA7,0x12DECE3B,0x00000000 6274 long 0x3FFE0000,0xE23855F9 6274 long 0x3FFE0000,0xE23855F9,0x69E8096A,0x00000000 6275 long 0x3FFE0000,0xE8771129 6275 long 0x3FFE0000,0xE8771129,0xC4353259,0x00000000 6276 long 0x3FFE0000,0xEE57C16E 6276 long 0x3FFE0000,0xEE57C16E,0x0D379C0D,0x00000000 6277 long 0x3FFE0000,0xF3E10211 6277 long 0x3FFE0000,0xF3E10211,0xA87C3779,0x00000000 6278 long 0x3FFE0000,0xF919039D 6278 long 0x3FFE0000,0xF919039D,0x758B8D41,0x00000000 6279 long 0x3FFE0000,0xFE058B8F 6279 long 0x3FFE0000,0xFE058B8F,0x64935FB3,0x00000000 6280 long 0x3FFF0000,0x8155FB49 6280 long 0x3FFF0000,0x8155FB49,0x7B685D04,0x00000000 6281 long 0x3FFF0000,0x83889E35 6281 long 0x3FFF0000,0x83889E35,0x49D108E1,0x00000000 6282 long 0x3FFF0000,0x859CFA76 6282 long 0x3FFF0000,0x859CFA76,0x511D724B,0x00000000 6283 long 0x3FFF0000,0x87952ECF 6283 long 0x3FFF0000,0x87952ECF,0xFF8131E7,0x00000000 6284 long 0x3FFF0000,0x89732FD1 6284 long 0x3FFF0000,0x89732FD1,0x9557641B,0x00000000 6285 long 0x3FFF0000,0x8B38CAD1 6285 long 0x3FFF0000,0x8B38CAD1,0x01932A35,0x00000000 6286 long 0x3FFF0000,0x8CE7A8D8 6286 long 0x3FFF0000,0x8CE7A8D8,0x301EE6B5,0x00000000 6287 long 0x3FFF0000,0x8F46A39E 6287 long 0x3FFF0000,0x8F46A39E,0x2EAE5281,0x00000000 6288 long 0x3FFF0000,0x922DA7D7 6288 long 0x3FFF0000,0x922DA7D7,0x91888487,0x00000000 6289 long 0x3FFF0000,0x94D19FCB 6289 long 0x3FFF0000,0x94D19FCB,0xDEDF5241,0x00000000 6290 long 0x3FFF0000,0x973AB944 6290 long 0x3FFF0000,0x973AB944,0x19D2A08B,0x00000000 6291 long 0x3FFF0000,0x996FF00E 6291 long 0x3FFF0000,0x996FF00E,0x08E10B96,0x00000000 6292 long 0x3FFF0000,0x9B773F95 6292 long 0x3FFF0000,0x9B773F95,0x12321DA7,0x00000000 6293 long 0x3FFF0000,0x9D55CC32 6293 long 0x3FFF0000,0x9D55CC32,0x0F935624,0x00000000 6294 long 0x3FFF0000,0x9F100575 6294 long 0x3FFF0000,0x9F100575,0x006CC571,0x00000000 6295 long 0x3FFF0000,0xA0A9C290 6295 long 0x3FFF0000,0xA0A9C290,0xD97CC06C,0x00000000 6296 long 0x3FFF0000,0xA22659EB 6296 long 0x3FFF0000,0xA22659EB,0xEBC0630A,0x00000000 6297 long 0x3FFF0000,0xA388B4AF 6297 long 0x3FFF0000,0xA388B4AF,0xF6EF0EC9,0x00000000 6298 long 0x3FFF0000,0xA4D35F10 6298 long 0x3FFF0000,0xA4D35F10,0x61D292C4,0x00000000 6299 long 0x3FFF0000,0xA60895DC 6299 long 0x3FFF0000,0xA60895DC,0xFBE3187E,0x00000000 6300 long 0x3FFF0000,0xA72A51DC 6300 long 0x3FFF0000,0xA72A51DC,0x7367BEAC,0x00000000 6301 long 0x3FFF0000,0xA83A5153 6301 long 0x3FFF0000,0xA83A5153,0x0956168F,0x00000000 6302 long 0x3FFF0000,0xA93A2007 6302 long 0x3FFF0000,0xA93A2007,0x7539546E,0x00000000 6303 long 0x3FFF0000,0xAA9E7245 6303 long 0x3FFF0000,0xAA9E7245,0x023B2605,0x00000000 6304 long 0x3FFF0000,0xAC4C84BA 6304 long 0x3FFF0000,0xAC4C84BA,0x6FE4D58F,0x00000000 6305 long 0x3FFF0000,0xADCE4A4A 6305 long 0x3FFF0000,0xADCE4A4A,0x606B9712,0x00000000 6306 long 0x3FFF0000,0xAF2A2DCD 6306 long 0x3FFF0000,0xAF2A2DCD,0x8D263C9C,0x00000000 6307 long 0x3FFF0000,0xB0656F81 6307 long 0x3FFF0000,0xB0656F81,0xF22265C7,0x00000000 6308 long 0x3FFF0000,0xB1846515 6308 long 0x3FFF0000,0xB1846515,0x0F71496A,0x00000000 6309 long 0x3FFF0000,0xB28AAA15 6309 long 0x3FFF0000,0xB28AAA15,0x6F9ADA35,0x00000000 6310 long 0x3FFF0000,0xB37B44FF 6310 long 0x3FFF0000,0xB37B44FF,0x3766B895,0x00000000 6311 long 0x3FFF0000,0xB458C3DC 6311 long 0x3FFF0000,0xB458C3DC,0xE9630433,0x00000000 6312 long 0x3FFF0000,0xB525529D 6312 long 0x3FFF0000,0xB525529D,0x562246BD,0x00000000 6313 long 0x3FFF0000,0xB5E2CCA9 6313 long 0x3FFF0000,0xB5E2CCA9,0x5F9D88CC,0x00000000 6314 long 0x3FFF0000,0xB692CADA 6314 long 0x3FFF0000,0xB692CADA,0x7ACA1ADA,0x00000000 6315 long 0x3FFF0000,0xB736AEA7 6315 long 0x3FFF0000,0xB736AEA7,0xA6925838,0x00000000 6316 long 0x3FFF0000,0xB7CFAB28 6316 long 0x3FFF0000,0xB7CFAB28,0x7E9F7B36,0x00000000 6317 long 0x3FFF0000,0xB85ECC66 6317 long 0x3FFF0000,0xB85ECC66,0xCB219835,0x00000000 6318 long 0x3FFF0000,0xB8E4FD5A 6318 long 0x3FFF0000,0xB8E4FD5A,0x20A593DA,0x00000000 6319 long 0x3FFF0000,0xB99F41F6 6319 long 0x3FFF0000,0xB99F41F6,0x4AFF9BB5,0x00000000 6320 long 0x3FFF0000,0xBA7F1E17 6320 long 0x3FFF0000,0xBA7F1E17,0x842BBE7B,0x00000000 6321 long 0x3FFF0000,0xBB471285 6321 long 0x3FFF0000,0xBB471285,0x7637E17D,0x00000000 6322 long 0x3FFF0000,0xBBFABE8A 6322 long 0x3FFF0000,0xBBFABE8A,0x4788DF6F,0x00000000 6323 long 0x3FFF0000,0xBC9D0FAD 6323 long 0x3FFF0000,0xBC9D0FAD,0x2B689D79,0x00000000 6324 long 0x3FFF0000,0xBD306A39 6324 long 0x3FFF0000,0xBD306A39,0x471ECD86,0x00000000 6325 long 0x3FFF0000,0xBDB6C731 6325 long 0x3FFF0000,0xBDB6C731,0x856AF18A,0x00000000 6326 long 0x3FFF0000,0xBE31CAC5 6326 long 0x3FFF0000,0xBE31CAC5,0x02E80D70,0x00000000 6327 long 0x3FFF0000,0xBEA2D55C 6327 long 0x3FFF0000,0xBEA2D55C,0xE33194E2,0x00000000 6328 long 0x3FFF0000,0xBF0B10B7 6328 long 0x3FFF0000,0xBF0B10B7,0xC03128F0,0x00000000 6329 long 0x3FFF0000,0xBF6B7A18 6329 long 0x3FFF0000,0xBF6B7A18,0xDACB778D,0x00000000 6330 long 0x3FFF0000,0xBFC4EA46 6330 long 0x3FFF0000,0xBFC4EA46,0x63FA18F6,0x00000000 6331 long 0x3FFF0000,0xC0181BDE 6331 long 0x3FFF0000,0xC0181BDE,0x8B89A454,0x00000000 6332 long 0x3FFF0000,0xC065B066 6332 long 0x3FFF0000,0xC065B066,0xCFBF6439,0x00000000 6333 long 0x3FFF0000,0xC0AE345F 6333 long 0x3FFF0000,0xC0AE345F,0x56340AE6,0x00000000 6334 long 0x3FFF0000,0xC0F22291 6334 long 0x3FFF0000,0xC0F22291,0x9CB9E6A7,0x00000000 6335 6335 6336 set X,FP_SCR0 6336 set X,FP_SCR0 6337 set XDCARE,X+2 6337 set XDCARE,X+2 6338 set XFRAC,X+4 6338 set XFRAC,X+4 6339 set XFRACLO,X+8 6339 set XFRACLO,X+8 6340 6340 6341 set ATANF,FP_SCR1 6341 set ATANF,FP_SCR1 6342 set ATANFHI,ATANF+4 6342 set ATANFHI,ATANF+4 6343 set ATANFLO,ATANF+8 6343 set ATANFLO,ATANF+8 6344 6344 6345 global satan 6345 global satan 6346 #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, 6346 #--ENTRY POINT FOR ATAN(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 6347 satan: 6347 satan: 6348 fmov.x (%a0),%fp0 6348 fmov.x (%a0),%fp0 # LOAD INPUT 6349 6349 6350 mov.l (%a0),%d1 6350 mov.l (%a0),%d1 6351 mov.w 4(%a0),%d1 6351 mov.w 4(%a0),%d1 6352 fmov.x %fp0,X(%a6) 6352 fmov.x %fp0,X(%a6) 6353 and.l &0x7FFFFFFF,%d1 6353 and.l &0x7FFFFFFF,%d1 6354 6354 6355 cmp.l %d1,&0x3FFB8000 6355 cmp.l %d1,&0x3FFB8000 # |X| >= 1/16? 6356 bge.b ATANOK1 6356 bge.b ATANOK1 6357 bra.w ATANSM 6357 bra.w ATANSM 6358 6358 6359 ATANOK1: 6359 ATANOK1: 6360 cmp.l %d1,&0x4002FFFF 6360 cmp.l %d1,&0x4002FFFF # |X| < 16 ? 6361 ble.b ATANMAIN 6361 ble.b ATANMAIN 6362 bra.w ATANBIG 6362 bra.w ATANBIG 6363 6363 6364 #--THE MOST LIKELY CASE, |X| IN [1/16, 16). W 6364 #--THE MOST LIKELY CASE, |X| IN [1/16, 16). WE USE TABLE TECHNIQUE 6365 #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F 6365 #--THE IDEA IS ATAN(X) = ATAN(F) + ATAN( [X-F] / [1+XF] ). 6366 #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATA 6366 #--SO IF F IS CHOSEN TO BE CLOSE TO X AND ATAN(F) IS STORED IN 6367 #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATA 6367 #--A TABLE, ALL WE NEED IS TO APPROXIMATE ATAN(U) WHERE 6368 #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS C 6368 #--U = (X-F)/(1+XF) IS SMALL (REMEMBER F IS CLOSE TO X). IT IS 6369 #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE 6369 #--TRUE THAT A DIVIDE IS NOW NEEDED, BUT THE APPROXIMATION FOR 6370 #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE 6370 #--ATAN(U) IS A VERY SHORT POLYNOMIAL AND THE INDEXING TO 6371 #--FETCH F AND SAVING OF REGISTERS CAN BE ALL 6371 #--FETCH F AND SAVING OF REGISTERS CAN BE ALL HIDED UNDER THE 6372 #--DIVIDE. IN THE END THIS METHOD IS MUCH FAS 6372 #--DIVIDE. IN THE END THIS METHOD IS MUCH FASTER THAN A TRADITIONAL 6373 #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME 6373 #--ONE. NOTE ALSO THAT THE TRADITIONAL SCHEME THAT APPROXIMATE 6374 #--ATAN(X) DIRECTLY WILL NEED TO USE A RATION 6374 #--ATAN(X) DIRECTLY WILL NEED TO USE A RATIONAL APPROXIMATION 6375 #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOM 6375 #--(DIVISION NEEDED) ANYWAY BECAUSE A POLYNOMIAL APPROXIMATION 6376 #--WILL INVOLVE A VERY LONG POLYNOMIAL. 6376 #--WILL INVOLVE A VERY LONG POLYNOMIAL. 6377 6377 6378 #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 6378 #--NOW WE SEE X AS +-2^K * 1.BBBBBBB....B <- 1. + 63 BITS 6379 #--WE CHOSE F TO BE +-2^K * 1.BBBB1 6379 #--WE CHOSE F TO BE +-2^K * 1.BBBB1 6380 #--THAT IS IT MATCHES THE EXPONENT AND FIRST 6380 #--THAT IS IT MATCHES THE EXPONENT AND FIRST 5 BITS OF X, THE 6381 #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, - 6381 #--SIXTH BITS IS SET TO BE 1. SINCE K = -4, -3, ..., 3, THERE 6382 #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SIN 6382 #--ARE ONLY 8 TIMES 16 = 2^7 = 128 |F|'S. SINCE ATAN(-|F|) IS 6383 #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F 6383 #-- -ATAN(|F|), WE NEED TO STORE ONLY ATAN(|F|). 6384 6384 6385 ATANMAIN: 6385 ATANMAIN: 6386 6386 6387 and.l &0xF8000000,XFRAC(%a6 6387 and.l &0xF8000000,XFRAC(%a6) # FIRST 5 BITS 6388 or.l &0x04000000,XFRAC(%a6 6388 or.l &0x04000000,XFRAC(%a6) # SET 6-TH BIT TO 1 6389 mov.l &0x00000000,XFRACLO(% 6389 mov.l &0x00000000,XFRACLO(%a6) # LOCATION OF X IS NOW F 6390 6390 6391 fmov.x %fp0,%fp1 6391 fmov.x %fp0,%fp1 # FP1 IS X 6392 fmul.x X(%a6),%fp1 6392 fmul.x X(%a6),%fp1 # FP1 IS X*F, NOTE THAT X*F > 0 6393 fsub.x X(%a6),%fp0 6393 fsub.x X(%a6),%fp0 # FP0 IS X-F 6394 fadd.s &0x3F800000,%fp1 6394 fadd.s &0x3F800000,%fp1 # FP1 IS 1 + X*F 6395 fdiv.x %fp1,%fp0 6395 fdiv.x %fp1,%fp0 # FP0 IS U = (X-F)/(1+X*F) 6396 6396 6397 #--WHILE THE DIVISION IS TAKING ITS TIME, WE 6397 #--WHILE THE DIVISION IS TAKING ITS TIME, WE FETCH ATAN(|F|) 6398 #--CREATE ATAN(F) AND STORE IT IN ATANF, AND 6398 #--CREATE ATAN(F) AND STORE IT IN ATANF, AND 6399 #--SAVE REGISTERS FP2. 6399 #--SAVE REGISTERS FP2. 6400 6400 6401 mov.l %d2,-(%sp) 6401 mov.l %d2,-(%sp) # SAVE d2 TEMPORARILY 6402 mov.l %d1,%d2 6402 mov.l %d1,%d2 # THE EXP AND 16 BITS OF X 6403 and.l &0x00007800,%d1 6403 and.l &0x00007800,%d1 # 4 VARYING BITS OF F'S FRACTION 6404 and.l &0x7FFF0000,%d2 6404 and.l &0x7FFF0000,%d2 # EXPONENT OF F 6405 sub.l &0x3FFB0000,%d2 6405 sub.l &0x3FFB0000,%d2 # K+4 6406 asr.l &1,%d2 6406 asr.l &1,%d2 6407 add.l %d2,%d1 6407 add.l %d2,%d1 # THE 7 BITS IDENTIFYING F 6408 asr.l &7,%d1 6408 asr.l &7,%d1 # INDEX INTO TBL OF ATAN(|F|) 6409 lea ATANTBL(%pc),%a1 6409 lea ATANTBL(%pc),%a1 6410 add.l %d1,%a1 6410 add.l %d1,%a1 # ADDRESS OF ATAN(|F|) 6411 mov.l (%a1)+,ATANF(%a6) 6411 mov.l (%a1)+,ATANF(%a6) 6412 mov.l (%a1)+,ATANFHI(%a6) 6412 mov.l (%a1)+,ATANFHI(%a6) 6413 mov.l (%a1)+,ATANFLO(%a6) 6413 mov.l (%a1)+,ATANFLO(%a6) # ATANF IS NOW ATAN(|F|) 6414 mov.l X(%a6),%d1 6414 mov.l X(%a6),%d1 # LOAD SIGN AND EXPO. AGAIN 6415 and.l &0x80000000,%d1 6415 and.l &0x80000000,%d1 # SIGN(F) 6416 or.l %d1,ATANF(%a6) 6416 or.l %d1,ATANF(%a6) # ATANF IS NOW SIGN(F)*ATAN(|F|) 6417 mov.l (%sp)+,%d2 6417 mov.l (%sp)+,%d2 # RESTORE d2 6418 6418 6419 #--THAT'S ALL I HAVE TO DO FOR NOW, 6419 #--THAT'S ALL I HAVE TO DO FOR NOW, 6420 #--BUT ALAS, THE DIVIDE IS STILL CRANKING! 6420 #--BUT ALAS, THE DIVIDE IS STILL CRANKING! 6421 6421 6422 #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN 6422 #--U IN FP0, WE ARE NOW READY TO COMPUTE ATAN(U) AS 6423 #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U 6423 #--U + A1*U*V*(A2 + V*(A3 + V)), V = U*U 6424 #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NE 6424 #--THE POLYNOMIAL MAY LOOK STRANGE, BUT IS NEVERTHELESS CORRECT. 6425 #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + 6425 #--THE NATURAL FORM IS U + U*V*(A1 + V*(A2 + V*A3)) 6426 #--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = 6426 #--WHAT WE HAVE HERE IS MERELY A1 = A3, A2 = A1/A3, A3 = A2/A3. 6427 #--THE REASON FOR THIS REARRANGEMENT IS TO MA 6427 #--THE REASON FOR THIS REARRANGEMENT IS TO MAKE THE INDEPENDENT 6428 #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOA 6428 #--PARTS A1*U*V AND (A2 + ... STUFF) MORE LOAD-BALANCED 6429 6429 6430 fmovm.x &0x04,-(%sp) 6430 fmovm.x &0x04,-(%sp) # save fp2 6431 6431 6432 fmov.x %fp0,%fp1 6432 fmov.x %fp0,%fp1 6433 fmul.x %fp1,%fp1 6433 fmul.x %fp1,%fp1 6434 fmov.d ATANA3(%pc),%fp2 6434 fmov.d ATANA3(%pc),%fp2 6435 fadd.x %fp1,%fp2 6435 fadd.x %fp1,%fp2 # A3+V 6436 fmul.x %fp1,%fp2 6436 fmul.x %fp1,%fp2 # V*(A3+V) 6437 fmul.x %fp0,%fp1 6437 fmul.x %fp0,%fp1 # U*V 6438 fadd.d ATANA2(%pc),%fp2 6438 fadd.d ATANA2(%pc),%fp2 # A2+V*(A3+V) 6439 fmul.d ATANA1(%pc),%fp1 6439 fmul.d ATANA1(%pc),%fp1 # A1*U*V 6440 fmul.x %fp2,%fp1 6440 fmul.x %fp2,%fp1 # A1*U*V*(A2+V*(A3+V)) 6441 fadd.x %fp1,%fp0 6441 fadd.x %fp1,%fp0 # ATAN(U), FP1 RELEASED 6442 6442 6443 fmovm.x (%sp)+,&0x20 6443 fmovm.x (%sp)+,&0x20 # restore fp2 6444 6444 6445 fmov.l %d0,%fpcr 6445 fmov.l %d0,%fpcr # restore users rnd mode,prec 6446 fadd.x ATANF(%a6),%fp0 6446 fadd.x ATANF(%a6),%fp0 # ATAN(X) 6447 bra t_inx2 6447 bra t_inx2 6448 6448 6449 ATANBORS: 6449 ATANBORS: 6450 #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVE 6450 #--|X| IS IN d0 IN COMPACT FORM. FP1, d0 SAVED. 6451 #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16. 6451 #--FP0 IS X AND |X| <= 1/16 OR |X| >= 16. 6452 cmp.l %d1,&0x3FFF8000 6452 cmp.l %d1,&0x3FFF8000 6453 bgt.w ATANBIG 6453 bgt.w ATANBIG # I.E. |X| >= 16 6454 6454 6455 ATANSM: 6455 ATANSM: 6456 #--|X| <= 1/16 6456 #--|X| <= 1/16 6457 #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHE 6457 #--IF |X| < 2^(-40), RETURN X AS ANSWER. OTHERWISE, APPROXIMATE 6458 #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y 6458 #--ATAN(X) BY X + X*Y*(B1+Y*(B2+Y*(B3+Y*(B4+Y*(B5+Y*B6))))) 6459 #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*( 6459 #--WHICH IS X + X*Y*( [B1+Z*(B3+Z*B5)] + [Y*(B2+Z*(B4+Z*B6)] ) 6460 #--WHERE Y = X*X, AND Z = Y*Y. 6460 #--WHERE Y = X*X, AND Z = Y*Y. 6461 6461 6462 cmp.l %d1,&0x3FD78000 6462 cmp.l %d1,&0x3FD78000 6463 blt.w ATANTINY 6463 blt.w ATANTINY 6464 6464 6465 #--COMPUTE POLYNOMIAL 6465 #--COMPUTE POLYNOMIAL 6466 fmovm.x &0x0c,-(%sp) 6466 fmovm.x &0x0c,-(%sp) # save fp2/fp3 6467 6467 6468 fmul.x %fp0,%fp0 6468 fmul.x %fp0,%fp0 # FPO IS Y = X*X 6469 6469 6470 fmov.x %fp0,%fp1 6470 fmov.x %fp0,%fp1 6471 fmul.x %fp1,%fp1 6471 fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 6472 6472 6473 fmov.d ATANB6(%pc),%fp2 6473 fmov.d ATANB6(%pc),%fp2 6474 fmov.d ATANB5(%pc),%fp3 6474 fmov.d ATANB5(%pc),%fp3 6475 6475 6476 fmul.x %fp1,%fp2 6476 fmul.x %fp1,%fp2 # Z*B6 6477 fmul.x %fp1,%fp3 6477 fmul.x %fp1,%fp3 # Z*B5 6478 6478 6479 fadd.d ATANB4(%pc),%fp2 6479 fadd.d ATANB4(%pc),%fp2 # B4+Z*B6 6480 fadd.d ATANB3(%pc),%fp3 6480 fadd.d ATANB3(%pc),%fp3 # B3+Z*B5 6481 6481 6482 fmul.x %fp1,%fp2 6482 fmul.x %fp1,%fp2 # Z*(B4+Z*B6) 6483 fmul.x %fp3,%fp1 6483 fmul.x %fp3,%fp1 # Z*(B3+Z*B5) 6484 6484 6485 fadd.d ATANB2(%pc),%fp2 6485 fadd.d ATANB2(%pc),%fp2 # B2+Z*(B4+Z*B6) 6486 fadd.d ATANB1(%pc),%fp1 6486 fadd.d ATANB1(%pc),%fp1 # B1+Z*(B3+Z*B5) 6487 6487 6488 fmul.x %fp0,%fp2 6488 fmul.x %fp0,%fp2 # Y*(B2+Z*(B4+Z*B6)) 6489 fmul.x X(%a6),%fp0 6489 fmul.x X(%a6),%fp0 # X*Y 6490 6490 6491 fadd.x %fp2,%fp1 6491 fadd.x %fp2,%fp1 # [B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))] 6492 6492 6493 fmul.x %fp1,%fp0 6493 fmul.x %fp1,%fp0 # X*Y*([B1+Z*(B3+Z*B5)]+[Y*(B2+Z*(B4+Z*B6))]) 6494 6494 6495 fmovm.x (%sp)+,&0x30 6495 fmovm.x (%sp)+,&0x30 # restore fp2/fp3 6496 6496 6497 fmov.l %d0,%fpcr 6497 fmov.l %d0,%fpcr # restore users rnd mode,prec 6498 fadd.x X(%a6),%fp0 6498 fadd.x X(%a6),%fp0 6499 bra t_inx2 6499 bra t_inx2 6500 6500 6501 ATANTINY: 6501 ATANTINY: 6502 #--|X| < 2^(-40), ATAN(X) = X 6502 #--|X| < 2^(-40), ATAN(X) = X 6503 6503 6504 fmov.l %d0,%fpcr 6504 fmov.l %d0,%fpcr # restore users rnd mode,prec 6505 mov.b &FMOV_OP,%d1 6505 mov.b &FMOV_OP,%d1 # last inst is MOVE 6506 fmov.x X(%a6),%fp0 6506 fmov.x X(%a6),%fp0 # last inst - possible exception set 6507 6507 6508 bra t_catch 6508 bra t_catch 6509 6509 6510 ATANBIG: 6510 ATANBIG: 6511 #--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 6511 #--IF |X| > 2^(100), RETURN SIGN(X)*(PI/2 - TINY). OTHERWISE, 6512 #--RETURN SIGN(X)*PI/2 + ATAN(-1/X). 6512 #--RETURN SIGN(X)*PI/2 + ATAN(-1/X). 6513 cmp.l %d1,&0x40638000 6513 cmp.l %d1,&0x40638000 6514 bgt.w ATANHUGE 6514 bgt.w ATANHUGE 6515 6515 6516 #--APPROXIMATE ATAN(-1/X) BY 6516 #--APPROXIMATE ATAN(-1/X) BY 6517 #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' 6517 #--X'+X'*Y*(C1+Y*(C2+Y*(C3+Y*(C4+Y*C5)))), X' = -1/X, Y = X'*X' 6518 #--THIS CAN BE RE-WRITTEN AS 6518 #--THIS CAN BE RE-WRITTEN AS 6519 #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] 6519 #--X'+X'*Y*( [C1+Z*(C3+Z*C5)] + [Y*(C2+Z*C4)] ), Z = Y*Y. 6520 6520 6521 fmovm.x &0x0c,-(%sp) 6521 fmovm.x &0x0c,-(%sp) # save fp2/fp3 6522 6522 6523 fmov.s &0xBF800000,%fp1 6523 fmov.s &0xBF800000,%fp1 # LOAD -1 6524 fdiv.x %fp0,%fp1 6524 fdiv.x %fp0,%fp1 # FP1 IS -1/X 6525 6525 6526 #--DIVIDE IS STILL CRANKING 6526 #--DIVIDE IS STILL CRANKING 6527 6527 6528 fmov.x %fp1,%fp0 6528 fmov.x %fp1,%fp0 # FP0 IS X' 6529 fmul.x %fp0,%fp0 6529 fmul.x %fp0,%fp0 # FP0 IS Y = X'*X' 6530 fmov.x %fp1,X(%a6) 6530 fmov.x %fp1,X(%a6) # X IS REALLY X' 6531 6531 6532 fmov.x %fp0,%fp1 6532 fmov.x %fp0,%fp1 6533 fmul.x %fp1,%fp1 6533 fmul.x %fp1,%fp1 # FP1 IS Z = Y*Y 6534 6534 6535 fmov.d ATANC5(%pc),%fp3 6535 fmov.d ATANC5(%pc),%fp3 6536 fmov.d ATANC4(%pc),%fp2 6536 fmov.d ATANC4(%pc),%fp2 6537 6537 6538 fmul.x %fp1,%fp3 6538 fmul.x %fp1,%fp3 # Z*C5 6539 fmul.x %fp1,%fp2 6539 fmul.x %fp1,%fp2 # Z*B4 6540 6540 6541 fadd.d ATANC3(%pc),%fp3 6541 fadd.d ATANC3(%pc),%fp3 # C3+Z*C5 6542 fadd.d ATANC2(%pc),%fp2 6542 fadd.d ATANC2(%pc),%fp2 # C2+Z*C4 6543 6543 6544 fmul.x %fp3,%fp1 6544 fmul.x %fp3,%fp1 # Z*(C3+Z*C5), FP3 RELEASED 6545 fmul.x %fp0,%fp2 6545 fmul.x %fp0,%fp2 # Y*(C2+Z*C4) 6546 6546 6547 fadd.d ATANC1(%pc),%fp1 6547 fadd.d ATANC1(%pc),%fp1 # C1+Z*(C3+Z*C5) 6548 fmul.x X(%a6),%fp0 6548 fmul.x X(%a6),%fp0 # X'*Y 6549 6549 6550 fadd.x %fp2,%fp1 6550 fadd.x %fp2,%fp1 # [Y*(C2+Z*C4)]+[C1+Z*(C3+Z*C5)] 6551 6551 6552 fmul.x %fp1,%fp0 6552 fmul.x %fp1,%fp0 # X'*Y*([B1+Z*(B3+Z*B5)] 6553 # ... 6553 # ... +[Y*(B2+Z*(B4+Z*B6))]) 6554 fadd.x X(%a6),%fp0 6554 fadd.x X(%a6),%fp0 6555 6555 6556 fmovm.x (%sp)+,&0x30 6556 fmovm.x (%sp)+,&0x30 # restore fp2/fp3 6557 6557 6558 fmov.l %d0,%fpcr 6558 fmov.l %d0,%fpcr # restore users rnd mode,prec 6559 tst.b (%a0) 6559 tst.b (%a0) 6560 bpl.b pos_big 6560 bpl.b pos_big 6561 6561 6562 neg_big: 6562 neg_big: 6563 fadd.x NPIBY2(%pc),%fp0 6563 fadd.x NPIBY2(%pc),%fp0 6564 bra t_minx2 6564 bra t_minx2 6565 6565 6566 pos_big: 6566 pos_big: 6567 fadd.x PPIBY2(%pc),%fp0 6567 fadd.x PPIBY2(%pc),%fp0 6568 bra t_pinx2 6568 bra t_pinx2 6569 6569 6570 ATANHUGE: 6570 ATANHUGE: 6571 #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PI 6571 #--RETURN SIGN(X)*(PIBY2 - TINY) = SIGN(X)*PIBY2 - SIGN(X)*TINY 6572 tst.b (%a0) 6572 tst.b (%a0) 6573 bpl.b pos_huge 6573 bpl.b pos_huge 6574 6574 6575 neg_huge: 6575 neg_huge: 6576 fmov.x NPIBY2(%pc),%fp0 6576 fmov.x NPIBY2(%pc),%fp0 6577 fmov.l %d0,%fpcr 6577 fmov.l %d0,%fpcr 6578 fadd.x PTINY(%pc),%fp0 6578 fadd.x PTINY(%pc),%fp0 6579 bra t_minx2 6579 bra t_minx2 6580 6580 6581 pos_huge: 6581 pos_huge: 6582 fmov.x PPIBY2(%pc),%fp0 6582 fmov.x PPIBY2(%pc),%fp0 6583 fmov.l %d0,%fpcr 6583 fmov.l %d0,%fpcr 6584 fadd.x NTINY(%pc),%fp0 6584 fadd.x NTINY(%pc),%fp0 6585 bra t_pinx2 6585 bra t_pinx2 6586 6586 6587 global satand 6587 global satand 6588 #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED A 6588 #--ENTRY POINT FOR ATAN(X) FOR DENORMALIZED ARGUMENT 6589 satand: 6589 satand: 6590 bra t_extdnrm 6590 bra t_extdnrm 6591 6591 6592 ############################################# 6592 ######################################################################### 6593 # sasin(): computes the inverse sine of a no 6593 # sasin(): computes the inverse sine of a normalized input # 6594 # sasind(): computes the inverse sine of a de 6594 # sasind(): computes the inverse sine of a denormalized input # 6595 # 6595 # # 6596 # INPUT ************************************* 6596 # INPUT *************************************************************** # 6597 # a0 = pointer to extended precision in 6597 # a0 = pointer to extended precision input # 6598 # d0 = round precision,mode 6598 # d0 = round precision,mode # 6599 # 6599 # # 6600 # OUTPUT ************************************ 6600 # OUTPUT ************************************************************** # 6601 # fp0 = arcsin(X) 6601 # fp0 = arcsin(X) # 6602 # 6602 # # 6603 # ACCURACY and MONOTONICITY ***************** 6603 # ACCURACY and MONOTONICITY ******************************************* # 6604 # The returned result is within 3 ulps 6604 # The returned result is within 3 ulps in 64 significant bit, # 6605 # i.e. within 0.5001 ulp to 53 bits if 6605 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6606 # rounded to double precision. The resu 6606 # rounded to double precision. The result is provably monotonic # 6607 # in double precision. 6607 # in double precision. # 6608 # 6608 # # 6609 # ALGORITHM ********************************* 6609 # ALGORITHM *********************************************************** # 6610 # 6610 # # 6611 # ASIN 6611 # ASIN # 6612 # 1. If |X| >= 1, go to 3. 6612 # 1. If |X| >= 1, go to 3. # 6613 # 6613 # # 6614 # 2. (|X| < 1) Calculate asin(X) by 6614 # 2. (|X| < 1) Calculate asin(X) by # 6615 # z := sqrt( [1-X][1+X] ) 6615 # z := sqrt( [1-X][1+X] ) # 6616 # asin(X) = atan( x / z ). 6616 # asin(X) = atan( x / z ). # 6617 # Exit. 6617 # Exit. # 6618 # 6618 # # 6619 # 3. If |X| > 1, go to 5. 6619 # 3. If |X| > 1, go to 5. # 6620 # 6620 # # 6621 # 4. (|X| = 1) sgn := sign(X), return a 6621 # 4. (|X| = 1) sgn := sign(X), return asin(X) := sgn * Pi/2. Exit.# 6622 # 6622 # # 6623 # 5. (|X| > 1) Generate an invalid oper 6623 # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 6624 # Exit. 6624 # Exit. # 6625 # 6625 # # 6626 ############################################# 6626 ######################################################################### 6627 6627 6628 global sasin 6628 global sasin 6629 sasin: 6629 sasin: 6630 fmov.x (%a0),%fp0 6630 fmov.x (%a0),%fp0 # LOAD INPUT 6631 6631 6632 mov.l (%a0),%d1 6632 mov.l (%a0),%d1 6633 mov.w 4(%a0),%d1 6633 mov.w 4(%a0),%d1 6634 and.l &0x7FFFFFFF,%d1 6634 and.l &0x7FFFFFFF,%d1 6635 cmp.l %d1,&0x3FFF8000 6635 cmp.l %d1,&0x3FFF8000 6636 bge.b ASINBIG 6636 bge.b ASINBIG 6637 6637 6638 # This catch is added here for the '060 QSP. 6638 # This catch is added here for the '060 QSP. Originally, the call to 6639 # satan() would handle this case by causing t 6639 # satan() would handle this case by causing the exception which would 6640 # not be caught until gen_except(). Now, with 6640 # not be caught until gen_except(). Now, with the exceptions being 6641 # detected inside of satan(), the exception w 6641 # detected inside of satan(), the exception would have been handled there 6642 # instead of inside sasin() as expected. 6642 # instead of inside sasin() as expected. 6643 cmp.l %d1,&0x3FD78000 6643 cmp.l %d1,&0x3FD78000 6644 blt.w ASINTINY 6644 blt.w ASINTINY 6645 6645 6646 #--THIS IS THE USUAL CASE, |X| < 1 6646 #--THIS IS THE USUAL CASE, |X| < 1 6647 #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) ) 6647 #--ASIN(X) = ATAN( X / SQRT( (1-X)(1+X) ) ) 6648 6648 6649 ASINMAIN: 6649 ASINMAIN: 6650 fmov.s &0x3F800000,%fp1 6650 fmov.s &0x3F800000,%fp1 6651 fsub.x %fp0,%fp1 6651 fsub.x %fp0,%fp1 # 1-X 6652 fmovm.x &0x4,-(%sp) 6652 fmovm.x &0x4,-(%sp) # {fp2} 6653 fmov.s &0x3F800000,%fp2 6653 fmov.s &0x3F800000,%fp2 6654 fadd.x %fp0,%fp2 6654 fadd.x %fp0,%fp2 # 1+X 6655 fmul.x %fp2,%fp1 6655 fmul.x %fp2,%fp1 # (1+X)(1-X) 6656 fmovm.x (%sp)+,&0x20 6656 fmovm.x (%sp)+,&0x20 # {fp2} 6657 fsqrt.x %fp1 6657 fsqrt.x %fp1 # SQRT([1-X][1+X]) 6658 fdiv.x %fp1,%fp0 6658 fdiv.x %fp1,%fp0 # X/SQRT([1-X][1+X]) 6659 fmovm.x &0x01,-(%sp) 6659 fmovm.x &0x01,-(%sp) # save X/SQRT(...) 6660 lea (%sp),%a0 6660 lea (%sp),%a0 # pass ptr to X/SQRT(...) 6661 bsr satan 6661 bsr satan 6662 add.l &0xc,%sp 6662 add.l &0xc,%sp # clear X/SQRT(...) from stack 6663 bra t_inx2 6663 bra t_inx2 6664 6664 6665 ASINBIG: 6665 ASINBIG: 6666 fabs.x %fp0 6666 fabs.x %fp0 # |X| 6667 fcmp.s %fp0,&0x3F800000 6667 fcmp.s %fp0,&0x3F800000 6668 fbgt t_operr 6668 fbgt t_operr # cause an operr exception 6669 6669 6670 #--|X| = 1, ASIN(X) = +- PI/2. 6670 #--|X| = 1, ASIN(X) = +- PI/2. 6671 ASINONE: 6671 ASINONE: 6672 fmov.x PIBY2(%pc),%fp0 6672 fmov.x PIBY2(%pc),%fp0 6673 mov.l (%a0),%d1 6673 mov.l (%a0),%d1 6674 and.l &0x80000000,%d1 6674 and.l &0x80000000,%d1 # SIGN BIT OF X 6675 or.l &0x3F800000,%d1 6675 or.l &0x3F800000,%d1 # +-1 IN SGL FORMAT 6676 mov.l %d1,-(%sp) 6676 mov.l %d1,-(%sp) # push SIGN(X) IN SGL-FMT 6677 fmov.l %d0,%fpcr 6677 fmov.l %d0,%fpcr 6678 fmul.s (%sp)+,%fp0 6678 fmul.s (%sp)+,%fp0 6679 bra t_inx2 6679 bra t_inx2 6680 6680 6681 #--|X| < 2^(-40), ATAN(X) = X 6681 #--|X| < 2^(-40), ATAN(X) = X 6682 ASINTINY: 6682 ASINTINY: 6683 fmov.l %d0,%fpcr 6683 fmov.l %d0,%fpcr # restore users rnd mode,prec 6684 mov.b &FMOV_OP,%d1 6684 mov.b &FMOV_OP,%d1 # last inst is MOVE 6685 fmov.x (%a0),%fp0 6685 fmov.x (%a0),%fp0 # last inst - possible exception 6686 bra t_catch 6686 bra t_catch 6687 6687 6688 global sasind 6688 global sasind 6689 #--ASIN(X) = X FOR DENORMALIZED X 6689 #--ASIN(X) = X FOR DENORMALIZED X 6690 sasind: 6690 sasind: 6691 bra t_extdnrm 6691 bra t_extdnrm 6692 6692 6693 ############################################# 6693 ######################################################################### 6694 # sacos(): computes the inverse cosine of a 6694 # sacos(): computes the inverse cosine of a normalized input # 6695 # sacosd(): computes the inverse cosine of a 6695 # sacosd(): computes the inverse cosine of a denormalized input # 6696 # 6696 # # 6697 # INPUT ************************************* 6697 # INPUT *************************************************************** # 6698 # a0 = pointer to extended precision in 6698 # a0 = pointer to extended precision input # 6699 # d0 = round precision,mode 6699 # d0 = round precision,mode # 6700 # 6700 # # 6701 # OUTPUT ************************************ 6701 # OUTPUT ************************************************************** # 6702 # fp0 = arccos(X) 6702 # fp0 = arccos(X) # 6703 # 6703 # # 6704 # ACCURACY and MONOTONICITY ***************** 6704 # ACCURACY and MONOTONICITY ******************************************* # 6705 # The returned result is within 3 ulps 6705 # The returned result is within 3 ulps in 64 significant bit, # 6706 # i.e. within 0.5001 ulp to 53 bits if 6706 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6707 # rounded to double precision. The resu 6707 # rounded to double precision. The result is provably monotonic # 6708 # in double precision. 6708 # in double precision. # 6709 # 6709 # # 6710 # ALGORITHM ********************************* 6710 # ALGORITHM *********************************************************** # 6711 # 6711 # # 6712 # ACOS 6712 # ACOS # 6713 # 1. If |X| >= 1, go to 3. 6713 # 1. If |X| >= 1, go to 3. # 6714 # 6714 # # 6715 # 2. (|X| < 1) Calculate acos(X) by 6715 # 2. (|X| < 1) Calculate acos(X) by # 6716 # z := (1-X) / (1+X) 6716 # z := (1-X) / (1+X) # 6717 # acos(X) = 2 * atan( sqrt(z) ) 6717 # acos(X) = 2 * atan( sqrt(z) ). # 6718 # Exit. 6718 # Exit. # 6719 # 6719 # # 6720 # 3. If |X| > 1, go to 5. 6720 # 3. If |X| > 1, go to 5. # 6721 # 6721 # # 6722 # 4. (|X| = 1) If X > 0, return 0. Othe 6722 # 4. (|X| = 1) If X > 0, return 0. Otherwise, return Pi. Exit. # 6723 # 6723 # # 6724 # 5. (|X| > 1) Generate an invalid oper 6724 # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 6725 # Exit. 6725 # Exit. # 6726 # 6726 # # 6727 ############################################# 6727 ######################################################################### 6728 6728 6729 global sacos 6729 global sacos 6730 sacos: 6730 sacos: 6731 fmov.x (%a0),%fp0 6731 fmov.x (%a0),%fp0 # LOAD INPUT 6732 6732 6733 mov.l (%a0),%d1 6733 mov.l (%a0),%d1 # pack exp w/ upper 16 fraction 6734 mov.w 4(%a0),%d1 6734 mov.w 4(%a0),%d1 6735 and.l &0x7FFFFFFF,%d1 6735 and.l &0x7FFFFFFF,%d1 6736 cmp.l %d1,&0x3FFF8000 6736 cmp.l %d1,&0x3FFF8000 6737 bge.b ACOSBIG 6737 bge.b ACOSBIG 6738 6738 6739 #--THIS IS THE USUAL CASE, |X| < 1 6739 #--THIS IS THE USUAL CASE, |X| < 1 6740 #--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) ) 6740 #--ACOS(X) = 2 * ATAN( SQRT( (1-X)/(1+X) ) ) 6741 6741 6742 ACOSMAIN: 6742 ACOSMAIN: 6743 fmov.s &0x3F800000,%fp1 6743 fmov.s &0x3F800000,%fp1 6744 fadd.x %fp0,%fp1 6744 fadd.x %fp0,%fp1 # 1+X 6745 fneg.x %fp0 6745 fneg.x %fp0 # -X 6746 fadd.s &0x3F800000,%fp0 6746 fadd.s &0x3F800000,%fp0 # 1-X 6747 fdiv.x %fp1,%fp0 6747 fdiv.x %fp1,%fp0 # (1-X)/(1+X) 6748 fsqrt.x %fp0 6748 fsqrt.x %fp0 # SQRT((1-X)/(1+X)) 6749 mov.l %d0,-(%sp) 6749 mov.l %d0,-(%sp) # save original users fpcr 6750 clr.l %d0 6750 clr.l %d0 6751 fmovm.x &0x01,-(%sp) 6751 fmovm.x &0x01,-(%sp) # save SQRT(...) to stack 6752 lea (%sp),%a0 6752 lea (%sp),%a0 # pass ptr to sqrt 6753 bsr satan 6753 bsr satan # ATAN(SQRT([1-X]/[1+X])) 6754 add.l &0xc,%sp 6754 add.l &0xc,%sp # clear SQRT(...) from stack 6755 6755 6756 fmov.l (%sp)+,%fpcr 6756 fmov.l (%sp)+,%fpcr # restore users round prec,mode 6757 fadd.x %fp0,%fp0 6757 fadd.x %fp0,%fp0 # 2 * ATAN( STUFF ) 6758 bra t_pinx2 6758 bra t_pinx2 6759 6759 6760 ACOSBIG: 6760 ACOSBIG: 6761 fabs.x %fp0 6761 fabs.x %fp0 6762 fcmp.s %fp0,&0x3F800000 6762 fcmp.s %fp0,&0x3F800000 6763 fbgt t_operr 6763 fbgt t_operr # cause an operr exception 6764 6764 6765 #--|X| = 1, ACOS(X) = 0 OR PI 6765 #--|X| = 1, ACOS(X) = 0 OR PI 6766 tst.b (%a0) 6766 tst.b (%a0) # is X positive or negative? 6767 bpl.b ACOSP1 6767 bpl.b ACOSP1 6768 6768 6769 #--X = -1 6769 #--X = -1 6770 #Returns PI and inexact exception 6770 #Returns PI and inexact exception 6771 ACOSM1: 6771 ACOSM1: 6772 fmov.x PI(%pc),%fp0 6772 fmov.x PI(%pc),%fp0 # load PI 6773 fmov.l %d0,%fpcr 6773 fmov.l %d0,%fpcr # load round mode,prec 6774 fadd.s &0x00800000,%fp0 6774 fadd.s &0x00800000,%fp0 # add a small value 6775 bra t_pinx2 6775 bra t_pinx2 6776 6776 6777 ACOSP1: 6777 ACOSP1: 6778 bra ld_pzero 6778 bra ld_pzero # answer is positive zero 6779 6779 6780 global sacosd 6780 global sacosd 6781 #--ACOS(X) = PI/2 FOR DENORMALIZED X 6781 #--ACOS(X) = PI/2 FOR DENORMALIZED X 6782 sacosd: 6782 sacosd: 6783 fmov.l %d0,%fpcr 6783 fmov.l %d0,%fpcr # load user's rnd mode/prec 6784 fmov.x PIBY2(%pc),%fp0 6784 fmov.x PIBY2(%pc),%fp0 6785 bra t_pinx2 6785 bra t_pinx2 6786 6786 6787 ############################################# 6787 ######################################################################### 6788 # setox(): computes the exponential for a 6788 # setox(): computes the exponential for a normalized input # 6789 # setoxd(): computes the exponential for a 6789 # setoxd(): computes the exponential for a denormalized input # 6790 # setoxm1(): computes the exponential minus 6790 # setoxm1(): computes the exponential minus 1 for a normalized input # 6791 # setoxm1d(): computes the exponential minus 6791 # setoxm1d(): computes the exponential minus 1 for a denormalized input # 6792 # 6792 # # 6793 # INPUT ************************************* 6793 # INPUT *************************************************************** # 6794 # a0 = pointer to extended precision in 6794 # a0 = pointer to extended precision input # 6795 # d0 = round precision,mode 6795 # d0 = round precision,mode # 6796 # 6796 # # 6797 # OUTPUT ************************************ 6797 # OUTPUT ************************************************************** # 6798 # fp0 = exp(X) or exp(X)-1 6798 # fp0 = exp(X) or exp(X)-1 # 6799 # 6799 # # 6800 # ACCURACY and MONOTONICITY ***************** 6800 # ACCURACY and MONOTONICITY ******************************************* # 6801 # The returned result is within 0.85 ul 6801 # The returned result is within 0.85 ulps in 64 significant bit, # 6802 # i.e. within 0.5001 ulp to 53 bits if 6802 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 6803 # rounded to double precision. The resu 6803 # rounded to double precision. The result is provably monotonic # 6804 # in double precision. 6804 # in double precision. # 6805 # 6805 # # 6806 # ALGORITHM and IMPLEMENTATION ************** 6806 # ALGORITHM and IMPLEMENTATION **************************************** # 6807 # 6807 # # 6808 # setoxd 6808 # setoxd # 6809 # ------ 6809 # ------ # 6810 # Step 1. Set ans := 1.0 6810 # Step 1. Set ans := 1.0 # 6811 # 6811 # # 6812 # Step 2. Return ans := ans + sign(X)* 6812 # Step 2. Return ans := ans + sign(X)*2^(-126). Exit. # 6813 # Notes: This will always generate one 6813 # Notes: This will always generate one exception -- inexact. # 6814 # 6814 # # 6815 # 6815 # # 6816 # setox 6816 # setox # 6817 # ----- 6817 # ----- # 6818 # 6818 # # 6819 # Step 1. Filter out extreme cases of i 6819 # Step 1. Filter out extreme cases of input argument. # 6820 # 1.1 If |X| >= 2^(-65), go 6820 # 1.1 If |X| >= 2^(-65), go to Step 1.3. # 6821 # 1.2 Go to Step 7. 6821 # 1.2 Go to Step 7. # 6822 # 1.3 If |X| < 16380 log(2) 6822 # 1.3 If |X| < 16380 log(2), go to Step 2. # 6823 # 1.4 Go to Step 8. 6823 # 1.4 Go to Step 8. # 6824 # Notes: The usual case should take th 6824 # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 6825 # To avoid the use of floating- 6825 # To avoid the use of floating-point comparisons, a # 6826 # compact representation of |X| 6826 # compact representation of |X| is used. This format is a # 6827 # 32-bit integer, the upper (mo 6827 # 32-bit integer, the upper (more significant) 16 bits # 6828 # are the sign and biased expon 6828 # are the sign and biased exponent field of |X|; the # 6829 # lower 16 bits are the 16 most 6829 # lower 16 bits are the 16 most significant fraction # 6830 # (including the explicit bit) 6830 # (including the explicit bit) bits of |X|. Consequently, # 6831 # the comparisons in Steps 1.1 6831 # the comparisons in Steps 1.1 and 1.3 can be performed # 6832 # by integer comparison. Note a 6832 # by integer comparison. Note also that the constant # 6833 # 16380 log(2) used in Step 1.3 6833 # 16380 log(2) used in Step 1.3 is also in the compact # 6834 # form. Thus taking the branch 6834 # form. Thus taking the branch to Step 2 guarantees # 6835 # |X| < 16380 log(2). There is 6835 # |X| < 16380 log(2). There is no harm to have a small # 6836 # number of cases where |X| is 6836 # number of cases where |X| is less than, but close to, # 6837 # 16380 log(2) and the branch t 6837 # 16380 log(2) and the branch to Step 9 is taken. # 6838 # 6838 # # 6839 # Step 2. Calculate N = round-to-neares 6839 # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 6840 # 2.1 Set AdjFlag := 0 (ind 6840 # 2.1 Set AdjFlag := 0 (indicates the branch 1.3 -> 2 # 6841 # was taken) 6841 # was taken) # 6842 # 2.2 N := round-to-nearest 6842 # 2.2 N := round-to-nearest-integer( X * 64/log2 ). # 6843 # 2.3 Calculate J = N 6843 # 2.3 Calculate J = N mod 64; so J = 0,1,2,..., # 6844 # or 63. 6844 # or 63. # 6845 # 2.4 Calculate M = ( 6845 # 2.4 Calculate M = (N - J)/64; so N = 64M + J. # 6846 # 2.5 Calculate the address 6846 # 2.5 Calculate the address of the stored value of # 6847 # 2^(J/64). 6847 # 2^(J/64). # 6848 # 2.6 Create the value Scal 6848 # 2.6 Create the value Scale = 2^M. # 6849 # Notes: The calculation in 2.2 is rea 6849 # Notes: The calculation in 2.2 is really performed by # 6850 # Z := X * constant 6850 # Z := X * constant # 6851 # N := round-to-nearest 6851 # N := round-to-nearest-integer(Z) # 6852 # where 6852 # where # 6853 # constant := single-pr 6853 # constant := single-precision( 64/log 2 ). # 6854 # 6854 # # 6855 # Using a single-precision cons 6855 # Using a single-precision constant avoids memory # 6856 # access. Another effect of usi 6856 # access. Another effect of using a single-precision # 6857 # "constant" is that the calcul 6857 # "constant" is that the calculated value Z is # 6858 # 6858 # # 6859 # Z = X*(64/log2)*(1+ep 6859 # Z = X*(64/log2)*(1+eps), |eps| <= 2^(-24). # 6860 # 6860 # # 6861 # This error has to be consider 6861 # This error has to be considered later in Steps 3 and 4. # 6862 # 6862 # # 6863 # Step 3. Calculate X - N*log2/64. 6863 # Step 3. Calculate X - N*log2/64. # 6864 # 3.1 R := X + N*L1, 6864 # 3.1 R := X + N*L1, # 6865 # where L1 := s 6865 # where L1 := single-precision(-log2/64). # 6866 # 3.2 R := R + N*L2, 6866 # 3.2 R := R + N*L2, # 6867 # L2 := extende 6867 # L2 := extended-precision(-log2/64 - L1).# 6868 # Notes: a) The way L1 and L2 are chos 6868 # Notes: a) The way L1 and L2 are chosen ensures L1+L2 # 6869 # approximate the value -log2/6 6869 # approximate the value -log2/64 to 88 bits of accuracy. # 6870 # b) N*L1 is exact because N is 6870 # b) N*L1 is exact because N is no longer than 22 bits # 6871 # and L1 is no longer than 24 b 6871 # and L1 is no longer than 24 bits. # 6872 # c) The calculation X+N*L1 is 6872 # c) The calculation X+N*L1 is also exact due to # 6873 # cancellation. Thus, R is prac 6873 # cancellation. Thus, R is practically X+N(L1+L2) to full # 6874 # 64 bits. 6874 # 64 bits. # 6875 # d) It is important to estimat 6875 # d) It is important to estimate how large can |R| be # 6876 # after Step 3.2. 6876 # after Step 3.2. # 6877 # 6877 # # 6878 # N = rnd-to-int( X*64/log2 (1+ 6878 # N = rnd-to-int( X*64/log2 (1+eps) ), |eps|<=2^(-24) # 6879 # X*64/log2 (1+eps) = 6879 # X*64/log2 (1+eps) = N + f, |f| <= 0.5 # 6880 # X*64/log2 - N = f - e 6880 # X*64/log2 - N = f - eps*X 64/log2 # 6881 # X - N*log2/64 = f*log 6881 # X - N*log2/64 = f*log2/64 - eps*X # 6882 # 6882 # # 6883 # 6883 # # 6884 # Now |X| <= 16446 log2, thus 6884 # Now |X| <= 16446 log2, thus # 6885 # 6885 # # 6886 # |X - N*log2/64| <= (0 6886 # |X - N*log2/64| <= (0.5 + 16446/2^(18))*log2/64 # 6887 # <= 0. 6887 # <= 0.57 log2/64. # 6888 # This bound will be used in S 6888 # This bound will be used in Step 4. # 6889 # 6889 # # 6890 # Step 4. Approximate exp(R)-1 by a pol 6890 # Step 4. Approximate exp(R)-1 by a polynomial # 6891 # p = R + R*R*(A1 + R*(A2 + R*( 6891 # p = R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) # 6892 # Notes: a) In order to reduce memory 6892 # Notes: a) In order to reduce memory access, the coefficients # 6893 # are made as "short" as possib 6893 # are made as "short" as possible: A1 (which is 1/2), A4 # 6894 # and A5 are single precision; 6894 # and A5 are single precision; A2 and A3 are double # 6895 # precision. 6895 # precision. # 6896 # b) Even with the restrictions 6896 # b) Even with the restrictions above, # 6897 # |p - (exp(R)-1)| < 2^(-68. 6897 # |p - (exp(R)-1)| < 2^(-68.8) for all |R| <= 0.0062. # 6898 # Note that 0.0062 is slightly 6898 # Note that 0.0062 is slightly bigger than 0.57 log2/64. # 6899 # c) To fully utilize the pipel 6899 # c) To fully utilize the pipeline, p is separated into # 6900 # two independent pieces of rou 6900 # two independent pieces of roughly equal complexities # 6901 # p = [ R + R*S*(A2 + S 6901 # p = [ R + R*S*(A2 + S*A4) ] + # 6902 # [ S*(A1 + S*( 6902 # [ S*(A1 + S*(A3 + S*A5)) ] # 6903 # where S = R*R. 6903 # where S = R*R. # 6904 # 6904 # # 6905 # Step 5. Compute 2^(J/64)*exp(R) = 2^( 6905 # Step 5. Compute 2^(J/64)*exp(R) = 2^(J/64)*(1+p) by # 6906 # ans := T + ( 6906 # ans := T + ( T*p + t) # 6907 # where T and t are the stored 6907 # where T and t are the stored values for 2^(J/64). # 6908 # Notes: 2^(J/64) is stored as T and t 6908 # Notes: 2^(J/64) is stored as T and t where T+t approximates # 6909 # 2^(J/64) to roughly 85 bits; 6909 # 2^(J/64) to roughly 85 bits; T is in extended precision # 6910 # and t is in single precision. 6910 # and t is in single precision. Note also that T is # 6911 # rounded to 62 bits so that th 6911 # rounded to 62 bits so that the last two bits of T are # 6912 # zero. The reason for such a s 6912 # zero. The reason for such a special form is that T-1, # 6913 # T-2, and T-8 will all be exac 6913 # T-2, and T-8 will all be exact --- a property that will # 6914 # give much more accurate compu 6914 # give much more accurate computation of the function # 6915 # EXPM1. 6915 # EXPM1. # 6916 # 6916 # # 6917 # Step 6. Reconstruction of exp(X) 6917 # Step 6. Reconstruction of exp(X) # 6918 # exp(X) = 2^M * 2^(J/6 6918 # exp(X) = 2^M * 2^(J/64) * exp(R). # 6919 # 6.1 If AdjFlag = 0, go to 6919 # 6.1 If AdjFlag = 0, go to 6.3 # 6920 # 6.2 ans := ans * AdjScale 6920 # 6.2 ans := ans * AdjScale # 6921 # 6.3 Restore the user FPCR 6921 # 6.3 Restore the user FPCR # 6922 # 6.4 Return ans := ans * S 6922 # 6.4 Return ans := ans * Scale. Exit. # 6923 # Notes: If AdjFlag = 0, we have X = M 6923 # Notes: If AdjFlag = 0, we have X = Mlog2 + Jlog2/64 + R, # 6924 # |M| <= 16380, and Scale = 2^M 6924 # |M| <= 16380, and Scale = 2^M. Moreover, exp(X) will # 6925 # neither overflow nor underflo 6925 # neither overflow nor underflow. If AdjFlag = 1, that # 6926 # means that 6926 # means that # 6927 # X = (M1+M)log2 + Jlog 6927 # X = (M1+M)log2 + Jlog2/64 + R, |M1+M| >= 16380. # 6928 # Hence, exp(X) may overflow or 6928 # Hence, exp(X) may overflow or underflow or neither. # 6929 # When that is the case, AdjSca 6929 # When that is the case, AdjScale = 2^(M1) where M1 is # 6930 # approximately M. Thus 6.2 wil 6930 # approximately M. Thus 6.2 will never cause # 6931 # over/underflow. Possible exce 6931 # over/underflow. Possible exception in 6.4 is overflow # 6932 # or underflow. The inexact exc 6932 # or underflow. The inexact exception is not generated in # 6933 # 6.4. Although one can argue t 6933 # 6.4. Although one can argue that the inexact flag # 6934 # should always be raised, to s 6934 # should always be raised, to simulate that exception # 6935 # cost to much than the flag is 6935 # cost to much than the flag is worth in practical uses. # 6936 # 6936 # # 6937 # Step 7. Return 1 + X. 6937 # Step 7. Return 1 + X. # 6938 # 7.1 ans := X 6938 # 7.1 ans := X # 6939 # 7.2 Restore user FPCR. 6939 # 7.2 Restore user FPCR. # 6940 # 7.3 Return ans := 1 + ans 6940 # 7.3 Return ans := 1 + ans. Exit # 6941 # Notes: For non-zero X, the inexact e 6941 # Notes: For non-zero X, the inexact exception will always be # 6942 # raised by 7.3. That is the on 6942 # raised by 7.3. That is the only exception raised by 7.3.# 6943 # Note also that we use the FMO 6943 # Note also that we use the FMOVEM instruction to move X # 6944 # in Step 7.1 to avoid unnecess 6944 # in Step 7.1 to avoid unnecessary trapping. (Although # 6945 # the FMOVEM may not seem relev 6945 # the FMOVEM may not seem relevant since X is normalized, # 6946 # the precaution will be useful 6946 # the precaution will be useful in the library version of # 6947 # this code where the separate 6947 # this code where the separate entry for denormalized # 6948 # inputs will be done away with 6948 # inputs will be done away with.) # 6949 # 6949 # # 6950 # Step 8. Handle exp(X) where |X| >= 16 6950 # Step 8. Handle exp(X) where |X| >= 16380log2. # 6951 # 8.1 If |X| > 16480 log2, 6951 # 8.1 If |X| > 16480 log2, go to Step 9. # 6952 # (mimic 2.2 - 2.6) 6952 # (mimic 2.2 - 2.6) # 6953 # 8.2 N := round-to-integer 6953 # 8.2 N := round-to-integer( X * 64/log2 ) # 6954 # 8.3 Calculate J = N mod 6 6954 # 8.3 Calculate J = N mod 64, J = 0,1,...,63 # 6955 # 8.4 K := (N-J)/64, M1 := 6955 # 8.4 K := (N-J)/64, M1 := truncate(K/2), M = K-M1, # 6956 # AdjFlag := 1. 6956 # AdjFlag := 1. # 6957 # 8.5 Calculate the address 6957 # 8.5 Calculate the address of the stored value # 6958 # 2^(J/64). 6958 # 2^(J/64). # 6959 # 8.6 Create the values Sca 6959 # 8.6 Create the values Scale = 2^M, AdjScale = 2^M1. # 6960 # 8.7 Go to Step 3. 6960 # 8.7 Go to Step 3. # 6961 # Notes: Refer to notes for 2.2 - 2.6. 6961 # Notes: Refer to notes for 2.2 - 2.6. # 6962 # 6962 # # 6963 # Step 9. Handle exp(X), |X| > 16480 lo 6963 # Step 9. Handle exp(X), |X| > 16480 log2. # 6964 # 9.1 If X < 0, go to 9.3 6964 # 9.1 If X < 0, go to 9.3 # 6965 # 9.2 ans := Huge, go to 9. 6965 # 9.2 ans := Huge, go to 9.4 # 6966 # 9.3 ans := Tiny. 6966 # 9.3 ans := Tiny. # 6967 # 9.4 Restore user FPCR. 6967 # 9.4 Restore user FPCR. # 6968 # 9.5 Return ans := ans * a 6968 # 9.5 Return ans := ans * ans. Exit. # 6969 # Notes: Exp(X) will surely overflow o 6969 # Notes: Exp(X) will surely overflow or underflow, depending on # 6970 # X's sign. "Huge" and "Tiny" a 6970 # X's sign. "Huge" and "Tiny" are respectively large/tiny # 6971 # extended-precision numbers wh 6971 # extended-precision numbers whose square over/underflow # 6972 # with an inexact result. Thus, 6972 # with an inexact result. Thus, 9.5 always raises the # 6973 # inexact together with either 6973 # inexact together with either overflow or underflow. # 6974 # 6974 # # 6975 # setoxm1d 6975 # setoxm1d # 6976 # -------- 6976 # -------- # 6977 # 6977 # # 6978 # Step 1. Set ans := 0 6978 # Step 1. Set ans := 0 # 6979 # 6979 # # 6980 # Step 2. Return ans := X + ans. Exit. 6980 # Step 2. Return ans := X + ans. Exit. # 6981 # Notes: This will return X with the a 6981 # Notes: This will return X with the appropriate rounding # 6982 # precision prescribed by the 6982 # precision prescribed by the user FPCR. # 6983 # 6983 # # 6984 # setoxm1 6984 # setoxm1 # 6985 # ------- 6985 # ------- # 6986 # 6986 # # 6987 # Step 1. Check |X| 6987 # Step 1. Check |X| # 6988 # 1.1 If |X| >= 1/4, go to 6988 # 1.1 If |X| >= 1/4, go to Step 1.3. # 6989 # 1.2 Go to Step 7. 6989 # 1.2 Go to Step 7. # 6990 # 1.3 If |X| < 70 log(2), g 6990 # 1.3 If |X| < 70 log(2), go to Step 2. # 6991 # 1.4 Go to Step 10. 6991 # 1.4 Go to Step 10. # 6992 # Notes: The usual case should take th 6992 # Notes: The usual case should take the branches 1.1 -> 1.3 -> 2.# 6993 # However, it is conceivable |X 6993 # However, it is conceivable |X| can be small very often # 6994 # because EXPM1 is intended to 6994 # because EXPM1 is intended to evaluate exp(X)-1 # 6995 # accurately when |X| is small. 6995 # accurately when |X| is small. For further details on # 6996 # the comparisons, see the note 6996 # the comparisons, see the notes on Step 1 of setox. # 6997 # 6997 # # 6998 # Step 2. Calculate N = round-to-neares 6998 # Step 2. Calculate N = round-to-nearest-int( X * 64/log2 ). # 6999 # 2.1 N := round-to-nearest 6999 # 2.1 N := round-to-nearest-integer( X * 64/log2 ). # 7000 # 2.2 Calculate J = N 7000 # 2.2 Calculate J = N mod 64; so J = 0,1,2,..., # 7001 # or 63. 7001 # or 63. # 7002 # 2.3 Calculate M = ( 7002 # 2.3 Calculate M = (N - J)/64; so N = 64M + J. # 7003 # 2.4 Calculate the address 7003 # 2.4 Calculate the address of the stored value of # 7004 # 2^(J/64). 7004 # 2^(J/64). # 7005 # 2.5 Create the values Sc 7005 # 2.5 Create the values Sc = 2^M and # 7006 # OnebySc := -2^(-M). 7006 # OnebySc := -2^(-M). # 7007 # Notes: See the notes on Step 2 of se 7007 # Notes: See the notes on Step 2 of setox. # 7008 # 7008 # # 7009 # Step 3. Calculate X - N*log2/64. 7009 # Step 3. Calculate X - N*log2/64. # 7010 # 3.1 R := X + N*L1, 7010 # 3.1 R := X + N*L1, # 7011 # where L1 := s 7011 # where L1 := single-precision(-log2/64). # 7012 # 3.2 R := R + N*L2, 7012 # 3.2 R := R + N*L2, # 7013 # L2 := extende 7013 # L2 := extended-precision(-log2/64 - L1).# 7014 # Notes: Applying the analysis of Step 7014 # Notes: Applying the analysis of Step 3 of setox in this case # 7015 # shows that |R| <= 0.0055 (not 7015 # shows that |R| <= 0.0055 (note that |X| <= 70 log2 in # 7016 # this case). 7016 # this case). # 7017 # 7017 # # 7018 # Step 4. Approximate exp(R)-1 by a pol 7018 # Step 4. Approximate exp(R)-1 by a polynomial # 7019 # p = R+R*R*(A1+R*(A2+R 7019 # p = R+R*R*(A1+R*(A2+R*(A3+R*(A4+R*(A5+R*A6))))) # 7020 # Notes: a) In order to reduce memory 7020 # Notes: a) In order to reduce memory access, the coefficients # 7021 # are made as "short" as possib 7021 # are made as "short" as possible: A1 (which is 1/2), A5 # 7022 # and A6 are single precision; 7022 # and A6 are single precision; A2, A3 and A4 are double # 7023 # precision. 7023 # precision. # 7024 # b) Even with the restriction 7024 # b) Even with the restriction above, # 7025 # |p - (exp(R)-1)| < 7025 # |p - (exp(R)-1)| < |R| * 2^(-72.7) # 7026 # for all |R| <= 0.0055. 7026 # for all |R| <= 0.0055. # 7027 # c) To fully utilize the pipel 7027 # c) To fully utilize the pipeline, p is separated into # 7028 # two independent pieces of rou 7028 # two independent pieces of roughly equal complexity # 7029 # p = [ R*S*(A2 + S*(A4 7029 # p = [ R*S*(A2 + S*(A4 + S*A6)) ] + # 7030 # [ R + S*(A1 + 7030 # [ R + S*(A1 + S*(A3 + S*A5)) ] # 7031 # where S = R*R. 7031 # where S = R*R. # 7032 # 7032 # # 7033 # Step 5. Compute 2^(J/64)*p by 7033 # Step 5. Compute 2^(J/64)*p by # 7034 # p := T*p 7034 # p := T*p # 7035 # where T and t are the stored 7035 # where T and t are the stored values for 2^(J/64). # 7036 # Notes: 2^(J/64) is stored as T and t 7036 # Notes: 2^(J/64) is stored as T and t where T+t approximates # 7037 # 2^(J/64) to roughly 85 bits; 7037 # 2^(J/64) to roughly 85 bits; T is in extended precision # 7038 # and t is in single precision. 7038 # and t is in single precision. Note also that T is # 7039 # rounded to 62 bits so that th 7039 # rounded to 62 bits so that the last two bits of T are # 7040 # zero. The reason for such a s 7040 # zero. The reason for such a special form is that T-1, # 7041 # T-2, and T-8 will all be exac 7041 # T-2, and T-8 will all be exact --- a property that will # 7042 # be exploited in Step 6 below. 7042 # be exploited in Step 6 below. The total relative error # 7043 # in p is no bigger than 2^(-67 7043 # in p is no bigger than 2^(-67.7) compared to the final # 7044 # result. 7044 # result. # 7045 # 7045 # # 7046 # Step 6. Reconstruction of exp(X)-1 7046 # Step 6. Reconstruction of exp(X)-1 # 7047 # exp(X)-1 = 2^M * ( 2^ 7047 # exp(X)-1 = 2^M * ( 2^(J/64) + p - 2^(-M) ). # 7048 # 6.1 If M <= 63, go to Ste 7048 # 6.1 If M <= 63, go to Step 6.3. # 7049 # 6.2 ans := T + (p + (t + 7049 # 6.2 ans := T + (p + (t + OnebySc)). Go to 6.6 # 7050 # 6.3 If M >= -3, go to 6.5 7050 # 6.3 If M >= -3, go to 6.5. # 7051 # 6.4 ans := (T + (p + t)) 7051 # 6.4 ans := (T + (p + t)) + OnebySc. Go to 6.6 # 7052 # 6.5 ans := (T + OnebySc) 7052 # 6.5 ans := (T + OnebySc) + (p + t). # 7053 # 6.6 Restore user FPCR. 7053 # 6.6 Restore user FPCR. # 7054 # 6.7 Return ans := Sc * an 7054 # 6.7 Return ans := Sc * ans. Exit. # 7055 # Notes: The various arrangements of t 7055 # Notes: The various arrangements of the expressions give # 7056 # accurate evaluations. 7056 # accurate evaluations. # 7057 # 7057 # # 7058 # Step 7. exp(X)-1 for |X| < 1/4. 7058 # Step 7. exp(X)-1 for |X| < 1/4. # 7059 # 7.1 If |X| >= 2^(-65), go 7059 # 7.1 If |X| >= 2^(-65), go to Step 9. # 7060 # 7.2 Go to Step 8. 7060 # 7.2 Go to Step 8. # 7061 # 7061 # # 7062 # Step 8. Calculate exp(X)-1, |X| < 2^( 7062 # Step 8. Calculate exp(X)-1, |X| < 2^(-65). # 7063 # 8.1 If |X| < 2^(-16312), 7063 # 8.1 If |X| < 2^(-16312), goto 8.3 # 7064 # 8.2 Restore FPCR; return 7064 # 8.2 Restore FPCR; return ans := X - 2^(-16382). # 7065 # Exit. 7065 # Exit. # 7066 # 8.3 X := X * 2^(140). 7066 # 8.3 X := X * 2^(140). # 7067 # 8.4 Restore FPCR; ans := 7067 # 8.4 Restore FPCR; ans := ans - 2^(-16382). # 7068 # Return ans := ans*2^(140). E 7068 # Return ans := ans*2^(140). Exit # 7069 # Notes: The idea is to return "X - ti 7069 # Notes: The idea is to return "X - tiny" under the user # 7070 # precision and rounding modes. 7070 # precision and rounding modes. To avoid unnecessary # 7071 # inefficiency, we stay away fr 7071 # inefficiency, we stay away from denormalized numbers # 7072 # the best we can. For |X| >= 2 7072 # the best we can. For |X| >= 2^(-16312), the # 7073 # straightforward 8.2 generates 7073 # straightforward 8.2 generates the inexact exception as # 7074 # the case warrants. 7074 # the case warrants. # 7075 # 7075 # # 7076 # Step 9. Calculate exp(X)-1, |X| < 1/4 7076 # Step 9. Calculate exp(X)-1, |X| < 1/4, by a polynomial # 7077 # p = X + X*X*(B1 + X*( 7077 # p = X + X*X*(B1 + X*(B2 + ... + X*B12)) # 7078 # Notes: a) In order to reduce memory 7078 # Notes: a) In order to reduce memory access, the coefficients # 7079 # are made as "short" as possib 7079 # are made as "short" as possible: B1 (which is 1/2), B9 # 7080 # to B12 are single precision; 7080 # to B12 are single precision; B3 to B8 are double # 7081 # precision; and B2 is double e 7081 # precision; and B2 is double extended. # 7082 # b) Even with the restriction 7082 # b) Even with the restriction above, # 7083 # |p - (exp(X)-1)| < |X 7083 # |p - (exp(X)-1)| < |X| 2^(-70.6) # 7084 # for all |X| <= 0.251. 7084 # for all |X| <= 0.251. # 7085 # Note that 0.251 is slightly b 7085 # Note that 0.251 is slightly bigger than 1/4. # 7086 # c) To fully preserve accuracy 7086 # c) To fully preserve accuracy, the polynomial is # 7087 # computed as 7087 # computed as # 7088 # X + ( S*B1 + Q ) w 7088 # X + ( S*B1 + Q ) where S = X*X and # 7089 # Q = X*S*( 7089 # Q = X*S*(B2 + X*(B3 + ... + X*B12)) # 7090 # d) To fully utilize the pipel 7090 # d) To fully utilize the pipeline, Q is separated into # 7091 # two independent pieces of rou 7091 # two independent pieces of roughly equal complexity # 7092 # Q = [ X*S*(B2 + S*(B4 7092 # Q = [ X*S*(B2 + S*(B4 + ... + S*B12)) ] + # 7093 # [ S*S*(B3 + S 7093 # [ S*S*(B3 + S*(B5 + ... + S*B11)) ] # 7094 # 7094 # # 7095 # Step 10. Calculate exp(X)-1 for |X| > 7095 # Step 10. Calculate exp(X)-1 for |X| >= 70 log 2. # 7096 # 10.1 If X >= 70log2 , exp(X) 7096 # 10.1 If X >= 70log2 , exp(X) - 1 = exp(X) for all # 7097 # practical purposes. Therefore 7097 # practical purposes. Therefore, go to Step 1 of setox. # 7098 # 10.2 If X <= -70log2, exp(X) 7098 # 10.2 If X <= -70log2, exp(X) - 1 = -1 for all practical # 7099 # purposes. 7099 # purposes. # 7100 # ans := -1 7100 # ans := -1 # 7101 # Restore user FPCR 7101 # Restore user FPCR # 7102 # Return ans := ans + 2^(-126). 7102 # Return ans := ans + 2^(-126). Exit. # 7103 # Notes: 10.2 will always create an in 7103 # Notes: 10.2 will always create an inexact and return -1 + tiny # 7104 # in the user rounding precisio 7104 # in the user rounding precision and mode. # 7105 # 7105 # # 7106 ############################################# 7106 ######################################################################### 7107 7107 7108 L2: long 0x3FDC0000,0x82E30865 7108 L2: long 0x3FDC0000,0x82E30865,0x4361C4C6,0x00000000 7109 7109 7110 EEXPA3: long 0x3FA55555,0x55554CC1 7110 EEXPA3: long 0x3FA55555,0x55554CC1 7111 EEXPA2: long 0x3FC55555,0x55554A54 7111 EEXPA2: long 0x3FC55555,0x55554A54 7112 7112 7113 EM1A4: long 0x3F811111,0x11174385 7113 EM1A4: long 0x3F811111,0x11174385 7114 EM1A3: long 0x3FA55555,0x55554F5A 7114 EM1A3: long 0x3FA55555,0x55554F5A 7115 7115 7116 EM1A2: long 0x3FC55555,0x55555555 7116 EM1A2: long 0x3FC55555,0x55555555,0x00000000,0x00000000 7117 7117 7118 EM1B8: long 0x3EC71DE3,0xA5774682 7118 EM1B8: long 0x3EC71DE3,0xA5774682 7119 EM1B7: long 0x3EFA01A0,0x19D7CB68 7119 EM1B7: long 0x3EFA01A0,0x19D7CB68 7120 7120 7121 EM1B6: long 0x3F2A01A0,0x1A019DF3 7121 EM1B6: long 0x3F2A01A0,0x1A019DF3 7122 EM1B5: long 0x3F56C16C,0x16C170E2 7122 EM1B5: long 0x3F56C16C,0x16C170E2 7123 7123 7124 EM1B4: long 0x3F811111,0x11111111 7124 EM1B4: long 0x3F811111,0x11111111 7125 EM1B3: long 0x3FA55555,0x55555555 7125 EM1B3: long 0x3FA55555,0x55555555 7126 7126 7127 EM1B2: long 0x3FFC0000,0xAAAAAAAA 7127 EM1B2: long 0x3FFC0000,0xAAAAAAAA,0xAAAAAAAB 7128 long 0x00000000 7128 long 0x00000000 7129 7129 7130 TWO140: long 0x48B00000,0x00000000 7130 TWO140: long 0x48B00000,0x00000000 7131 TWON140: 7131 TWON140: 7132 long 0x37300000,0x00000000 7132 long 0x37300000,0x00000000 7133 7133 7134 EEXPTBL: 7134 EEXPTBL: 7135 long 0x3FFF0000,0x80000000 7135 long 0x3FFF0000,0x80000000,0x00000000,0x00000000 7136 long 0x3FFF0000,0x8164D1F3 7136 long 0x3FFF0000,0x8164D1F3,0xBC030774,0x9F841A9B 7137 long 0x3FFF0000,0x82CD8698 7137 long 0x3FFF0000,0x82CD8698,0xAC2BA1D8,0x9FC1D5B9 7138 long 0x3FFF0000,0x843A28C3 7138 long 0x3FFF0000,0x843A28C3,0xACDE4048,0xA0728369 7139 long 0x3FFF0000,0x85AAC367 7139 long 0x3FFF0000,0x85AAC367,0xCC487B14,0x1FC5C95C 7140 long 0x3FFF0000,0x871F6196 7140 long 0x3FFF0000,0x871F6196,0x9E8D1010,0x1EE85C9F 7141 long 0x3FFF0000,0x88980E80 7141 long 0x3FFF0000,0x88980E80,0x92DA8528,0x9FA20729 7142 long 0x3FFF0000,0x8A14D575 7142 long 0x3FFF0000,0x8A14D575,0x496EFD9C,0xA07BF9AF 7143 long 0x3FFF0000,0x8B95C1E3 7143 long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E8,0xA0020DCF 7144 long 0x3FFF0000,0x8D1ADF5B 7144 long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E4,0x205A63DA 7145 long 0x3FFF0000,0x8EA4398B 7145 long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x1EB70051 7146 long 0x3FFF0000,0x9031DC43 7146 long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x1F6EB029 7147 long 0x3FFF0000,0x91C3D373 7147 long 0x3FFF0000,0x91C3D373,0xAB11C338,0xA0781494 7148 long 0x3FFF0000,0x935A2B2F 7148 long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0x9EB319B0 7149 long 0x3FFF0000,0x94F4EFA8 7149 long 0x3FFF0000,0x94F4EFA8,0xFEF70960,0x2017457D 7150 long 0x3FFF0000,0x96942D37 7150 long 0x3FFF0000,0x96942D37,0x20185A00,0x1F11D537 7151 long 0x3FFF0000,0x9837F051 7151 long 0x3FFF0000,0x9837F051,0x8DB8A970,0x9FB952DD 7152 long 0x3FFF0000,0x99E04593 7152 long 0x3FFF0000,0x99E04593,0x20B7FA64,0x1FE43087 7153 long 0x3FFF0000,0x9B8D39B9 7153 long 0x3FFF0000,0x9B8D39B9,0xD54E5538,0x1FA2A818 7154 long 0x3FFF0000,0x9D3ED9A7 7154 long 0x3FFF0000,0x9D3ED9A7,0x2CFFB750,0x1FDE494D 7155 long 0x3FFF0000,0x9EF53260 7155 long 0x3FFF0000,0x9EF53260,0x91A111AC,0x20504890 7156 long 0x3FFF0000,0xA0B0510F 7156 long 0x3FFF0000,0xA0B0510F,0xB9714FC4,0xA073691C 7157 long 0x3FFF0000,0xA2704303 7157 long 0x3FFF0000,0xA2704303,0x0C496818,0x1F9B7A05 7158 long 0x3FFF0000,0xA43515AE 7158 long 0x3FFF0000,0xA43515AE,0x09E680A0,0xA0797126 7159 long 0x3FFF0000,0xA5FED6A9 7159 long 0x3FFF0000,0xA5FED6A9,0xB15138EC,0xA071A140 7160 long 0x3FFF0000,0xA7CD93B4 7160 long 0x3FFF0000,0xA7CD93B4,0xE9653568,0x204F62DA 7161 long 0x3FFF0000,0xA9A15AB4 7161 long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x1F283C4A 7162 long 0x3FFF0000,0xAB7A39B5 7162 long 0x3FFF0000,0xAB7A39B5,0xA93ED338,0x9F9A7FDC 7163 long 0x3FFF0000,0xAD583EEA 7163 long 0x3FFF0000,0xAD583EEA,0x42A14AC8,0xA05B3FAC 7164 long 0x3FFF0000,0xAF3B78AD 7164 long 0x3FFF0000,0xAF3B78AD,0x690A4374,0x1FDF2610 7165 long 0x3FFF0000,0xB123F581 7165 long 0x3FFF0000,0xB123F581,0xD2AC2590,0x9F705F90 7166 long 0x3FFF0000,0xB311C412 7166 long 0x3FFF0000,0xB311C412,0xA9112488,0x201F678A 7167 long 0x3FFF0000,0xB504F333 7167 long 0x3FFF0000,0xB504F333,0xF9DE6484,0x1F32FB13 7168 long 0x3FFF0000,0xB6FD91E3 7168 long 0x3FFF0000,0xB6FD91E3,0x28D17790,0x20038B30 7169 long 0x3FFF0000,0xB8FBAF47 7169 long 0x3FFF0000,0xB8FBAF47,0x62FB9EE8,0x200DC3CC 7170 long 0x3FFF0000,0xBAFF5AB2 7170 long 0x3FFF0000,0xBAFF5AB2,0x133E45FC,0x9F8B2AE6 7171 long 0x3FFF0000,0xBD08A39F 7171 long 0x3FFF0000,0xBD08A39F,0x580C36C0,0xA02BBF70 7172 long 0x3FFF0000,0xBF1799B6 7172 long 0x3FFF0000,0xBF1799B6,0x7A731084,0xA00BF518 7173 long 0x3FFF0000,0xC12C4CCA 7173 long 0x3FFF0000,0xC12C4CCA,0x66709458,0xA041DD41 7174 long 0x3FFF0000,0xC346CCDA 7174 long 0x3FFF0000,0xC346CCDA,0x24976408,0x9FDF137B 7175 long 0x3FFF0000,0xC5672A11 7175 long 0x3FFF0000,0xC5672A11,0x5506DADC,0x201F1568 7176 long 0x3FFF0000,0xC78D74C8 7176 long 0x3FFF0000,0xC78D74C8,0xABB9B15C,0x1FC13A2E 7177 long 0x3FFF0000,0xC9B9BD86 7177 long 0x3FFF0000,0xC9B9BD86,0x6E2F27A4,0xA03F8F03 7178 long 0x3FFF0000,0xCBEC14FE 7178 long 0x3FFF0000,0xCBEC14FE,0xF2727C5C,0x1FF4907D 7179 long 0x3FFF0000,0xCE248C15 7179 long 0x3FFF0000,0xCE248C15,0x1F8480E4,0x9E6E53E4 7180 long 0x3FFF0000,0xD06333DA 7180 long 0x3FFF0000,0xD06333DA,0xEF2B2594,0x1FD6D45C 7181 long 0x3FFF0000,0xD2A81D91 7181 long 0x3FFF0000,0xD2A81D91,0xF12AE45C,0xA076EDB9 7182 long 0x3FFF0000,0xD4F35AAB 7182 long 0x3FFF0000,0xD4F35AAB,0xCFEDFA20,0x9FA6DE21 7183 long 0x3FFF0000,0xD744FCCA 7183 long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x1EE69A2F 7184 long 0x3FFF0000,0xD99D15C2 7184 long 0x3FFF0000,0xD99D15C2,0x78AFD7B4,0x207F439F 7185 long 0x3FFF0000,0xDBFBB797 7185 long 0x3FFF0000,0xDBFBB797,0xDAF23754,0x201EC207 7186 long 0x3FFF0000,0xDE60F482 7186 long 0x3FFF0000,0xDE60F482,0x5E0E9124,0x9E8BE175 7187 long 0x3FFF0000,0xE0CCDEEC 7187 long 0x3FFF0000,0xE0CCDEEC,0x2A94E110,0x20032C4B 7188 long 0x3FFF0000,0xE33F8972 7188 long 0x3FFF0000,0xE33F8972,0xBE8A5A50,0x2004DFF5 7189 long 0x3FFF0000,0xE5B906E7 7189 long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x1E72F47A 7190 long 0x3FFF0000,0xE8396A50 7190 long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x1F722F22 7191 long 0x3FFF0000,0xEAC0C6E7 7191 long 0x3FFF0000,0xEAC0C6E7,0xDD243930,0xA017E945 7192 long 0x3FFF0000,0xED4F301E 7192 long 0x3FFF0000,0xED4F301E,0xD9942B84,0x1F401A5B 7193 long 0x3FFF0000,0xEFE4B99B 7193 long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CC,0x9FB9A9E3 7194 long 0x3FFF0000,0xF281773C 7194 long 0x3FFF0000,0xF281773C,0x59FFB138,0x20744C05 7195 long 0x3FFF0000,0xF5257D15 7195 long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x1F773A19 7196 long 0x3FFF0000,0xF7D0DF73 7196 long 0x3FFF0000,0xF7D0DF73,0x0AD13BB8,0x1FFE90D5 7197 long 0x3FFF0000,0xFA83B2DB 7197 long 0x3FFF0000,0xFA83B2DB,0x722A033C,0xA041ED22 7198 long 0x3FFF0000,0xFD3E0C0C 7198 long 0x3FFF0000,0xFD3E0C0C,0xF486C174,0x1F853F3A 7199 7199 7200 set ADJFLAG,L_SCR2 7200 set ADJFLAG,L_SCR2 7201 set SCALE,FP_SCR0 7201 set SCALE,FP_SCR0 7202 set ADJSCALE,FP_SCR1 7202 set ADJSCALE,FP_SCR1 7203 set SC,FP_SCR0 7203 set SC,FP_SCR0 7204 set ONEBYSC,FP_SCR1 7204 set ONEBYSC,FP_SCR1 7205 7205 7206 global setox 7206 global setox 7207 setox: 7207 setox: 7208 #--entry point for EXP(X), here X is finite, 7208 #--entry point for EXP(X), here X is finite, non-zero, and not NaN's 7209 7209 7210 #--Step 1. 7210 #--Step 1. 7211 mov.l (%a0),%d1 7211 mov.l (%a0),%d1 # load part of input X 7212 and.l &0x7FFF0000,%d1 7212 and.l &0x7FFF0000,%d1 # biased expo. of X 7213 cmp.l %d1,&0x3FBE0000 7213 cmp.l %d1,&0x3FBE0000 # 2^(-65) 7214 bge.b EXPC1 7214 bge.b EXPC1 # normal case 7215 bra EXPSM 7215 bra EXPSM 7216 7216 7217 EXPC1: 7217 EXPC1: 7218 #--The case |X| >= 2^(-65) 7218 #--The case |X| >= 2^(-65) 7219 mov.w 4(%a0),%d1 7219 mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 7220 cmp.l %d1,&0x400CB167 7220 cmp.l %d1,&0x400CB167 # 16380 log2 trunc. 16 bits 7221 blt.b EXPMAIN 7221 blt.b EXPMAIN # normal case 7222 bra EEXPBIG 7222 bra EEXPBIG 7223 7223 7224 EXPMAIN: 7224 EXPMAIN: 7225 #--Step 2. 7225 #--Step 2. 7226 #--This is the normal branch: 2^(-65) <= |X 7226 #--This is the normal branch: 2^(-65) <= |X| < 16380 log2. 7227 fmov.x (%a0),%fp0 7227 fmov.x (%a0),%fp0 # load input from (a0) 7228 7228 7229 fmov.x %fp0,%fp1 7229 fmov.x %fp0,%fp1 7230 fmul.s &0x42B8AA3B,%fp0 7230 fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 7231 fmovm.x &0xc,-(%sp) 7231 fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7232 mov.l &0,ADJFLAG(%a6) 7232 mov.l &0,ADJFLAG(%a6) 7233 fmov.l %fp0,%d1 7233 fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 7234 lea EEXPTBL(%pc),%a1 7234 lea EEXPTBL(%pc),%a1 7235 fmov.l %d1,%fp0 7235 fmov.l %d1,%fp0 # convert to floating-format 7236 7236 7237 mov.l %d1,L_SCR1(%a6) 7237 mov.l %d1,L_SCR1(%a6) # save N temporarily 7238 and.l &0x3F,%d1 7238 and.l &0x3F,%d1 # D0 is J = N mod 64 7239 lsl.l &4,%d1 7239 lsl.l &4,%d1 7240 add.l %d1,%a1 7240 add.l %d1,%a1 # address of 2^(J/64) 7241 mov.l L_SCR1(%a6),%d1 7241 mov.l L_SCR1(%a6),%d1 7242 asr.l &6,%d1 7242 asr.l &6,%d1 # D0 is M 7243 add.w &0x3FFF,%d1 7243 add.w &0x3FFF,%d1 # biased expo. of 2^(M) 7244 mov.w L2(%pc),L_SCR1(%a6) 7244 mov.w L2(%pc),L_SCR1(%a6) # prefetch L2, no need in CB 7245 7245 7246 EXPCONT1: 7246 EXPCONT1: 7247 #--Step 3. 7247 #--Step 3. 7248 #--fp1,fp2 saved on the stack. fp0 is N, fp1 7248 #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 7249 #--a0 points to 2^(J/64), D0 is biased expo. 7249 #--a0 points to 2^(J/64), D0 is biased expo. of 2^(M) 7250 fmov.x %fp0,%fp2 7250 fmov.x %fp0,%fp2 7251 fmul.s &0xBC317218,%fp0 7251 fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 7252 fmul.x L2(%pc),%fp2 7252 fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 7253 fadd.x %fp1,%fp0 7253 fadd.x %fp1,%fp0 # X + N*L1 7254 fadd.x %fp2,%fp0 7254 fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 7255 7255 7256 #--Step 4. 7256 #--Step 4. 7257 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 7257 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 7258 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A 7258 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*A5)))) 7259 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE 7259 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R 7260 #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))] 7260 #--[R+R*S*(A2+S*A4)] + [S*(A1+S*(A3+S*A5))] 7261 7261 7262 fmov.x %fp0,%fp1 7262 fmov.x %fp0,%fp1 7263 fmul.x %fp1,%fp1 7263 fmul.x %fp1,%fp1 # fp1 IS S = R*R 7264 7264 7265 fmov.s &0x3AB60B70,%fp2 7265 fmov.s &0x3AB60B70,%fp2 # fp2 IS A5 7266 7266 7267 fmul.x %fp1,%fp2 7267 fmul.x %fp1,%fp2 # fp2 IS S*A5 7268 fmov.x %fp1,%fp3 7268 fmov.x %fp1,%fp3 7269 fmul.s &0x3C088895,%fp3 7269 fmul.s &0x3C088895,%fp3 # fp3 IS S*A4 7270 7270 7271 fadd.d EEXPA3(%pc),%fp2 7271 fadd.d EEXPA3(%pc),%fp2 # fp2 IS A3+S*A5 7272 fadd.d EEXPA2(%pc),%fp3 7272 fadd.d EEXPA2(%pc),%fp3 # fp3 IS A2+S*A4 7273 7273 7274 fmul.x %fp1,%fp2 7274 fmul.x %fp1,%fp2 # fp2 IS S*(A3+S*A5) 7275 mov.w %d1,SCALE(%a6) 7275 mov.w %d1,SCALE(%a6) # SCALE is 2^(M) in extended 7276 mov.l &0x80000000,SCALE+4(% 7276 mov.l &0x80000000,SCALE+4(%a6) 7277 clr.l SCALE+8(%a6) 7277 clr.l SCALE+8(%a6) 7278 7278 7279 fmul.x %fp1,%fp3 7279 fmul.x %fp1,%fp3 # fp3 IS S*(A2+S*A4) 7280 7280 7281 fadd.s &0x3F000000,%fp2 7281 fadd.s &0x3F000000,%fp2 # fp2 IS A1+S*(A3+S*A5) 7282 fmul.x %fp0,%fp3 7282 fmul.x %fp0,%fp3 # fp3 IS R*S*(A2+S*A4) 7283 7283 7284 fmul.x %fp1,%fp2 7284 fmul.x %fp1,%fp2 # fp2 IS S*(A1+S*(A3+S*A5)) 7285 fadd.x %fp3,%fp0 7285 fadd.x %fp3,%fp0 # fp0 IS R+R*S*(A2+S*A4), 7286 7286 7287 fmov.x (%a1)+,%fp1 7287 fmov.x (%a1)+,%fp1 # fp1 is lead. pt. of 2^(J/64) 7288 fadd.x %fp2,%fp0 7288 fadd.x %fp2,%fp0 # fp0 is EXP(R) - 1 7289 7289 7290 #--Step 5 7290 #--Step 5 7291 #--final reconstruction process 7291 #--final reconstruction process 7292 #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP( 7292 #--EXP(X) = 2^M * ( 2^(J/64) + 2^(J/64)*(EXP(R)-1) ) 7293 7293 7294 fmul.x %fp1,%fp0 7294 fmul.x %fp1,%fp0 # 2^(J/64)*(Exp(R)-1) 7295 fmovm.x (%sp)+,&0x30 7295 fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 7296 fadd.s (%a1),%fp0 7296 fadd.s (%a1),%fp0 # accurate 2^(J/64) 7297 7297 7298 fadd.x %fp1,%fp0 7298 fadd.x %fp1,%fp0 # 2^(J/64) + 2^(J/64)*... 7299 mov.l ADJFLAG(%a6),%d1 7299 mov.l ADJFLAG(%a6),%d1 7300 7300 7301 #--Step 6 7301 #--Step 6 7302 tst.l %d1 7302 tst.l %d1 7303 beq.b NORMAL 7303 beq.b NORMAL 7304 ADJUST: 7304 ADJUST: 7305 fmul.x ADJSCALE(%a6),%fp0 7305 fmul.x ADJSCALE(%a6),%fp0 7306 NORMAL: 7306 NORMAL: 7307 fmov.l %d0,%fpcr 7307 fmov.l %d0,%fpcr # restore user FPCR 7308 mov.b &FMUL_OP,%d1 7308 mov.b &FMUL_OP,%d1 # last inst is MUL 7309 fmul.x SCALE(%a6),%fp0 7309 fmul.x SCALE(%a6),%fp0 # multiply 2^(M) 7310 bra t_catch 7310 bra t_catch 7311 7311 7312 EXPSM: 7312 EXPSM: 7313 #--Step 7 7313 #--Step 7 7314 fmovm.x (%a0),&0x80 7314 fmovm.x (%a0),&0x80 # load X 7315 fmov.l %d0,%fpcr 7315 fmov.l %d0,%fpcr 7316 fadd.s &0x3F800000,%fp0 7316 fadd.s &0x3F800000,%fp0 # 1+X in user mode 7317 bra t_pinx2 7317 bra t_pinx2 7318 7318 7319 EEXPBIG: 7319 EEXPBIG: 7320 #--Step 8 7320 #--Step 8 7321 cmp.l %d1,&0x400CB27C 7321 cmp.l %d1,&0x400CB27C # 16480 log2 7322 bgt.b EXP2BIG 7322 bgt.b EXP2BIG 7323 #--Steps 8.2 -- 8.6 7323 #--Steps 8.2 -- 8.6 7324 fmov.x (%a0),%fp0 7324 fmov.x (%a0),%fp0 # load input from (a0) 7325 7325 7326 fmov.x %fp0,%fp1 7326 fmov.x %fp0,%fp1 7327 fmul.s &0x42B8AA3B,%fp0 7327 fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 7328 fmovm.x &0xc,-(%sp) 7328 fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7329 mov.l &1,ADJFLAG(%a6) 7329 mov.l &1,ADJFLAG(%a6) 7330 fmov.l %fp0,%d1 7330 fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 7331 lea EEXPTBL(%pc),%a1 7331 lea EEXPTBL(%pc),%a1 7332 fmov.l %d1,%fp0 7332 fmov.l %d1,%fp0 # convert to floating-format 7333 mov.l %d1,L_SCR1(%a6) 7333 mov.l %d1,L_SCR1(%a6) # save N temporarily 7334 and.l &0x3F,%d1 7334 and.l &0x3F,%d1 # D0 is J = N mod 64 7335 lsl.l &4,%d1 7335 lsl.l &4,%d1 7336 add.l %d1,%a1 7336 add.l %d1,%a1 # address of 2^(J/64) 7337 mov.l L_SCR1(%a6),%d1 7337 mov.l L_SCR1(%a6),%d1 7338 asr.l &6,%d1 7338 asr.l &6,%d1 # D0 is K 7339 mov.l %d1,L_SCR1(%a6) 7339 mov.l %d1,L_SCR1(%a6) # save K temporarily 7340 asr.l &1,%d1 7340 asr.l &1,%d1 # D0 is M1 7341 sub.l %d1,L_SCR1(%a6) 7341 sub.l %d1,L_SCR1(%a6) # a1 is M 7342 add.w &0x3FFF,%d1 7342 add.w &0x3FFF,%d1 # biased expo. of 2^(M1) 7343 mov.w %d1,ADJSCALE(%a6) 7343 mov.w %d1,ADJSCALE(%a6) # ADJSCALE := 2^(M1) 7344 mov.l &0x80000000,ADJSCALE+ 7344 mov.l &0x80000000,ADJSCALE+4(%a6) 7345 clr.l ADJSCALE+8(%a6) 7345 clr.l ADJSCALE+8(%a6) 7346 mov.l L_SCR1(%a6),%d1 7346 mov.l L_SCR1(%a6),%d1 # D0 is M 7347 add.w &0x3FFF,%d1 7347 add.w &0x3FFF,%d1 # biased expo. of 2^(M) 7348 bra.w EXPCONT1 7348 bra.w EXPCONT1 # go back to Step 3 7349 7349 7350 EXP2BIG: 7350 EXP2BIG: 7351 #--Step 9 7351 #--Step 9 7352 tst.b (%a0) 7352 tst.b (%a0) # is X positive or negative? 7353 bmi t_unfl2 7353 bmi t_unfl2 7354 bra t_ovfl2 7354 bra t_ovfl2 7355 7355 7356 global setoxd 7356 global setoxd 7357 setoxd: 7357 setoxd: 7358 #--entry point for EXP(X), X is denormalized 7358 #--entry point for EXP(X), X is denormalized 7359 mov.l (%a0),-(%sp) 7359 mov.l (%a0),-(%sp) 7360 andi.l &0x80000000,(%sp) 7360 andi.l &0x80000000,(%sp) 7361 ori.l &0x00800000,(%sp) 7361 ori.l &0x00800000,(%sp) # sign(X)*2^(-126) 7362 7362 7363 fmov.s &0x3F800000,%fp0 7363 fmov.s &0x3F800000,%fp0 7364 7364 7365 fmov.l %d0,%fpcr 7365 fmov.l %d0,%fpcr 7366 fadd.s (%sp)+,%fp0 7366 fadd.s (%sp)+,%fp0 7367 bra t_pinx2 7367 bra t_pinx2 7368 7368 7369 global setoxm1 7369 global setoxm1 7370 setoxm1: 7370 setoxm1: 7371 #--entry point for EXPM1(X), here X is finite 7371 #--entry point for EXPM1(X), here X is finite, non-zero, non-NaN 7372 7372 7373 #--Step 1. 7373 #--Step 1. 7374 #--Step 1.1 7374 #--Step 1.1 7375 mov.l (%a0),%d1 7375 mov.l (%a0),%d1 # load part of input X 7376 and.l &0x7FFF0000,%d1 7376 and.l &0x7FFF0000,%d1 # biased expo. of X 7377 cmp.l %d1,&0x3FFD0000 7377 cmp.l %d1,&0x3FFD0000 # 1/4 7378 bge.b EM1CON1 7378 bge.b EM1CON1 # |X| >= 1/4 7379 bra EM1SM 7379 bra EM1SM 7380 7380 7381 EM1CON1: 7381 EM1CON1: 7382 #--Step 1.3 7382 #--Step 1.3 7383 #--The case |X| >= 1/4 7383 #--The case |X| >= 1/4 7384 mov.w 4(%a0),%d1 7384 mov.w 4(%a0),%d1 # expo. and partial sig. of |X| 7385 cmp.l %d1,&0x4004C215 7385 cmp.l %d1,&0x4004C215 # 70log2 rounded up to 16 bits 7386 ble.b EM1MAIN 7386 ble.b EM1MAIN # 1/4 <= |X| <= 70log2 7387 bra EM1BIG 7387 bra EM1BIG 7388 7388 7389 EM1MAIN: 7389 EM1MAIN: 7390 #--Step 2. 7390 #--Step 2. 7391 #--This is the case: 1/4 <= |X| <= 70 log2 7391 #--This is the case: 1/4 <= |X| <= 70 log2. 7392 fmov.x (%a0),%fp0 7392 fmov.x (%a0),%fp0 # load input from (a0) 7393 7393 7394 fmov.x %fp0,%fp1 7394 fmov.x %fp0,%fp1 7395 fmul.s &0x42B8AA3B,%fp0 7395 fmul.s &0x42B8AA3B,%fp0 # 64/log2 * X 7396 fmovm.x &0xc,-(%sp) 7396 fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7397 fmov.l %fp0,%d1 7397 fmov.l %fp0,%d1 # N = int( X * 64/log2 ) 7398 lea EEXPTBL(%pc),%a1 7398 lea EEXPTBL(%pc),%a1 7399 fmov.l %d1,%fp0 7399 fmov.l %d1,%fp0 # convert to floating-format 7400 7400 7401 mov.l %d1,L_SCR1(%a6) 7401 mov.l %d1,L_SCR1(%a6) # save N temporarily 7402 and.l &0x3F,%d1 7402 and.l &0x3F,%d1 # D0 is J = N mod 64 7403 lsl.l &4,%d1 7403 lsl.l &4,%d1 7404 add.l %d1,%a1 7404 add.l %d1,%a1 # address of 2^(J/64) 7405 mov.l L_SCR1(%a6),%d1 7405 mov.l L_SCR1(%a6),%d1 7406 asr.l &6,%d1 7406 asr.l &6,%d1 # D0 is M 7407 mov.l %d1,L_SCR1(%a6) 7407 mov.l %d1,L_SCR1(%a6) # save a copy of M 7408 7408 7409 #--Step 3. 7409 #--Step 3. 7410 #--fp1,fp2 saved on the stack. fp0 is N, fp1 7410 #--fp1,fp2 saved on the stack. fp0 is N, fp1 is X, 7411 #--a0 points to 2^(J/64), D0 and a1 both cont 7411 #--a0 points to 2^(J/64), D0 and a1 both contain M 7412 fmov.x %fp0,%fp2 7412 fmov.x %fp0,%fp2 7413 fmul.s &0xBC317218,%fp0 7413 fmul.s &0xBC317218,%fp0 # N * L1, L1 = lead(-log2/64) 7414 fmul.x L2(%pc),%fp2 7414 fmul.x L2(%pc),%fp2 # N * L2, L1+L2 = -log2/64 7415 fadd.x %fp1,%fp0 7415 fadd.x %fp1,%fp0 # X + N*L1 7416 fadd.x %fp2,%fp0 7416 fadd.x %fp2,%fp0 # fp0 is R, reduced arg. 7417 add.w &0x3FFF,%d1 7417 add.w &0x3FFF,%d1 # D0 is biased expo. of 2^M 7418 7418 7419 #--Step 4. 7419 #--Step 4. 7420 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 7420 #--WE NOW COMPUTE EXP(R)-1 BY A POLYNOMIAL 7421 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*( 7421 #-- R + R*R*(A1 + R*(A2 + R*(A3 + R*(A4 + R*(A5 + R*A6))))) 7422 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE 7422 #--TO FULLY UTILIZE THE PIPELINE, WE COMPUTE S = R*R 7423 #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S* 7423 #--[R*S*(A2+S*(A4+S*A6))] + [R+S*(A1+S*(A3+S*A5))] 7424 7424 7425 fmov.x %fp0,%fp1 7425 fmov.x %fp0,%fp1 7426 fmul.x %fp1,%fp1 7426 fmul.x %fp1,%fp1 # fp1 IS S = R*R 7427 7427 7428 fmov.s &0x3950097B,%fp2 7428 fmov.s &0x3950097B,%fp2 # fp2 IS a6 7429 7429 7430 fmul.x %fp1,%fp2 7430 fmul.x %fp1,%fp2 # fp2 IS S*A6 7431 fmov.x %fp1,%fp3 7431 fmov.x %fp1,%fp3 7432 fmul.s &0x3AB60B6A,%fp3 7432 fmul.s &0x3AB60B6A,%fp3 # fp3 IS S*A5 7433 7433 7434 fadd.d EM1A4(%pc),%fp2 7434 fadd.d EM1A4(%pc),%fp2 # fp2 IS A4+S*A6 7435 fadd.d EM1A3(%pc),%fp3 7435 fadd.d EM1A3(%pc),%fp3 # fp3 IS A3+S*A5 7436 mov.w %d1,SC(%a6) 7436 mov.w %d1,SC(%a6) # SC is 2^(M) in extended 7437 mov.l &0x80000000,SC+4(%a6) 7437 mov.l &0x80000000,SC+4(%a6) 7438 clr.l SC+8(%a6) 7438 clr.l SC+8(%a6) 7439 7439 7440 fmul.x %fp1,%fp2 7440 fmul.x %fp1,%fp2 # fp2 IS S*(A4+S*A6) 7441 mov.l L_SCR1(%a6),%d1 7441 mov.l L_SCR1(%a6),%d1 # D0 is M 7442 neg.w %d1 7442 neg.w %d1 # D0 is -M 7443 fmul.x %fp1,%fp3 7443 fmul.x %fp1,%fp3 # fp3 IS S*(A3+S*A5) 7444 add.w &0x3FFF,%d1 7444 add.w &0x3FFF,%d1 # biased expo. of 2^(-M) 7445 fadd.d EM1A2(%pc),%fp2 7445 fadd.d EM1A2(%pc),%fp2 # fp2 IS A2+S*(A4+S*A6) 7446 fadd.s &0x3F000000,%fp3 7446 fadd.s &0x3F000000,%fp3 # fp3 IS A1+S*(A3+S*A5) 7447 7447 7448 fmul.x %fp1,%fp2 7448 fmul.x %fp1,%fp2 # fp2 IS S*(A2+S*(A4+S*A6)) 7449 or.w &0x8000,%d1 7449 or.w &0x8000,%d1 # signed/expo. of -2^(-M) 7450 mov.w %d1,ONEBYSC(%a6) 7450 mov.w %d1,ONEBYSC(%a6) # OnebySc is -2^(-M) 7451 mov.l &0x80000000,ONEBYSC+4 7451 mov.l &0x80000000,ONEBYSC+4(%a6) 7452 clr.l ONEBYSC+8(%a6) 7452 clr.l ONEBYSC+8(%a6) 7453 fmul.x %fp3,%fp1 7453 fmul.x %fp3,%fp1 # fp1 IS S*(A1+S*(A3+S*A5)) 7454 7454 7455 fmul.x %fp0,%fp2 7455 fmul.x %fp0,%fp2 # fp2 IS R*S*(A2+S*(A4+S*A6)) 7456 fadd.x %fp1,%fp0 7456 fadd.x %fp1,%fp0 # fp0 IS R+S*(A1+S*(A3+S*A5)) 7457 7457 7458 fadd.x %fp2,%fp0 7458 fadd.x %fp2,%fp0 # fp0 IS EXP(R)-1 7459 7459 7460 fmovm.x (%sp)+,&0x30 7460 fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 7461 7461 7462 #--Step 5 7462 #--Step 5 7463 #--Compute 2^(J/64)*p 7463 #--Compute 2^(J/64)*p 7464 7464 7465 fmul.x (%a1),%fp0 7465 fmul.x (%a1),%fp0 # 2^(J/64)*(Exp(R)-1) 7466 7466 7467 #--Step 6 7467 #--Step 6 7468 #--Step 6.1 7468 #--Step 6.1 7469 mov.l L_SCR1(%a6),%d1 7469 mov.l L_SCR1(%a6),%d1 # retrieve M 7470 cmp.l %d1,&63 7470 cmp.l %d1,&63 7471 ble.b MLE63 7471 ble.b MLE63 7472 #--Step 6.2 M >= 64 7472 #--Step 6.2 M >= 64 7473 fmov.s 12(%a1),%fp1 7473 fmov.s 12(%a1),%fp1 # fp1 is t 7474 fadd.x ONEBYSC(%a6),%fp1 7474 fadd.x ONEBYSC(%a6),%fp1 # fp1 is t+OnebySc 7475 fadd.x %fp1,%fp0 7475 fadd.x %fp1,%fp0 # p+(t+OnebySc), fp1 released 7476 fadd.x (%a1),%fp0 7476 fadd.x (%a1),%fp0 # T+(p+(t+OnebySc)) 7477 bra EM1SCALE 7477 bra EM1SCALE 7478 MLE63: 7478 MLE63: 7479 #--Step 6.3 M <= 63 7479 #--Step 6.3 M <= 63 7480 cmp.l %d1,&-3 7480 cmp.l %d1,&-3 7481 bge.b MGEN3 7481 bge.b MGEN3 7482 MLTN3: 7482 MLTN3: 7483 #--Step 6.4 M <= -4 7483 #--Step 6.4 M <= -4 7484 fadd.s 12(%a1),%fp0 7484 fadd.s 12(%a1),%fp0 # p+t 7485 fadd.x (%a1),%fp0 7485 fadd.x (%a1),%fp0 # T+(p+t) 7486 fadd.x ONEBYSC(%a6),%fp0 7486 fadd.x ONEBYSC(%a6),%fp0 # OnebySc + (T+(p+t)) 7487 bra EM1SCALE 7487 bra EM1SCALE 7488 MGEN3: 7488 MGEN3: 7489 #--Step 6.5 -3 <= M <= 63 7489 #--Step 6.5 -3 <= M <= 63 7490 fmov.x (%a1)+,%fp1 7490 fmov.x (%a1)+,%fp1 # fp1 is T 7491 fadd.s (%a1),%fp0 7491 fadd.s (%a1),%fp0 # fp0 is p+t 7492 fadd.x ONEBYSC(%a6),%fp1 7492 fadd.x ONEBYSC(%a6),%fp1 # fp1 is T+OnebySc 7493 fadd.x %fp1,%fp0 7493 fadd.x %fp1,%fp0 # (T+OnebySc)+(p+t) 7494 7494 7495 EM1SCALE: 7495 EM1SCALE: 7496 #--Step 6.6 7496 #--Step 6.6 7497 fmov.l %d0,%fpcr 7497 fmov.l %d0,%fpcr 7498 fmul.x SC(%a6),%fp0 7498 fmul.x SC(%a6),%fp0 7499 bra t_inx2 7499 bra t_inx2 7500 7500 7501 EM1SM: 7501 EM1SM: 7502 #--Step 7 |X| < 1/4. 7502 #--Step 7 |X| < 1/4. 7503 cmp.l %d1,&0x3FBE0000 7503 cmp.l %d1,&0x3FBE0000 # 2^(-65) 7504 bge.b EM1POLY 7504 bge.b EM1POLY 7505 7505 7506 EM1TINY: 7506 EM1TINY: 7507 #--Step 8 |X| < 2^(-65) 7507 #--Step 8 |X| < 2^(-65) 7508 cmp.l %d1,&0x00330000 7508 cmp.l %d1,&0x00330000 # 2^(-16312) 7509 blt.b EM12TINY 7509 blt.b EM12TINY 7510 #--Step 8.2 7510 #--Step 8.2 7511 mov.l &0x80010000,SC(%a6) 7511 mov.l &0x80010000,SC(%a6) # SC is -2^(-16382) 7512 mov.l &0x80000000,SC+4(%a6) 7512 mov.l &0x80000000,SC+4(%a6) 7513 clr.l SC+8(%a6) 7513 clr.l SC+8(%a6) 7514 fmov.x (%a0),%fp0 7514 fmov.x (%a0),%fp0 7515 fmov.l %d0,%fpcr 7515 fmov.l %d0,%fpcr 7516 mov.b &FADD_OP,%d1 7516 mov.b &FADD_OP,%d1 # last inst is ADD 7517 fadd.x SC(%a6),%fp0 7517 fadd.x SC(%a6),%fp0 7518 bra t_catch 7518 bra t_catch 7519 7519 7520 EM12TINY: 7520 EM12TINY: 7521 #--Step 8.3 7521 #--Step 8.3 7522 fmov.x (%a0),%fp0 7522 fmov.x (%a0),%fp0 7523 fmul.d TWO140(%pc),%fp0 7523 fmul.d TWO140(%pc),%fp0 7524 mov.l &0x80010000,SC(%a6) 7524 mov.l &0x80010000,SC(%a6) 7525 mov.l &0x80000000,SC+4(%a6) 7525 mov.l &0x80000000,SC+4(%a6) 7526 clr.l SC+8(%a6) 7526 clr.l SC+8(%a6) 7527 fadd.x SC(%a6),%fp0 7527 fadd.x SC(%a6),%fp0 7528 fmov.l %d0,%fpcr 7528 fmov.l %d0,%fpcr 7529 mov.b &FMUL_OP,%d1 7529 mov.b &FMUL_OP,%d1 # last inst is MUL 7530 fmul.d TWON140(%pc),%fp0 7530 fmul.d TWON140(%pc),%fp0 7531 bra t_catch 7531 bra t_catch 7532 7532 7533 EM1POLY: 7533 EM1POLY: 7534 #--Step 9 exp(X)-1 by a simple polynomi 7534 #--Step 9 exp(X)-1 by a simple polynomial 7535 fmov.x (%a0),%fp0 7535 fmov.x (%a0),%fp0 # fp0 is X 7536 fmul.x %fp0,%fp0 7536 fmul.x %fp0,%fp0 # fp0 is S := X*X 7537 fmovm.x &0xc,-(%sp) 7537 fmovm.x &0xc,-(%sp) # save fp2 {%fp2/%fp3} 7538 fmov.s &0x2F30CAA8,%fp1 7538 fmov.s &0x2F30CAA8,%fp1 # fp1 is B12 7539 fmul.x %fp0,%fp1 7539 fmul.x %fp0,%fp1 # fp1 is S*B12 7540 fmov.s &0x310F8290,%fp2 7540 fmov.s &0x310F8290,%fp2 # fp2 is B11 7541 fadd.s &0x32D73220,%fp1 7541 fadd.s &0x32D73220,%fp1 # fp1 is B10+S*B12 7542 7542 7543 fmul.x %fp0,%fp2 7543 fmul.x %fp0,%fp2 # fp2 is S*B11 7544 fmul.x %fp0,%fp1 7544 fmul.x %fp0,%fp1 # fp1 is S*(B10 + ... 7545 7545 7546 fadd.s &0x3493F281,%fp2 7546 fadd.s &0x3493F281,%fp2 # fp2 is B9+S*... 7547 fadd.d EM1B8(%pc),%fp1 7547 fadd.d EM1B8(%pc),%fp1 # fp1 is B8+S*... 7548 7548 7549 fmul.x %fp0,%fp2 7549 fmul.x %fp0,%fp2 # fp2 is S*(B9+... 7550 fmul.x %fp0,%fp1 7550 fmul.x %fp0,%fp1 # fp1 is S*(B8+... 7551 7551 7552 fadd.d EM1B7(%pc),%fp2 7552 fadd.d EM1B7(%pc),%fp2 # fp2 is B7+S*... 7553 fadd.d EM1B6(%pc),%fp1 7553 fadd.d EM1B6(%pc),%fp1 # fp1 is B6+S*... 7554 7554 7555 fmul.x %fp0,%fp2 7555 fmul.x %fp0,%fp2 # fp2 is S*(B7+... 7556 fmul.x %fp0,%fp1 7556 fmul.x %fp0,%fp1 # fp1 is S*(B6+... 7557 7557 7558 fadd.d EM1B5(%pc),%fp2 7558 fadd.d EM1B5(%pc),%fp2 # fp2 is B5+S*... 7559 fadd.d EM1B4(%pc),%fp1 7559 fadd.d EM1B4(%pc),%fp1 # fp1 is B4+S*... 7560 7560 7561 fmul.x %fp0,%fp2 7561 fmul.x %fp0,%fp2 # fp2 is S*(B5+... 7562 fmul.x %fp0,%fp1 7562 fmul.x %fp0,%fp1 # fp1 is S*(B4+... 7563 7563 7564 fadd.d EM1B3(%pc),%fp2 7564 fadd.d EM1B3(%pc),%fp2 # fp2 is B3+S*... 7565 fadd.x EM1B2(%pc),%fp1 7565 fadd.x EM1B2(%pc),%fp1 # fp1 is B2+S*... 7566 7566 7567 fmul.x %fp0,%fp2 7567 fmul.x %fp0,%fp2 # fp2 is S*(B3+... 7568 fmul.x %fp0,%fp1 7568 fmul.x %fp0,%fp1 # fp1 is S*(B2+... 7569 7569 7570 fmul.x %fp0,%fp2 7570 fmul.x %fp0,%fp2 # fp2 is S*S*(B3+...) 7571 fmul.x (%a0),%fp1 7571 fmul.x (%a0),%fp1 # fp1 is X*S*(B2... 7572 7572 7573 fmul.s &0x3F000000,%fp0 7573 fmul.s &0x3F000000,%fp0 # fp0 is S*B1 7574 fadd.x %fp2,%fp1 7574 fadd.x %fp2,%fp1 # fp1 is Q 7575 7575 7576 fmovm.x (%sp)+,&0x30 7576 fmovm.x (%sp)+,&0x30 # fp2 restored {%fp2/%fp3} 7577 7577 7578 fadd.x %fp1,%fp0 7578 fadd.x %fp1,%fp0 # fp0 is S*B1+Q 7579 7579 7580 fmov.l %d0,%fpcr 7580 fmov.l %d0,%fpcr 7581 fadd.x (%a0),%fp0 7581 fadd.x (%a0),%fp0 7582 bra t_inx2 7582 bra t_inx2 7583 7583 7584 EM1BIG: 7584 EM1BIG: 7585 #--Step 10 |X| > 70 log2 7585 #--Step 10 |X| > 70 log2 7586 mov.l (%a0),%d1 7586 mov.l (%a0),%d1 7587 cmp.l %d1,&0 7587 cmp.l %d1,&0 7588 bgt.w EXPC1 7588 bgt.w EXPC1 7589 #--Step 10.2 7589 #--Step 10.2 7590 fmov.s &0xBF800000,%fp0 7590 fmov.s &0xBF800000,%fp0 # fp0 is -1 7591 fmov.l %d0,%fpcr 7591 fmov.l %d0,%fpcr 7592 fadd.s &0x00800000,%fp0 7592 fadd.s &0x00800000,%fp0 # -1 + 2^(-126) 7593 bra t_minx2 7593 bra t_minx2 7594 7594 7595 global setoxm1d 7595 global setoxm1d 7596 setoxm1d: 7596 setoxm1d: 7597 #--entry point for EXPM1(X), here X is denorm 7597 #--entry point for EXPM1(X), here X is denormalized 7598 #--Step 0. 7598 #--Step 0. 7599 bra t_extdnrm 7599 bra t_extdnrm 7600 7600 7601 ############################################# 7601 ######################################################################### 7602 # sgetexp(): returns the exponent portion of 7602 # sgetexp(): returns the exponent portion of the input argument. # 7603 # The exponent bias is removed an 7603 # The exponent bias is removed and the exponent value is # 7604 # returned as an extended precisi 7604 # returned as an extended precision number in fp0. # 7605 # sgetexpd(): handles denormalized numbers. 7605 # sgetexpd(): handles denormalized numbers. # 7606 # 7606 # # 7607 # sgetman(): extracts the mantissa of the in 7607 # sgetman(): extracts the mantissa of the input argument. The # 7608 # mantissa is converted to an ext 7608 # mantissa is converted to an extended precision number w/ # 7609 # an exponent of $3fff and is ret 7609 # an exponent of $3fff and is returned in fp0. The range of # 7610 # the result is [1.0 - 2.0). 7610 # the result is [1.0 - 2.0). # 7611 # sgetmand(): handles denormalized numbers. 7611 # sgetmand(): handles denormalized numbers. # 7612 # 7612 # # 7613 # INPUT ************************************* 7613 # INPUT *************************************************************** # 7614 # a0 = pointer to extended precision i 7614 # a0 = pointer to extended precision input # 7615 # 7615 # # 7616 # OUTPUT ************************************ 7616 # OUTPUT ************************************************************** # 7617 # fp0 = exponent(X) or mantissa(X) 7617 # fp0 = exponent(X) or mantissa(X) # 7618 # 7618 # # 7619 ############################################# 7619 ######################################################################### 7620 7620 7621 global sgetexp 7621 global sgetexp 7622 sgetexp: 7622 sgetexp: 7623 mov.w SRC_EX(%a0),%d0 7623 mov.w SRC_EX(%a0),%d0 # get the exponent 7624 bclr &0xf,%d0 7624 bclr &0xf,%d0 # clear the sign bit 7625 subi.w &0x3fff,%d0 7625 subi.w &0x3fff,%d0 # subtract off the bias 7626 fmov.w %d0,%fp0 7626 fmov.w %d0,%fp0 # return exp in fp0 7627 blt.b sgetexpn 7627 blt.b sgetexpn # it's negative 7628 rts 7628 rts 7629 7629 7630 sgetexpn: 7630 sgetexpn: 7631 mov.b &neg_bmask,FPSR_CC(%a 7631 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 7632 rts 7632 rts 7633 7633 7634 global sgetexpd 7634 global sgetexpd 7635 sgetexpd: 7635 sgetexpd: 7636 bsr.l norm 7636 bsr.l norm # normalize 7637 neg.w %d0 7637 neg.w %d0 # new exp = -(shft amt) 7638 subi.w &0x3fff,%d0 7638 subi.w &0x3fff,%d0 # subtract off the bias 7639 fmov.w %d0,%fp0 7639 fmov.w %d0,%fp0 # return exp in fp0 7640 mov.b &neg_bmask,FPSR_CC(%a 7640 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 7641 rts 7641 rts 7642 7642 7643 global sgetman 7643 global sgetman 7644 sgetman: 7644 sgetman: 7645 mov.w SRC_EX(%a0),%d0 7645 mov.w SRC_EX(%a0),%d0 # get the exp 7646 ori.w &0x7fff,%d0 7646 ori.w &0x7fff,%d0 # clear old exp 7647 bclr &0xe,%d0 7647 bclr &0xe,%d0 # make it the new exp +-3fff 7648 7648 7649 # here, we build the result in a tmp location 7649 # here, we build the result in a tmp location so as not to disturb the input 7650 mov.l SRC_HI(%a0),FP_SCR0_H 7650 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy to tmp loc 7651 mov.l SRC_LO(%a0),FP_SCR0_L 7651 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy to tmp loc 7652 mov.w %d0,FP_SCR0_EX(%a6) 7652 mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent 7653 fmov.x FP_SCR0(%a6),%fp0 7653 fmov.x FP_SCR0(%a6),%fp0 # put new value back in fp0 7654 bmi.b sgetmann 7654 bmi.b sgetmann # it's negative 7655 rts 7655 rts 7656 7656 7657 sgetmann: 7657 sgetmann: 7658 mov.b &neg_bmask,FPSR_CC(%a 7658 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 7659 rts 7659 rts 7660 7660 7661 # 7661 # 7662 # For denormalized numbers, shift the mantiss 7662 # For denormalized numbers, shift the mantissa until the j-bit = 1, 7663 # then load the exponent with +/1 $3fff. 7663 # then load the exponent with +/1 $3fff. 7664 # 7664 # 7665 global sgetmand 7665 global sgetmand 7666 sgetmand: 7666 sgetmand: 7667 bsr.l norm 7667 bsr.l norm # normalize exponent 7668 bra.b sgetman 7668 bra.b sgetman 7669 7669 7670 ############################################# 7670 ######################################################################### 7671 # scosh(): computes the hyperbolic cosine of 7671 # scosh(): computes the hyperbolic cosine of a normalized input # 7672 # scoshd(): computes the hyperbolic cosine of 7672 # scoshd(): computes the hyperbolic cosine of a denormalized input # 7673 # 7673 # # 7674 # INPUT ************************************* 7674 # INPUT *************************************************************** # 7675 # a0 = pointer to extended precision in 7675 # a0 = pointer to extended precision input # 7676 # d0 = round precision,mode 7676 # d0 = round precision,mode # 7677 # 7677 # # 7678 # OUTPUT ************************************ 7678 # OUTPUT ************************************************************** # 7679 # fp0 = cosh(X) 7679 # fp0 = cosh(X) # 7680 # 7680 # # 7681 # ACCURACY and MONOTONICITY ***************** 7681 # ACCURACY and MONOTONICITY ******************************************* # 7682 # The returned result is within 3 ulps 7682 # The returned result is within 3 ulps in 64 significant bit, # 7683 # i.e. within 0.5001 ulp to 53 bits if 7683 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 7684 # rounded to double precision. The resu 7684 # rounded to double precision. The result is provably monotonic # 7685 # in double precision. 7685 # in double precision. # 7686 # 7686 # # 7687 # ALGORITHM ********************************* 7687 # ALGORITHM *********************************************************** # 7688 # 7688 # # 7689 # COSH 7689 # COSH # 7690 # 1. If |X| > 16380 log2, go to 3. 7690 # 1. If |X| > 16380 log2, go to 3. # 7691 # 7691 # # 7692 # 2. (|X| <= 16380 log2) Cosh(X) is obt 7692 # 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae # 7693 # y = |X|, z = exp(Y), and 7693 # y = |X|, z = exp(Y), and # 7694 # cosh(X) = (1/2)*( z + 1/z ). 7694 # cosh(X) = (1/2)*( z + 1/z ). # 7695 # Exit. 7695 # Exit. # 7696 # 7696 # # 7697 # 3. (|X| > 16380 log2). If |X| > 16480 7697 # 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. # 7698 # 7698 # # 7699 # 4. (16380 log2 < |X| <= 16480 log2) 7699 # 4. (16380 log2 < |X| <= 16480 log2) # 7700 # cosh(X) = sign(X) * exp(|X|)/ 7700 # cosh(X) = sign(X) * exp(|X|)/2. # 7701 # However, invoking exp(|X|) ma 7701 # However, invoking exp(|X|) may cause premature # 7702 # overflow. Thus, we calculate 7702 # overflow. Thus, we calculate sinh(X) as follows: # 7703 # Y := |X| 7703 # Y := |X| # 7704 # Fact := 2**(16380) 7704 # Fact := 2**(16380) # 7705 # Y' := Y - 16381 log2 7705 # Y' := Y - 16381 log2 # 7706 # cosh(X) := Fact * exp(Y'). 7706 # cosh(X) := Fact * exp(Y'). # 7707 # Exit. 7707 # Exit. # 7708 # 7708 # # 7709 # 5. (|X| > 16480 log2) sinh(X) must ov 7709 # 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 7710 # Huge*Huge to generate overflo 7710 # Huge*Huge to generate overflow and an infinity with # 7711 # the appropriate sign. Huge is 7711 # the appropriate sign. Huge is the largest finite number # 7712 # in extended format. Exit. 7712 # in extended format. Exit. # 7713 # 7713 # # 7714 ############################################# 7714 ######################################################################### 7715 7715 7716 TWO16380: 7716 TWO16380: 7717 long 0x7FFB0000,0x80000000 7717 long 0x7FFB0000,0x80000000,0x00000000,0x00000000 7718 7718 7719 global scosh 7719 global scosh 7720 scosh: 7720 scosh: 7721 fmov.x (%a0),%fp0 7721 fmov.x (%a0),%fp0 # LOAD INPUT 7722 7722 7723 mov.l (%a0),%d1 7723 mov.l (%a0),%d1 7724 mov.w 4(%a0),%d1 7724 mov.w 4(%a0),%d1 7725 and.l &0x7FFFFFFF,%d1 7725 and.l &0x7FFFFFFF,%d1 7726 cmp.l %d1,&0x400CB167 7726 cmp.l %d1,&0x400CB167 7727 bgt.b COSHBIG 7727 bgt.b COSHBIG 7728 7728 7729 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 7729 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 7730 #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) ) 7730 #--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) ) 7731 7731 7732 fabs.x %fp0 7732 fabs.x %fp0 # |X| 7733 7733 7734 mov.l %d0,-(%sp) 7734 mov.l %d0,-(%sp) 7735 clr.l %d0 7735 clr.l %d0 7736 fmovm.x &0x01,-(%sp) 7736 fmovm.x &0x01,-(%sp) # save |X| to stack 7737 lea (%sp),%a0 7737 lea (%sp),%a0 # pass ptr to |X| 7738 bsr setox 7738 bsr setox # FP0 IS EXP(|X|) 7739 add.l &0xc,%sp 7739 add.l &0xc,%sp # erase |X| from stack 7740 fmul.s &0x3F000000,%fp0 7740 fmul.s &0x3F000000,%fp0 # (1/2)EXP(|X|) 7741 mov.l (%sp)+,%d0 7741 mov.l (%sp)+,%d0 7742 7742 7743 fmov.s &0x3E800000,%fp1 7743 fmov.s &0x3E800000,%fp1 # (1/4) 7744 fdiv.x %fp0,%fp1 7744 fdiv.x %fp0,%fp1 # 1/(2 EXP(|X|)) 7745 7745 7746 fmov.l %d0,%fpcr 7746 fmov.l %d0,%fpcr 7747 mov.b &FADD_OP,%d1 7747 mov.b &FADD_OP,%d1 # last inst is ADD 7748 fadd.x %fp1,%fp0 7748 fadd.x %fp1,%fp0 7749 bra t_catch 7749 bra t_catch 7750 7750 7751 COSHBIG: 7751 COSHBIG: 7752 cmp.l %d1,&0x400CB2B3 7752 cmp.l %d1,&0x400CB2B3 7753 bgt.b COSHHUGE 7753 bgt.b COSHHUGE 7754 7754 7755 fabs.x %fp0 7755 fabs.x %fp0 7756 fsub.d T1(%pc),%fp0 7756 fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 7757 fsub.d T2(%pc),%fp0 7757 fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 7758 7758 7759 mov.l %d0,-(%sp) 7759 mov.l %d0,-(%sp) 7760 clr.l %d0 7760 clr.l %d0 7761 fmovm.x &0x01,-(%sp) 7761 fmovm.x &0x01,-(%sp) # save fp0 to stack 7762 lea (%sp),%a0 7762 lea (%sp),%a0 # pass ptr to fp0 7763 bsr setox 7763 bsr setox 7764 add.l &0xc,%sp 7764 add.l &0xc,%sp # clear fp0 from stack 7765 mov.l (%sp)+,%d0 7765 mov.l (%sp)+,%d0 7766 7766 7767 fmov.l %d0,%fpcr 7767 fmov.l %d0,%fpcr 7768 mov.b &FMUL_OP,%d1 7768 mov.b &FMUL_OP,%d1 # last inst is MUL 7769 fmul.x TWO16380(%pc),%fp0 7769 fmul.x TWO16380(%pc),%fp0 7770 bra t_catch 7770 bra t_catch 7771 7771 7772 COSHHUGE: 7772 COSHHUGE: 7773 bra t_ovfl2 7773 bra t_ovfl2 7774 7774 7775 global scoshd 7775 global scoshd 7776 #--COSH(X) = 1 FOR DENORMALIZED X 7776 #--COSH(X) = 1 FOR DENORMALIZED X 7777 scoshd: 7777 scoshd: 7778 fmov.s &0x3F800000,%fp0 7778 fmov.s &0x3F800000,%fp0 7779 7779 7780 fmov.l %d0,%fpcr 7780 fmov.l %d0,%fpcr 7781 fadd.s &0x00800000,%fp0 7781 fadd.s &0x00800000,%fp0 7782 bra t_pinx2 7782 bra t_pinx2 7783 7783 7784 ############################################# 7784 ######################################################################### 7785 # ssinh(): computes the hyperbolic sine of a 7785 # ssinh(): computes the hyperbolic sine of a normalized input # 7786 # ssinhd(): computes the hyperbolic sine of a 7786 # ssinhd(): computes the hyperbolic sine of a denormalized input # 7787 # 7787 # # 7788 # INPUT ************************************* 7788 # INPUT *************************************************************** # 7789 # a0 = pointer to extended precision in 7789 # a0 = pointer to extended precision input # 7790 # d0 = round precision,mode 7790 # d0 = round precision,mode # 7791 # 7791 # # 7792 # OUTPUT ************************************ 7792 # OUTPUT ************************************************************** # 7793 # fp0 = sinh(X) 7793 # fp0 = sinh(X) # 7794 # 7794 # # 7795 # ACCURACY and MONOTONICITY ***************** 7795 # ACCURACY and MONOTONICITY ******************************************* # 7796 # The returned result is within 3 ulps 7796 # The returned result is within 3 ulps in 64 significant bit, # 7797 # i.e. within 0.5001 ulp to 53 bits if 7797 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 7798 # rounded to double precision. The resu 7798 # rounded to double precision. The result is provably monotonic # 7799 # in double precision. 7799 # in double precision. # 7800 # 7800 # # 7801 # ALGORITHM ********************************* 7801 # ALGORITHM *********************************************************** # 7802 # 7802 # # 7803 # SINH 7803 # SINH # 7804 # 1. If |X| > 16380 log2, go to 3. 7804 # 1. If |X| > 16380 log2, go to 3. # 7805 # 7805 # # 7806 # 2. (|X| <= 16380 log2) Sinh(X) is obt 7806 # 2. (|X| <= 16380 log2) Sinh(X) is obtained by the formula # 7807 # y = |X|, sgn = sign(X), and z 7807 # y = |X|, sgn = sign(X), and z = expm1(Y), # 7808 # sinh(X) = sgn*(1/2)*( z + z/( 7808 # sinh(X) = sgn*(1/2)*( z + z/(1+z) ). # 7809 # Exit. 7809 # Exit. # 7810 # 7810 # # 7811 # 3. If |X| > 16480 log2, go to 5. 7811 # 3. If |X| > 16480 log2, go to 5. # 7812 # 7812 # # 7813 # 4. (16380 log2 < |X| <= 16480 log2) 7813 # 4. (16380 log2 < |X| <= 16480 log2) # 7814 # sinh(X) = sign(X) * exp(|X|)/ 7814 # sinh(X) = sign(X) * exp(|X|)/2. # 7815 # However, invoking exp(|X|) may cau 7815 # However, invoking exp(|X|) may cause premature overflow. # 7816 # Thus, we calculate sinh(X) as foll 7816 # Thus, we calculate sinh(X) as follows: # 7817 # Y := |X| 7817 # Y := |X| # 7818 # sgn := sign(X) 7818 # sgn := sign(X) # 7819 # sgnFact := sgn * 2**(16380) 7819 # sgnFact := sgn * 2**(16380) # 7820 # Y' := Y - 16381 log2 7820 # Y' := Y - 16381 log2 # 7821 # sinh(X) := sgnFact * exp(Y'). 7821 # sinh(X) := sgnFact * exp(Y'). # 7822 # Exit. 7822 # Exit. # 7823 # 7823 # # 7824 # 5. (|X| > 16480 log2) sinh(X) must ov 7824 # 5. (|X| > 16480 log2) sinh(X) must overflow. Return # 7825 # sign(X)*Huge*Huge to generate over 7825 # sign(X)*Huge*Huge to generate overflow and an infinity with # 7826 # the appropriate sign. Huge is the 7826 # the appropriate sign. Huge is the largest finite number in # 7827 # extended format. Exit. 7827 # extended format. Exit. # 7828 # 7828 # # 7829 ############################################# 7829 ######################################################################### 7830 7830 7831 global ssinh 7831 global ssinh 7832 ssinh: 7832 ssinh: 7833 fmov.x (%a0),%fp0 7833 fmov.x (%a0),%fp0 # LOAD INPUT 7834 7834 7835 mov.l (%a0),%d1 7835 mov.l (%a0),%d1 7836 mov.w 4(%a0),%d1 7836 mov.w 4(%a0),%d1 7837 mov.l %d1,%a1 7837 mov.l %d1,%a1 # save (compacted) operand 7838 and.l &0x7FFFFFFF,%d1 7838 and.l &0x7FFFFFFF,%d1 7839 cmp.l %d1,&0x400CB167 7839 cmp.l %d1,&0x400CB167 7840 bgt.b SINHBIG 7840 bgt.b SINHBIG 7841 7841 7842 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 7842 #--THIS IS THE USUAL CASE, |X| < 16380 LOG2 7843 #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*( 7843 #--Y = |X|, Z = EXPM1(Y), SINH(X) = SIGN(X)*(1/2)*( Z + Z/(1+Z) ) 7844 7844 7845 fabs.x %fp0 7845 fabs.x %fp0 # Y = |X| 7846 7846 7847 movm.l &0x8040,-(%sp) 7847 movm.l &0x8040,-(%sp) # {a1/d0} 7848 fmovm.x &0x01,-(%sp) 7848 fmovm.x &0x01,-(%sp) # save Y on stack 7849 lea (%sp),%a0 7849 lea (%sp),%a0 # pass ptr to Y 7850 clr.l %d0 7850 clr.l %d0 7851 bsr setoxm1 7851 bsr setoxm1 # FP0 IS Z = EXPM1(Y) 7852 add.l &0xc,%sp 7852 add.l &0xc,%sp # clear Y from stack 7853 fmov.l &0,%fpcr 7853 fmov.l &0,%fpcr 7854 movm.l (%sp)+,&0x0201 7854 movm.l (%sp)+,&0x0201 # {a1/d0} 7855 7855 7856 fmov.x %fp0,%fp1 7856 fmov.x %fp0,%fp1 7857 fadd.s &0x3F800000,%fp1 7857 fadd.s &0x3F800000,%fp1 # 1+Z 7858 fmov.x %fp0,-(%sp) 7858 fmov.x %fp0,-(%sp) 7859 fdiv.x %fp1,%fp0 7859 fdiv.x %fp1,%fp0 # Z/(1+Z) 7860 mov.l %a1,%d1 7860 mov.l %a1,%d1 7861 and.l &0x80000000,%d1 7861 and.l &0x80000000,%d1 7862 or.l &0x3F000000,%d1 7862 or.l &0x3F000000,%d1 7863 fadd.x (%sp)+,%fp0 7863 fadd.x (%sp)+,%fp0 7864 mov.l %d1,-(%sp) 7864 mov.l %d1,-(%sp) 7865 7865 7866 fmov.l %d0,%fpcr 7866 fmov.l %d0,%fpcr 7867 mov.b &FMUL_OP,%d1 7867 mov.b &FMUL_OP,%d1 # last inst is MUL 7868 fmul.s (%sp)+,%fp0 7868 fmul.s (%sp)+,%fp0 # last fp inst - possible exceptions set 7869 bra t_catch 7869 bra t_catch 7870 7870 7871 SINHBIG: 7871 SINHBIG: 7872 cmp.l %d1,&0x400CB2B3 7872 cmp.l %d1,&0x400CB2B3 7873 bgt t_ovfl 7873 bgt t_ovfl 7874 fabs.x %fp0 7874 fabs.x %fp0 7875 fsub.d T1(%pc),%fp0 7875 fsub.d T1(%pc),%fp0 # (|X|-16381LOG2_LEAD) 7876 mov.l &0,-(%sp) 7876 mov.l &0,-(%sp) 7877 mov.l &0x80000000,-(%sp) 7877 mov.l &0x80000000,-(%sp) 7878 mov.l %a1,%d1 7878 mov.l %a1,%d1 7879 and.l &0x80000000,%d1 7879 and.l &0x80000000,%d1 7880 or.l &0x7FFB0000,%d1 7880 or.l &0x7FFB0000,%d1 7881 mov.l %d1,-(%sp) 7881 mov.l %d1,-(%sp) # EXTENDED FMT 7882 fsub.d T2(%pc),%fp0 7882 fsub.d T2(%pc),%fp0 # |X| - 16381 LOG2, ACCURATE 7883 7883 7884 mov.l %d0,-(%sp) 7884 mov.l %d0,-(%sp) 7885 clr.l %d0 7885 clr.l %d0 7886 fmovm.x &0x01,-(%sp) 7886 fmovm.x &0x01,-(%sp) # save fp0 on stack 7887 lea (%sp),%a0 7887 lea (%sp),%a0 # pass ptr to fp0 7888 bsr setox 7888 bsr setox 7889 add.l &0xc,%sp 7889 add.l &0xc,%sp # clear fp0 from stack 7890 7890 7891 mov.l (%sp)+,%d0 7891 mov.l (%sp)+,%d0 7892 fmov.l %d0,%fpcr 7892 fmov.l %d0,%fpcr 7893 mov.b &FMUL_OP,%d1 7893 mov.b &FMUL_OP,%d1 # last inst is MUL 7894 fmul.x (%sp)+,%fp0 7894 fmul.x (%sp)+,%fp0 # possible exception 7895 bra t_catch 7895 bra t_catch 7896 7896 7897 global ssinhd 7897 global ssinhd 7898 #--SINH(X) = X FOR DENORMALIZED X 7898 #--SINH(X) = X FOR DENORMALIZED X 7899 ssinhd: 7899 ssinhd: 7900 bra t_extdnrm 7900 bra t_extdnrm 7901 7901 7902 ############################################# 7902 ######################################################################### 7903 # stanh(): computes the hyperbolic tangent o 7903 # stanh(): computes the hyperbolic tangent of a normalized input # 7904 # stanhd(): computes the hyperbolic tangent o 7904 # stanhd(): computes the hyperbolic tangent of a denormalized input # 7905 # 7905 # # 7906 # INPUT ************************************* 7906 # INPUT *************************************************************** # 7907 # a0 = pointer to extended precision in 7907 # a0 = pointer to extended precision input # 7908 # d0 = round precision,mode 7908 # d0 = round precision,mode # 7909 # 7909 # # 7910 # OUTPUT ************************************ 7910 # OUTPUT ************************************************************** # 7911 # fp0 = tanh(X) 7911 # fp0 = tanh(X) # 7912 # 7912 # # 7913 # ACCURACY and MONOTONICITY ***************** 7913 # ACCURACY and MONOTONICITY ******************************************* # 7914 # The returned result is within 3 ulps 7914 # The returned result is within 3 ulps in 64 significant bit, # 7915 # i.e. within 0.5001 ulp to 53 bits if 7915 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 7916 # rounded to double precision. The resu 7916 # rounded to double precision. The result is provably monotonic # 7917 # in double precision. 7917 # in double precision. # 7918 # 7918 # # 7919 # ALGORITHM ********************************* 7919 # ALGORITHM *********************************************************** # 7920 # 7920 # # 7921 # TANH 7921 # TANH # 7922 # 1. If |X| >= (5/2) log2 or |X| <= 2** 7922 # 1. If |X| >= (5/2) log2 or |X| <= 2**(-40), go to 3. # 7923 # 7923 # # 7924 # 2. (2**(-40) < |X| < (5/2) log2) Calc 7924 # 2. (2**(-40) < |X| < (5/2) log2) Calculate tanh(X) by # 7925 # sgn := sign(X), y := 2|X|, z 7925 # sgn := sign(X), y := 2|X|, z := expm1(Y), and # 7926 # tanh(X) = sgn*( z/(2+z) ). 7926 # tanh(X) = sgn*( z/(2+z) ). # 7927 # Exit. 7927 # Exit. # 7928 # 7928 # # 7929 # 3. (|X| <= 2**(-40) or |X| >= (5/2) l 7929 # 3. (|X| <= 2**(-40) or |X| >= (5/2) log2). If |X| < 1, # 7930 # go to 7. 7930 # go to 7. # 7931 # 7931 # # 7932 # 4. (|X| >= (5/2) log2) If |X| >= 50 l 7932 # 4. (|X| >= (5/2) log2) If |X| >= 50 log2, go to 6. # 7933 # 7933 # # 7934 # 5. ((5/2) log2 <= |X| < 50 log2) Calc 7934 # 5. ((5/2) log2 <= |X| < 50 log2) Calculate tanh(X) by # 7935 # sgn := sign(X), y := 2|X|, z 7935 # sgn := sign(X), y := 2|X|, z := exp(Y), # 7936 # tanh(X) = sgn - [ sgn*2/(1+z) 7936 # tanh(X) = sgn - [ sgn*2/(1+z) ]. # 7937 # Exit. 7937 # Exit. # 7938 # 7938 # # 7939 # 6. (|X| >= 50 log2) Tanh(X) = +-1 (ro 7939 # 6. (|X| >= 50 log2) Tanh(X) = +-1 (round to nearest). Thus, we # 7940 # calculate Tanh(X) by 7940 # calculate Tanh(X) by # 7941 # sgn := sign(X), Tiny := 2**(- 7941 # sgn := sign(X), Tiny := 2**(-126), # 7942 # tanh(X) := sgn - sgn*Tiny. 7942 # tanh(X) := sgn - sgn*Tiny. # 7943 # Exit. 7943 # Exit. # 7944 # 7944 # # 7945 # 7. (|X| < 2**(-40)). Tanh(X) = X. 7945 # 7. (|X| < 2**(-40)). Tanh(X) = X. Exit. # 7946 # 7946 # # 7947 ############################################# 7947 ######################################################################### 7948 7948 7949 set X,FP_SCR0 7949 set X,FP_SCR0 7950 set XFRAC,X+4 7950 set XFRAC,X+4 7951 7951 7952 set SGN,L_SCR3 7952 set SGN,L_SCR3 7953 7953 7954 set V,FP_SCR0 7954 set V,FP_SCR0 7955 7955 7956 global stanh 7956 global stanh 7957 stanh: 7957 stanh: 7958 fmov.x (%a0),%fp0 7958 fmov.x (%a0),%fp0 # LOAD INPUT 7959 7959 7960 fmov.x %fp0,X(%a6) 7960 fmov.x %fp0,X(%a6) 7961 mov.l (%a0),%d1 7961 mov.l (%a0),%d1 7962 mov.w 4(%a0),%d1 7962 mov.w 4(%a0),%d1 7963 mov.l %d1,X(%a6) 7963 mov.l %d1,X(%a6) 7964 and.l &0x7FFFFFFF,%d1 7964 and.l &0x7FFFFFFF,%d1 7965 cmp.l %d1, &0x3fd78000 7965 cmp.l %d1, &0x3fd78000 # is |X| < 2^(-40)? 7966 blt.w TANHBORS 7966 blt.w TANHBORS # yes 7967 cmp.l %d1, &0x3fffddce 7967 cmp.l %d1, &0x3fffddce # is |X| > (5/2)LOG2? 7968 bgt.w TANHBORS 7968 bgt.w TANHBORS # yes 7969 7969 7970 #--THIS IS THE USUAL CASE 7970 #--THIS IS THE USUAL CASE 7971 #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) 7971 #--Y = 2|X|, Z = EXPM1(Y), TANH(X) = SIGN(X) * Z / (Z+2). 7972 7972 7973 mov.l X(%a6),%d1 7973 mov.l X(%a6),%d1 7974 mov.l %d1,SGN(%a6) 7974 mov.l %d1,SGN(%a6) 7975 and.l &0x7FFF0000,%d1 7975 and.l &0x7FFF0000,%d1 7976 add.l &0x00010000,%d1 7976 add.l &0x00010000,%d1 # EXPONENT OF 2|X| 7977 mov.l %d1,X(%a6) 7977 mov.l %d1,X(%a6) 7978 and.l &0x80000000,SGN(%a6) 7978 and.l &0x80000000,SGN(%a6) 7979 fmov.x X(%a6),%fp0 7979 fmov.x X(%a6),%fp0 # FP0 IS Y = 2|X| 7980 7980 7981 mov.l %d0,-(%sp) 7981 mov.l %d0,-(%sp) 7982 clr.l %d0 7982 clr.l %d0 7983 fmovm.x &0x1,-(%sp) 7983 fmovm.x &0x1,-(%sp) # save Y on stack 7984 lea (%sp),%a0 7984 lea (%sp),%a0 # pass ptr to Y 7985 bsr setoxm1 7985 bsr setoxm1 # FP0 IS Z = EXPM1(Y) 7986 add.l &0xc,%sp 7986 add.l &0xc,%sp # clear Y from stack 7987 mov.l (%sp)+,%d0 7987 mov.l (%sp)+,%d0 7988 7988 7989 fmov.x %fp0,%fp1 7989 fmov.x %fp0,%fp1 7990 fadd.s &0x40000000,%fp1 7990 fadd.s &0x40000000,%fp1 # Z+2 7991 mov.l SGN(%a6),%d1 7991 mov.l SGN(%a6),%d1 7992 fmov.x %fp1,V(%a6) 7992 fmov.x %fp1,V(%a6) 7993 eor.l %d1,V(%a6) 7993 eor.l %d1,V(%a6) 7994 7994 7995 fmov.l %d0,%fpcr 7995 fmov.l %d0,%fpcr # restore users round prec,mode 7996 fdiv.x V(%a6),%fp0 7996 fdiv.x V(%a6),%fp0 7997 bra t_inx2 7997 bra t_inx2 7998 7998 7999 TANHBORS: 7999 TANHBORS: 8000 cmp.l %d1,&0x3FFF8000 8000 cmp.l %d1,&0x3FFF8000 8001 blt.w TANHSM 8001 blt.w TANHSM 8002 8002 8003 cmp.l %d1,&0x40048AA1 8003 cmp.l %d1,&0x40048AA1 8004 bgt.w TANHHUGE 8004 bgt.w TANHHUGE 8005 8005 8006 #-- (5/2) LOG2 < |X| < 50 LOG2, 8006 #-- (5/2) LOG2 < |X| < 50 LOG2, 8007 #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X 8007 #--TANH(X) = 1 - (2/[EXP(2X)+1]). LET Y = 2|X|, SGN = SIGN(X), 8008 #--TANH(X) = SGN - SGN*2/[EXP(Y)+1]. 8008 #--TANH(X) = SGN - SGN*2/[EXP(Y)+1]. 8009 8009 8010 mov.l X(%a6),%d1 8010 mov.l X(%a6),%d1 8011 mov.l %d1,SGN(%a6) 8011 mov.l %d1,SGN(%a6) 8012 and.l &0x7FFF0000,%d1 8012 and.l &0x7FFF0000,%d1 8013 add.l &0x00010000,%d1 8013 add.l &0x00010000,%d1 # EXPO OF 2|X| 8014 mov.l %d1,X(%a6) 8014 mov.l %d1,X(%a6) # Y = 2|X| 8015 and.l &0x80000000,SGN(%a6) 8015 and.l &0x80000000,SGN(%a6) 8016 mov.l SGN(%a6),%d1 8016 mov.l SGN(%a6),%d1 8017 fmov.x X(%a6),%fp0 8017 fmov.x X(%a6),%fp0 # Y = 2|X| 8018 8018 8019 mov.l %d0,-(%sp) 8019 mov.l %d0,-(%sp) 8020 clr.l %d0 8020 clr.l %d0 8021 fmovm.x &0x01,-(%sp) 8021 fmovm.x &0x01,-(%sp) # save Y on stack 8022 lea (%sp),%a0 8022 lea (%sp),%a0 # pass ptr to Y 8023 bsr setox 8023 bsr setox # FP0 IS EXP(Y) 8024 add.l &0xc,%sp 8024 add.l &0xc,%sp # clear Y from stack 8025 mov.l (%sp)+,%d0 8025 mov.l (%sp)+,%d0 8026 mov.l SGN(%a6),%d1 8026 mov.l SGN(%a6),%d1 8027 fadd.s &0x3F800000,%fp0 8027 fadd.s &0x3F800000,%fp0 # EXP(Y)+1 8028 8028 8029 eor.l &0xC0000000,%d1 8029 eor.l &0xC0000000,%d1 # -SIGN(X)*2 8030 fmov.s %d1,%fp1 8030 fmov.s %d1,%fp1 # -SIGN(X)*2 IN SGL FMT 8031 fdiv.x %fp0,%fp1 8031 fdiv.x %fp0,%fp1 # -SIGN(X)2 / [EXP(Y)+1 ] 8032 8032 8033 mov.l SGN(%a6),%d1 8033 mov.l SGN(%a6),%d1 8034 or.l &0x3F800000,%d1 8034 or.l &0x3F800000,%d1 # SGN 8035 fmov.s %d1,%fp0 8035 fmov.s %d1,%fp0 # SGN IN SGL FMT 8036 8036 8037 fmov.l %d0,%fpcr 8037 fmov.l %d0,%fpcr # restore users round prec,mode 8038 mov.b &FADD_OP,%d1 8038 mov.b &FADD_OP,%d1 # last inst is ADD 8039 fadd.x %fp1,%fp0 8039 fadd.x %fp1,%fp0 8040 bra t_inx2 8040 bra t_inx2 8041 8041 8042 TANHSM: 8042 TANHSM: 8043 fmov.l %d0,%fpcr 8043 fmov.l %d0,%fpcr # restore users round prec,mode 8044 mov.b &FMOV_OP,%d1 8044 mov.b &FMOV_OP,%d1 # last inst is MOVE 8045 fmov.x X(%a6),%fp0 8045 fmov.x X(%a6),%fp0 # last inst - possible exception set 8046 bra t_catch 8046 bra t_catch 8047 8047 8048 #---RETURN SGN(X) - SGN(X)EPS 8048 #---RETURN SGN(X) - SGN(X)EPS 8049 TANHHUGE: 8049 TANHHUGE: 8050 mov.l X(%a6),%d1 8050 mov.l X(%a6),%d1 8051 and.l &0x80000000,%d1 8051 and.l &0x80000000,%d1 8052 or.l &0x3F800000,%d1 8052 or.l &0x3F800000,%d1 8053 fmov.s %d1,%fp0 8053 fmov.s %d1,%fp0 8054 and.l &0x80000000,%d1 8054 and.l &0x80000000,%d1 8055 eor.l &0x80800000,%d1 8055 eor.l &0x80800000,%d1 # -SIGN(X)*EPS 8056 8056 8057 fmov.l %d0,%fpcr 8057 fmov.l %d0,%fpcr # restore users round prec,mode 8058 fadd.s %d1,%fp0 8058 fadd.s %d1,%fp0 8059 bra t_inx2 8059 bra t_inx2 8060 8060 8061 global stanhd 8061 global stanhd 8062 #--TANH(X) = X FOR DENORMALIZED X 8062 #--TANH(X) = X FOR DENORMALIZED X 8063 stanhd: 8063 stanhd: 8064 bra t_extdnrm 8064 bra t_extdnrm 8065 8065 8066 ############################################# 8066 ######################################################################### 8067 # slogn(): computes the natural logarithm 8067 # slogn(): computes the natural logarithm of a normalized input # 8068 # slognd(): computes the natural logarithm 8068 # slognd(): computes the natural logarithm of a denormalized input # 8069 # slognp1(): computes the log(1+X) of a norm 8069 # slognp1(): computes the log(1+X) of a normalized input # 8070 # slognp1d(): computes the log(1+X) of a deno 8070 # slognp1d(): computes the log(1+X) of a denormalized input # 8071 # 8071 # # 8072 # INPUT ************************************* 8072 # INPUT *************************************************************** # 8073 # a0 = pointer to extended precision in 8073 # a0 = pointer to extended precision input # 8074 # d0 = round precision,mode 8074 # d0 = round precision,mode # 8075 # 8075 # # 8076 # OUTPUT ************************************ 8076 # OUTPUT ************************************************************** # 8077 # fp0 = log(X) or log(1+X) 8077 # fp0 = log(X) or log(1+X) # 8078 # 8078 # # 8079 # ACCURACY and MONOTONICITY ***************** 8079 # ACCURACY and MONOTONICITY ******************************************* # 8080 # The returned result is within 2 ulps 8080 # The returned result is within 2 ulps in 64 significant bit, # 8081 # i.e. within 0.5001 ulp to 53 bits if 8081 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 8082 # rounded to double precision. The resu 8082 # rounded to double precision. The result is provably monotonic # 8083 # in double precision. 8083 # in double precision. # 8084 # 8084 # # 8085 # ALGORITHM ********************************* 8085 # ALGORITHM *********************************************************** # 8086 # LOGN: 8086 # LOGN: # 8087 # Step 1. If |X-1| < 1/16, approximate 8087 # Step 1. If |X-1| < 1/16, approximate log(X) by an odd # 8088 # polynomial in u, where u = 2( 8088 # polynomial in u, where u = 2(X-1)/(X+1). Otherwise, # 8089 # move on to Step 2. 8089 # move on to Step 2. # 8090 # 8090 # # 8091 # Step 2. X = 2**k * Y where 1 <= Y < 2 8091 # Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first # 8092 # seven significant bits of Y p 8092 # seven significant bits of Y plus 2**(-7), i.e. # 8093 # F = 1.xxxxxx1 in base 2 where 8093 # F = 1.xxxxxx1 in base 2 where the six "x" match those # 8094 # of Y. Note that |Y-F| <= 2**( 8094 # of Y. Note that |Y-F| <= 2**(-7). # 8095 # 8095 # # 8096 # Step 3. Define u = (Y-F)/F. Approxima 8096 # Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a # 8097 # polynomial in u, log(1+u) = p 8097 # polynomial in u, log(1+u) = poly. # 8098 # 8098 # # 8099 # Step 4. Reconstruct 8099 # Step 4. Reconstruct # 8100 # log(X) = log( 2**k * Y ) = k* 8100 # log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) # 8101 # by k*log(2) + (log(F) + poly) 8101 # by k*log(2) + (log(F) + poly). The values of log(F) are # 8102 # calculated beforehand and sto 8102 # calculated beforehand and stored in the program. # 8103 # 8103 # # 8104 # lognp1: 8104 # lognp1: # 8105 # Step 1: If |X| < 1/16, approximate lo 8105 # Step 1: If |X| < 1/16, approximate log(1+X) by an odd # 8106 # polynomial in u where u = 2X/ 8106 # polynomial in u where u = 2X/(2+X). Otherwise, move on # 8107 # to Step 2. 8107 # to Step 2. # 8108 # 8108 # # 8109 # Step 2: Let 1+X = 2**k * Y, where 1 < 8109 # Step 2: Let 1+X = 2**k * Y, where 1 <= Y < 2. Define F as done # 8110 # in Step 2 of the algorithm fo 8110 # in Step 2 of the algorithm for LOGN and compute # 8111 # log(1+X) as k*log(2) + log(F) 8111 # log(1+X) as k*log(2) + log(F) + poly where poly # 8112 # approximates log(1+u), u = (Y 8112 # approximates log(1+u), u = (Y-F)/F. # 8113 # 8113 # # 8114 # Implementation Notes: 8114 # Implementation Notes: # 8115 # Note 1. There are 64 different possib 8115 # Note 1. There are 64 different possible values for F, thus 64 # 8116 # log(F)'s need to be tabulated 8116 # log(F)'s need to be tabulated. Moreover, the values of # 8117 # 1/F are also tabulated so tha 8117 # 1/F are also tabulated so that the division in (Y-F)/F # 8118 # can be performed by a multipl 8118 # can be performed by a multiplication. # 8119 # 8119 # # 8120 # Note 2. In Step 2 of lognp1, in order 8120 # Note 2. In Step 2 of lognp1, in order to preserved accuracy, # 8121 # the value Y-F has to be calcu 8121 # the value Y-F has to be calculated carefully when # 8122 # 1/2 <= X < 3/2. 8122 # 1/2 <= X < 3/2. # 8123 # 8123 # # 8124 # Note 3. To fully exploit the pipeline 8124 # Note 3. To fully exploit the pipeline, polynomials are usually # 8125 # separated into two parts eval 8125 # separated into two parts evaluated independently before # 8126 # being added up. 8126 # being added up. # 8127 # 8127 # # 8128 ############################################# 8128 ######################################################################### 8129 LOGOF2: 8129 LOGOF2: 8130 long 0x3FFE0000,0xB17217F7 8130 long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 8131 8131 8132 one: 8132 one: 8133 long 0x3F800000 8133 long 0x3F800000 8134 zero: 8134 zero: 8135 long 0x00000000 8135 long 0x00000000 8136 infty: 8136 infty: 8137 long 0x7F800000 8137 long 0x7F800000 8138 negone: 8138 negone: 8139 long 0xBF800000 8139 long 0xBF800000 8140 8140 8141 LOGA6: 8141 LOGA6: 8142 long 0x3FC2499A,0xB5E4040B 8142 long 0x3FC2499A,0xB5E4040B 8143 LOGA5: 8143 LOGA5: 8144 long 0xBFC555B5,0x848CB7DB 8144 long 0xBFC555B5,0x848CB7DB 8145 8145 8146 LOGA4: 8146 LOGA4: 8147 long 0x3FC99999,0x987D8730 8147 long 0x3FC99999,0x987D8730 8148 LOGA3: 8148 LOGA3: 8149 long 0xBFCFFFFF,0xFF6F7E97 8149 long 0xBFCFFFFF,0xFF6F7E97 8150 8150 8151 LOGA2: 8151 LOGA2: 8152 long 0x3FD55555,0x555555A4 8152 long 0x3FD55555,0x555555A4 8153 LOGA1: 8153 LOGA1: 8154 long 0xBFE00000,0x00000008 8154 long 0xBFE00000,0x00000008 8155 8155 8156 LOGB5: 8156 LOGB5: 8157 long 0x3F175496,0xADD7DAD6 8157 long 0x3F175496,0xADD7DAD6 8158 LOGB4: 8158 LOGB4: 8159 long 0x3F3C71C2,0xFE80C7E0 8159 long 0x3F3C71C2,0xFE80C7E0 8160 8160 8161 LOGB3: 8161 LOGB3: 8162 long 0x3F624924,0x928BCCFF 8162 long 0x3F624924,0x928BCCFF 8163 LOGB2: 8163 LOGB2: 8164 long 0x3F899999,0x999995EC 8164 long 0x3F899999,0x999995EC 8165 8165 8166 LOGB1: 8166 LOGB1: 8167 long 0x3FB55555,0x55555555 8167 long 0x3FB55555,0x55555555 8168 TWO: 8168 TWO: 8169 long 0x40000000,0x00000000 8169 long 0x40000000,0x00000000 8170 8170 8171 LTHOLD: 8171 LTHOLD: 8172 long 0x3f990000,0x80000000 8172 long 0x3f990000,0x80000000,0x00000000,0x00000000 8173 8173 8174 LOGTBL: 8174 LOGTBL: 8175 long 0x3FFE0000,0xFE03F80F 8175 long 0x3FFE0000,0xFE03F80F,0xE03F80FE,0x00000000 8176 long 0x3FF70000,0xFF015358 8176 long 0x3FF70000,0xFF015358,0x833C47E2,0x00000000 8177 long 0x3FFE0000,0xFA232CF2 8177 long 0x3FFE0000,0xFA232CF2,0x52138AC0,0x00000000 8178 long 0x3FF90000,0xBDC8D83E 8178 long 0x3FF90000,0xBDC8D83E,0xAD88D549,0x00000000 8179 long 0x3FFE0000,0xF6603D98 8179 long 0x3FFE0000,0xF6603D98,0x0F6603DA,0x00000000 8180 long 0x3FFA0000,0x9CF43DCF 8180 long 0x3FFA0000,0x9CF43DCF,0xF5EAFD48,0x00000000 8181 long 0x3FFE0000,0xF2B9D648 8181 long 0x3FFE0000,0xF2B9D648,0x0F2B9D65,0x00000000 8182 long 0x3FFA0000,0xDA16EB88 8182 long 0x3FFA0000,0xDA16EB88,0xCB8DF614,0x00000000 8183 long 0x3FFE0000,0xEF2EB71F 8183 long 0x3FFE0000,0xEF2EB71F,0xC4345238,0x00000000 8184 long 0x3FFB0000,0x8B29B775 8184 long 0x3FFB0000,0x8B29B775,0x1BD70743,0x00000000 8185 long 0x3FFE0000,0xEBBDB2A5 8185 long 0x3FFE0000,0xEBBDB2A5,0xC1619C8C,0x00000000 8186 long 0x3FFB0000,0xA8D839F8 8186 long 0x3FFB0000,0xA8D839F8,0x30C1FB49,0x00000000 8187 long 0x3FFE0000,0xE865AC7B 8187 long 0x3FFE0000,0xE865AC7B,0x7603A197,0x00000000 8188 long 0x3FFB0000,0xC61A2EB1 8188 long 0x3FFB0000,0xC61A2EB1,0x8CD907AD,0x00000000 8189 long 0x3FFE0000,0xE525982A 8189 long 0x3FFE0000,0xE525982A,0xF70C880E,0x00000000 8190 long 0x3FFB0000,0xE2F2A47A 8190 long 0x3FFB0000,0xE2F2A47A,0xDE3A18AF,0x00000000 8191 long 0x3FFE0000,0xE1FC780E 8191 long 0x3FFE0000,0xE1FC780E,0x1FC780E2,0x00000000 8192 long 0x3FFB0000,0xFF64898E 8192 long 0x3FFB0000,0xFF64898E,0xDF55D551,0x00000000 8193 long 0x3FFE0000,0xDEE95C4C 8193 long 0x3FFE0000,0xDEE95C4C,0xA037BA57,0x00000000 8194 long 0x3FFC0000,0x8DB956A9 8194 long 0x3FFC0000,0x8DB956A9,0x7B3D0148,0x00000000 8195 long 0x3FFE0000,0xDBEB61EE 8195 long 0x3FFE0000,0xDBEB61EE,0xD19C5958,0x00000000 8196 long 0x3FFC0000,0x9B8FE100 8196 long 0x3FFC0000,0x9B8FE100,0xF47BA1DE,0x00000000 8197 long 0x3FFE0000,0xD901B203 8197 long 0x3FFE0000,0xD901B203,0x6406C80E,0x00000000 8198 long 0x3FFC0000,0xA9372F1D 8198 long 0x3FFC0000,0xA9372F1D,0x0DA1BD17,0x00000000 8199 long 0x3FFE0000,0xD62B80D6 8199 long 0x3FFE0000,0xD62B80D6,0x2B80D62C,0x00000000 8200 long 0x3FFC0000,0xB6B07F38 8200 long 0x3FFC0000,0xB6B07F38,0xCE90E46B,0x00000000 8201 long 0x3FFE0000,0xD3680D36 8201 long 0x3FFE0000,0xD3680D36,0x80D3680D,0x00000000 8202 long 0x3FFC0000,0xC3FD0329 8202 long 0x3FFC0000,0xC3FD0329,0x06488481,0x00000000 8203 long 0x3FFE0000,0xD0B69FCB 8203 long 0x3FFE0000,0xD0B69FCB,0xD2580D0B,0x00000000 8204 long 0x3FFC0000,0xD11DE0FF 8204 long 0x3FFC0000,0xD11DE0FF,0x15AB18CA,0x00000000 8205 long 0x3FFE0000,0xCE168A77 8205 long 0x3FFE0000,0xCE168A77,0x25080CE1,0x00000000 8206 long 0x3FFC0000,0xDE1433A1 8206 long 0x3FFC0000,0xDE1433A1,0x6C66B150,0x00000000 8207 long 0x3FFE0000,0xCB8727C0 8207 long 0x3FFE0000,0xCB8727C0,0x65C393E0,0x00000000 8208 long 0x3FFC0000,0xEAE10B5A 8208 long 0x3FFC0000,0xEAE10B5A,0x7DDC8ADD,0x00000000 8209 long 0x3FFE0000,0xC907DA4E 8209 long 0x3FFE0000,0xC907DA4E,0x871146AD,0x00000000 8210 long 0x3FFC0000,0xF7856E5E 8210 long 0x3FFC0000,0xF7856E5E,0xE2C9B291,0x00000000 8211 long 0x3FFE0000,0xC6980C69 8211 long 0x3FFE0000,0xC6980C69,0x80C6980C,0x00000000 8212 long 0x3FFD0000,0x82012CA5 8212 long 0x3FFD0000,0x82012CA5,0xA68206D7,0x00000000 8213 long 0x3FFE0000,0xC4372F85 8213 long 0x3FFE0000,0xC4372F85,0x5D824CA6,0x00000000 8214 long 0x3FFD0000,0x882C5FCD 8214 long 0x3FFD0000,0x882C5FCD,0x7256A8C5,0x00000000 8215 long 0x3FFE0000,0xC1E4BBD5 8215 long 0x3FFE0000,0xC1E4BBD5,0x95F6E947,0x00000000 8216 long 0x3FFD0000,0x8E44C60B 8216 long 0x3FFD0000,0x8E44C60B,0x4CCFD7DE,0x00000000 8217 long 0x3FFE0000,0xBFA02FE8 8217 long 0x3FFE0000,0xBFA02FE8,0x0BFA02FF,0x00000000 8218 long 0x3FFD0000,0x944AD09E 8218 long 0x3FFD0000,0x944AD09E,0xF4351AF6,0x00000000 8219 long 0x3FFE0000,0xBD691047 8219 long 0x3FFE0000,0xBD691047,0x07661AA3,0x00000000 8220 long 0x3FFD0000,0x9A3EECD4 8220 long 0x3FFD0000,0x9A3EECD4,0xC3EAA6B2,0x00000000 8221 long 0x3FFE0000,0xBB3EE721 8221 long 0x3FFE0000,0xBB3EE721,0xA54D880C,0x00000000 8222 long 0x3FFD0000,0xA0218434 8222 long 0x3FFD0000,0xA0218434,0x353F1DE8,0x00000000 8223 long 0x3FFE0000,0xB92143FA 8223 long 0x3FFE0000,0xB92143FA,0x36F5E02E,0x00000000 8224 long 0x3FFD0000,0xA5F2FCAB 8224 long 0x3FFD0000,0xA5F2FCAB,0xBBC506DA,0x00000000 8225 long 0x3FFE0000,0xB70FBB5A 8225 long 0x3FFE0000,0xB70FBB5A,0x19BE3659,0x00000000 8226 long 0x3FFD0000,0xABB3B8BA 8226 long 0x3FFD0000,0xABB3B8BA,0x2AD362A5,0x00000000 8227 long 0x3FFE0000,0xB509E68A 8227 long 0x3FFE0000,0xB509E68A,0x9B94821F,0x00000000 8228 long 0x3FFD0000,0xB1641795 8228 long 0x3FFD0000,0xB1641795,0xCE3CA97B,0x00000000 8229 long 0x3FFE0000,0xB30F6352 8229 long 0x3FFE0000,0xB30F6352,0x8917C80B,0x00000000 8230 long 0x3FFD0000,0xB7047551 8230 long 0x3FFD0000,0xB7047551,0x5D0F1C61,0x00000000 8231 long 0x3FFE0000,0xB11FD3B8 8231 long 0x3FFE0000,0xB11FD3B8,0x0B11FD3C,0x00000000 8232 long 0x3FFD0000,0xBC952AFE 8232 long 0x3FFD0000,0xBC952AFE,0xEA3D13E1,0x00000000 8233 long 0x3FFE0000,0xAF3ADDC6 8233 long 0x3FFE0000,0xAF3ADDC6,0x80AF3ADE,0x00000000 8234 long 0x3FFD0000,0xC2168ED0 8234 long 0x3FFD0000,0xC2168ED0,0xF458BA4A,0x00000000 8235 long 0x3FFE0000,0xAD602B58 8235 long 0x3FFE0000,0xAD602B58,0x0AD602B6,0x00000000 8236 long 0x3FFD0000,0xC788F439 8236 long 0x3FFD0000,0xC788F439,0xB3163BF1,0x00000000 8237 long 0x3FFE0000,0xAB8F69E2 8237 long 0x3FFE0000,0xAB8F69E2,0x8359CD11,0x00000000 8238 long 0x3FFD0000,0xCCECAC08 8238 long 0x3FFD0000,0xCCECAC08,0xBF04565D,0x00000000 8239 long 0x3FFE0000,0xA9C84A47 8239 long 0x3FFE0000,0xA9C84A47,0xA07F5638,0x00000000 8240 long 0x3FFD0000,0xD2420487 8240 long 0x3FFD0000,0xD2420487,0x2DD85160,0x00000000 8241 long 0x3FFE0000,0xA80A80A8 8241 long 0x3FFE0000,0xA80A80A8,0x0A80A80B,0x00000000 8242 long 0x3FFD0000,0xD7894992 8242 long 0x3FFD0000,0xD7894992,0x3BC3588A,0x00000000 8243 long 0x3FFE0000,0xA655C439 8243 long 0x3FFE0000,0xA655C439,0x2D7B73A8,0x00000000 8244 long 0x3FFD0000,0xDCC2C4B4 8244 long 0x3FFD0000,0xDCC2C4B4,0x9887DACC,0x00000000 8245 long 0x3FFE0000,0xA4A9CF1D 8245 long 0x3FFE0000,0xA4A9CF1D,0x96833751,0x00000000 8246 long 0x3FFD0000,0xE1EEBD3E 8246 long 0x3FFD0000,0xE1EEBD3E,0x6D6A6B9E,0x00000000 8247 long 0x3FFE0000,0xA3065E3F 8247 long 0x3FFE0000,0xA3065E3F,0xAE7CD0E0,0x00000000 8248 long 0x3FFD0000,0xE70D785C 8248 long 0x3FFD0000,0xE70D785C,0x2F9F5BDC,0x00000000 8249 long 0x3FFE0000,0xA16B312E 8249 long 0x3FFE0000,0xA16B312E,0xA8FC377D,0x00000000 8250 long 0x3FFD0000,0xEC1F392C 8250 long 0x3FFD0000,0xEC1F392C,0x5179F283,0x00000000 8251 long 0x3FFE0000,0x9FD809FD 8251 long 0x3FFE0000,0x9FD809FD,0x809FD80A,0x00000000 8252 long 0x3FFD0000,0xF12440D3 8252 long 0x3FFD0000,0xF12440D3,0xE36130E6,0x00000000 8253 long 0x3FFE0000,0x9E4CAD23 8253 long 0x3FFE0000,0x9E4CAD23,0xDD5F3A20,0x00000000 8254 long 0x3FFD0000,0xF61CCE92 8254 long 0x3FFD0000,0xF61CCE92,0x346600BB,0x00000000 8255 long 0x3FFE0000,0x9CC8E160 8255 long 0x3FFE0000,0x9CC8E160,0xC3FB19B9,0x00000000 8256 long 0x3FFD0000,0xFB091FD3 8256 long 0x3FFD0000,0xFB091FD3,0x8145630A,0x00000000 8257 long 0x3FFE0000,0x9B4C6F9E 8257 long 0x3FFE0000,0x9B4C6F9E,0xF03A3CAA,0x00000000 8258 long 0x3FFD0000,0xFFE97042 8258 long 0x3FFD0000,0xFFE97042,0xBFA4C2AD,0x00000000 8259 long 0x3FFE0000,0x99D722DA 8259 long 0x3FFE0000,0x99D722DA,0xBDE58F06,0x00000000 8260 long 0x3FFE0000,0x825EFCED 8260 long 0x3FFE0000,0x825EFCED,0x49369330,0x00000000 8261 long 0x3FFE0000,0x9868C809 8261 long 0x3FFE0000,0x9868C809,0x868C8098,0x00000000 8262 long 0x3FFE0000,0x84C37A7A 8262 long 0x3FFE0000,0x84C37A7A,0xB9A905C9,0x00000000 8263 long 0x3FFE0000,0x97012E02 8263 long 0x3FFE0000,0x97012E02,0x5C04B809,0x00000000 8264 long 0x3FFE0000,0x87224C2E 8264 long 0x3FFE0000,0x87224C2E,0x8E645FB7,0x00000000 8265 long 0x3FFE0000,0x95A02568 8265 long 0x3FFE0000,0x95A02568,0x095A0257,0x00000000 8266 long 0x3FFE0000,0x897B8CAC 8266 long 0x3FFE0000,0x897B8CAC,0x9F7DE298,0x00000000 8267 long 0x3FFE0000,0x94458094 8267 long 0x3FFE0000,0x94458094,0x45809446,0x00000000 8268 long 0x3FFE0000,0x8BCF55DE 8268 long 0x3FFE0000,0x8BCF55DE,0xC4CD05FE,0x00000000 8269 long 0x3FFE0000,0x92F11384 8269 long 0x3FFE0000,0x92F11384,0x0497889C,0x00000000 8270 long 0x3FFE0000,0x8E1DC0FB 8270 long 0x3FFE0000,0x8E1DC0FB,0x89E125E5,0x00000000 8271 long 0x3FFE0000,0x91A2B3C4 8271 long 0x3FFE0000,0x91A2B3C4,0xD5E6F809,0x00000000 8272 long 0x3FFE0000,0x9066E68C 8272 long 0x3FFE0000,0x9066E68C,0x955B6C9B,0x00000000 8273 long 0x3FFE0000,0x905A3863 8273 long 0x3FFE0000,0x905A3863,0x3E06C43B,0x00000000 8274 long 0x3FFE0000,0x92AADE74 8274 long 0x3FFE0000,0x92AADE74,0xC7BE59E0,0x00000000 8275 long 0x3FFE0000,0x8F1779D9 8275 long 0x3FFE0000,0x8F1779D9,0xFDC3A219,0x00000000 8276 long 0x3FFE0000,0x94E9BFF6 8276 long 0x3FFE0000,0x94E9BFF6,0x15845643,0x00000000 8277 long 0x3FFE0000,0x8DDA5202 8277 long 0x3FFE0000,0x8DDA5202,0x37694809,0x00000000 8278 long 0x3FFE0000,0x9723A1B7 8278 long 0x3FFE0000,0x9723A1B7,0x20134203,0x00000000 8279 long 0x3FFE0000,0x8CA29C04 8279 long 0x3FFE0000,0x8CA29C04,0x6514E023,0x00000000 8280 long 0x3FFE0000,0x995899C8 8280 long 0x3FFE0000,0x995899C8,0x90EB8990,0x00000000 8281 long 0x3FFE0000,0x8B70344A 8281 long 0x3FFE0000,0x8B70344A,0x139BC75A,0x00000000 8282 long 0x3FFE0000,0x9B88BDAA 8282 long 0x3FFE0000,0x9B88BDAA,0x3A3DAE2F,0x00000000 8283 long 0x3FFE0000,0x8A42F870 8283 long 0x3FFE0000,0x8A42F870,0x5669DB46,0x00000000 8284 long 0x3FFE0000,0x9DB4224F 8284 long 0x3FFE0000,0x9DB4224F,0xFFE1157C,0x00000000 8285 long 0x3FFE0000,0x891AC73A 8285 long 0x3FFE0000,0x891AC73A,0xE9819B50,0x00000000 8286 long 0x3FFE0000,0x9FDADC26 8286 long 0x3FFE0000,0x9FDADC26,0x8B7A12DA,0x00000000 8287 long 0x3FFE0000,0x87F78087 8287 long 0x3FFE0000,0x87F78087,0xF78087F8,0x00000000 8288 long 0x3FFE0000,0xA1FCFF17 8288 long 0x3FFE0000,0xA1FCFF17,0xCE733BD4,0x00000000 8289 long 0x3FFE0000,0x86D90544 8289 long 0x3FFE0000,0x86D90544,0x7A34ACC6,0x00000000 8290 long 0x3FFE0000,0xA41A9E8F 8290 long 0x3FFE0000,0xA41A9E8F,0x5446FB9F,0x00000000 8291 long 0x3FFE0000,0x85BF3761 8291 long 0x3FFE0000,0x85BF3761,0x2CEE3C9B,0x00000000 8292 long 0x3FFE0000,0xA633CD7E 8292 long 0x3FFE0000,0xA633CD7E,0x6771CD8B,0x00000000 8293 long 0x3FFE0000,0x84A9F9C8 8293 long 0x3FFE0000,0x84A9F9C8,0x084A9F9D,0x00000000 8294 long 0x3FFE0000,0xA8489E60 8294 long 0x3FFE0000,0xA8489E60,0x0B435A5E,0x00000000 8295 long 0x3FFE0000,0x83993052 8295 long 0x3FFE0000,0x83993052,0x3FBE3368,0x00000000 8296 long 0x3FFE0000,0xAA59233C 8296 long 0x3FFE0000,0xAA59233C,0xCCA4BD49,0x00000000 8297 long 0x3FFE0000,0x828CBFBE 8297 long 0x3FFE0000,0x828CBFBE,0xB9A020A3,0x00000000 8298 long 0x3FFE0000,0xAC656DAE 8298 long 0x3FFE0000,0xAC656DAE,0x6BCC4985,0x00000000 8299 long 0x3FFE0000,0x81848DA8 8299 long 0x3FFE0000,0x81848DA8,0xFAF0D277,0x00000000 8300 long 0x3FFE0000,0xAE6D8EE3 8300 long 0x3FFE0000,0xAE6D8EE3,0x60BB2468,0x00000000 8301 long 0x3FFE0000,0x80808080 8301 long 0x3FFE0000,0x80808080,0x80808081,0x00000000 8302 long 0x3FFE0000,0xB07197A2 8302 long 0x3FFE0000,0xB07197A2,0x3C46C654,0x00000000 8303 8303 8304 set ADJK,L_SCR1 8304 set ADJK,L_SCR1 8305 8305 8306 set X,FP_SCR0 8306 set X,FP_SCR0 8307 set XDCARE,X+2 8307 set XDCARE,X+2 8308 set XFRAC,X+4 8308 set XFRAC,X+4 8309 8309 8310 set F,FP_SCR1 8310 set F,FP_SCR1 8311 set FFRAC,F+4 8311 set FFRAC,F+4 8312 8312 8313 set KLOG2,FP_SCR0 8313 set KLOG2,FP_SCR0 8314 8314 8315 set SAVEU,FP_SCR0 8315 set SAVEU,FP_SCR0 8316 8316 8317 global slogn 8317 global slogn 8318 #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-Z 8318 #--ENTRY POINT FOR LOG(X) FOR X FINITE, NON-ZERO, NOT NAN'S 8319 slogn: 8319 slogn: 8320 fmov.x (%a0),%fp0 8320 fmov.x (%a0),%fp0 # LOAD INPUT 8321 mov.l &0x00000000,ADJK(%a6) 8321 mov.l &0x00000000,ADJK(%a6) 8322 8322 8323 LOGBGN: 8323 LOGBGN: 8324 #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)* 8324 #--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS 8325 #--A FINITE, NON-ZERO, NORMALIZED NUMBER. 8325 #--A FINITE, NON-ZERO, NORMALIZED NUMBER. 8326 8326 8327 mov.l (%a0),%d1 8327 mov.l (%a0),%d1 8328 mov.w 4(%a0),%d1 8328 mov.w 4(%a0),%d1 8329 8329 8330 mov.l (%a0),X(%a6) 8330 mov.l (%a0),X(%a6) 8331 mov.l 4(%a0),X+4(%a6) 8331 mov.l 4(%a0),X+4(%a6) 8332 mov.l 8(%a0),X+8(%a6) 8332 mov.l 8(%a0),X+8(%a6) 8333 8333 8334 cmp.l %d1,&0 8334 cmp.l %d1,&0 # CHECK IF X IS NEGATIVE 8335 blt.w LOGNEG 8335 blt.w LOGNEG # LOG OF NEGATIVE ARGUMENT IS INVALID 8336 # X IS POSITIVE, CHECK IF X IS NEAR 1 8336 # X IS POSITIVE, CHECK IF X IS NEAR 1 8337 cmp.l %d1,&0x3ffef07d 8337 cmp.l %d1,&0x3ffef07d # IS X < 15/16? 8338 blt.b LOGMAIN 8338 blt.b LOGMAIN # YES 8339 cmp.l %d1,&0x3fff8841 8339 cmp.l %d1,&0x3fff8841 # IS X > 17/16? 8340 ble.w LOGNEAR1 8340 ble.w LOGNEAR1 # NO 8341 8341 8342 LOGMAIN: 8342 LOGMAIN: 8343 #--THIS SHOULD BE THE USUAL CASE, X NOT VERY 8343 #--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1 8344 8344 8345 #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXX 8345 #--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY. 8346 #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS 8346 #--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1. 8347 #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y) 8347 #--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y) 8348 #-- = K*LOG2 + LOG(F) + 8348 #-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F). 8349 #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND TH 8349 #--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING 8350 #--LOG(1+U) CAN BE VERY EFFICIENT. 8350 #--LOG(1+U) CAN BE VERY EFFICIENT. 8351 #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN 8351 #--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO 8352 #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F. 8352 #--DIVISION IS NEEDED TO CALCULATE (Y-F)/F. 8353 8353 8354 #--GET K, Y, F, AND ADDRESS OF 1/F. 8354 #--GET K, Y, F, AND ADDRESS OF 1/F. 8355 asr.l &8,%d1 8355 asr.l &8,%d1 8356 asr.l &8,%d1 8356 asr.l &8,%d1 # SHIFTED 16 BITS, BIASED EXPO. OF X 8357 sub.l &0x3FFF,%d1 8357 sub.l &0x3FFF,%d1 # THIS IS K 8358 add.l ADJK(%a6),%d1 8358 add.l ADJK(%a6),%d1 # ADJUST K, ORIGINAL INPUT MAY BE DENORM. 8359 lea LOGTBL(%pc),%a0 8359 lea LOGTBL(%pc),%a0 # BASE ADDRESS OF 1/F AND LOG(F) 8360 fmov.l %d1,%fp1 8360 fmov.l %d1,%fp1 # CONVERT K TO FLOATING-POINT FORMAT 8361 8361 8362 #--WHILE THE CONVERSION IS GOING ON, WE GET F 8362 #--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F 8363 mov.l &0x3FFF0000,X(%a6) 8363 mov.l &0x3FFF0000,X(%a6) # X IS NOW Y, I.E. 2^(-K)*X 8364 mov.l XFRAC(%a6),FFRAC(%a6) 8364 mov.l XFRAC(%a6),FFRAC(%a6) 8365 and.l &0xFE000000,FFRAC(%a6 8365 and.l &0xFE000000,FFRAC(%a6) # FIRST 7 BITS OF Y 8366 or.l &0x01000000,FFRAC(%a6 8366 or.l &0x01000000,FFRAC(%a6) # GET F: ATTACH A 1 AT THE EIGHTH BIT 8367 mov.l FFRAC(%a6),%d1 # REA 8367 mov.l FFRAC(%a6),%d1 # READY TO GET ADDRESS OF 1/F 8368 and.l &0x7E000000,%d1 8368 and.l &0x7E000000,%d1 8369 asr.l &8,%d1 8369 asr.l &8,%d1 8370 asr.l &8,%d1 8370 asr.l &8,%d1 8371 asr.l &4,%d1 8371 asr.l &4,%d1 # SHIFTED 20, D0 IS THE DISPLACEMENT 8372 add.l %d1,%a0 8372 add.l %d1,%a0 # A0 IS THE ADDRESS FOR 1/F 8373 8373 8374 fmov.x X(%a6),%fp0 8374 fmov.x X(%a6),%fp0 8375 mov.l &0x3fff0000,F(%a6) 8375 mov.l &0x3fff0000,F(%a6) 8376 clr.l F+8(%a6) 8376 clr.l F+8(%a6) 8377 fsub.x F(%a6),%fp0 8377 fsub.x F(%a6),%fp0 # Y-F 8378 fmovm.x &0xc,-(%sp) 8378 fmovm.x &0xc,-(%sp) # SAVE FP2-3 WHILE FP0 IS NOT READY 8379 #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, 8379 #--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K 8380 #--REGISTERS SAVED: FPCR, FP1, FP2 8380 #--REGISTERS SAVED: FPCR, FP1, FP2 8381 8381 8382 LP1CONT1: 8382 LP1CONT1: 8383 #--AN RE-ENTRY POINT FOR LOGNP1 8383 #--AN RE-ENTRY POINT FOR LOGNP1 8384 fmul.x (%a0),%fp0 8384 fmul.x (%a0),%fp0 # FP0 IS U = (Y-F)/F 8385 fmul.x LOGOF2(%pc),%fp1 8385 fmul.x LOGOF2(%pc),%fp1 # GET K*LOG2 WHILE FP0 IS NOT READY 8386 fmov.x %fp0,%fp2 8386 fmov.x %fp0,%fp2 8387 fmul.x %fp2,%fp2 8387 fmul.x %fp2,%fp2 # FP2 IS V=U*U 8388 fmov.x %fp1,KLOG2(%a6) 8388 fmov.x %fp1,KLOG2(%a6) # PUT K*LOG2 IN MEMEORY, FREE FP1 8389 8389 8390 #--LOG(1+U) IS APPROXIMATED BY 8390 #--LOG(1+U) IS APPROXIMATED BY 8391 #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6)))) 8391 #--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS 8392 #--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A 8392 #--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))] 8393 8393 8394 fmov.x %fp2,%fp3 8394 fmov.x %fp2,%fp3 8395 fmov.x %fp2,%fp1 8395 fmov.x %fp2,%fp1 8396 8396 8397 fmul.d LOGA6(%pc),%fp1 8397 fmul.d LOGA6(%pc),%fp1 # V*A6 8398 fmul.d LOGA5(%pc),%fp2 8398 fmul.d LOGA5(%pc),%fp2 # V*A5 8399 8399 8400 fadd.d LOGA4(%pc),%fp1 8400 fadd.d LOGA4(%pc),%fp1 # A4+V*A6 8401 fadd.d LOGA3(%pc),%fp2 8401 fadd.d LOGA3(%pc),%fp2 # A3+V*A5 8402 8402 8403 fmul.x %fp3,%fp1 8403 fmul.x %fp3,%fp1 # V*(A4+V*A6) 8404 fmul.x %fp3,%fp2 8404 fmul.x %fp3,%fp2 # V*(A3+V*A5) 8405 8405 8406 fadd.d LOGA2(%pc),%fp1 8406 fadd.d LOGA2(%pc),%fp1 # A2+V*(A4+V*A6) 8407 fadd.d LOGA1(%pc),%fp2 8407 fadd.d LOGA1(%pc),%fp2 # A1+V*(A3+V*A5) 8408 8408 8409 fmul.x %fp3,%fp1 8409 fmul.x %fp3,%fp1 # V*(A2+V*(A4+V*A6)) 8410 add.l &16,%a0 8410 add.l &16,%a0 # ADDRESS OF LOG(F) 8411 fmul.x %fp3,%fp2 8411 fmul.x %fp3,%fp2 # V*(A1+V*(A3+V*A5)) 8412 8412 8413 fmul.x %fp0,%fp1 8413 fmul.x %fp0,%fp1 # U*V*(A2+V*(A4+V*A6)) 8414 fadd.x %fp2,%fp0 8414 fadd.x %fp2,%fp0 # U+V*(A1+V*(A3+V*A5)) 8415 8415 8416 fadd.x (%a0),%fp1 8416 fadd.x (%a0),%fp1 # LOG(F)+U*V*(A2+V*(A4+V*A6)) 8417 fmovm.x (%sp)+,&0x30 8417 fmovm.x (%sp)+,&0x30 # RESTORE FP2-3 8418 fadd.x %fp1,%fp0 8418 fadd.x %fp1,%fp0 # FP0 IS LOG(F) + LOG(1+U) 8419 8419 8420 fmov.l %d0,%fpcr 8420 fmov.l %d0,%fpcr 8421 fadd.x KLOG2(%a6),%fp0 8421 fadd.x KLOG2(%a6),%fp0 # FINAL ADD 8422 bra t_inx2 8422 bra t_inx2 8423 8423 8424 8424 8425 LOGNEAR1: 8425 LOGNEAR1: 8426 8426 8427 # if the input is exactly equal to one, then 8427 # if the input is exactly equal to one, then exit through ld_pzero. 8428 # if these 2 lines weren't here, the correct 8428 # if these 2 lines weren't here, the correct answer would be returned 8429 # but the INEX2 bit would be set. 8429 # but the INEX2 bit would be set. 8430 fcmp.b %fp0,&0x1 8430 fcmp.b %fp0,&0x1 # is it equal to one? 8431 fbeq.l ld_pzero 8431 fbeq.l ld_pzero # yes 8432 8432 8433 #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS T 8433 #--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT. 8434 fmov.x %fp0,%fp1 8434 fmov.x %fp0,%fp1 8435 fsub.s one(%pc),%fp1 8435 fsub.s one(%pc),%fp1 # FP1 IS X-1 8436 fadd.s one(%pc),%fp0 8436 fadd.s one(%pc),%fp0 # FP0 IS X+1 8437 fadd.x %fp1,%fp1 8437 fadd.x %fp1,%fp1 # FP1 IS 2(X-1) 8438 #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN 8438 #--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL 8439 #--IN U, U = 2(X-1)/(X+1) = FP1/FP0 8439 #--IN U, U = 2(X-1)/(X+1) = FP1/FP0 8440 8440 8441 LP1CONT2: 8441 LP1CONT2: 8442 #--THIS IS AN RE-ENTRY POINT FOR LOGNP1 8442 #--THIS IS AN RE-ENTRY POINT FOR LOGNP1 8443 fdiv.x %fp0,%fp1 8443 fdiv.x %fp0,%fp1 # FP1 IS U 8444 fmovm.x &0xc,-(%sp) 8444 fmovm.x &0xc,-(%sp) # SAVE FP2-3 8445 #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3 8445 #--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3 8446 #--LET V=U*U, W=V*V, CALCULATE 8446 #--LET V=U*U, W=V*V, CALCULATE 8447 #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5 8447 #--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY 8448 #--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 8448 #--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] ) 8449 fmov.x %fp1,%fp0 8449 fmov.x %fp1,%fp0 8450 fmul.x %fp0,%fp0 8450 fmul.x %fp0,%fp0 # FP0 IS V 8451 fmov.x %fp1,SAVEU(%a6) 8451 fmov.x %fp1,SAVEU(%a6) # STORE U IN MEMORY, FREE FP1 8452 fmov.x %fp0,%fp1 8452 fmov.x %fp0,%fp1 8453 fmul.x %fp1,%fp1 8453 fmul.x %fp1,%fp1 # FP1 IS W 8454 8454 8455 fmov.d LOGB5(%pc),%fp3 8455 fmov.d LOGB5(%pc),%fp3 8456 fmov.d LOGB4(%pc),%fp2 8456 fmov.d LOGB4(%pc),%fp2 8457 8457 8458 fmul.x %fp1,%fp3 8458 fmul.x %fp1,%fp3 # W*B5 8459 fmul.x %fp1,%fp2 8459 fmul.x %fp1,%fp2 # W*B4 8460 8460 8461 fadd.d LOGB3(%pc),%fp3 8461 fadd.d LOGB3(%pc),%fp3 # B3+W*B5 8462 fadd.d LOGB2(%pc),%fp2 8462 fadd.d LOGB2(%pc),%fp2 # B2+W*B4 8463 8463 8464 fmul.x %fp3,%fp1 8464 fmul.x %fp3,%fp1 # W*(B3+W*B5), FP3 RELEASED 8465 8465 8466 fmul.x %fp0,%fp2 8466 fmul.x %fp0,%fp2 # V*(B2+W*B4) 8467 8467 8468 fadd.d LOGB1(%pc),%fp1 8468 fadd.d LOGB1(%pc),%fp1 # B1+W*(B3+W*B5) 8469 fmul.x SAVEU(%a6),%fp0 8469 fmul.x SAVEU(%a6),%fp0 # FP0 IS U*V 8470 8470 8471 fadd.x %fp2,%fp1 8471 fadd.x %fp2,%fp1 # B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED 8472 fmovm.x (%sp)+,&0x30 8472 fmovm.x (%sp)+,&0x30 # FP2-3 RESTORED 8473 8473 8474 fmul.x %fp1,%fp0 8474 fmul.x %fp1,%fp0 # U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] ) 8475 8475 8476 fmov.l %d0,%fpcr 8476 fmov.l %d0,%fpcr 8477 fadd.x SAVEU(%a6),%fp0 8477 fadd.x SAVEU(%a6),%fp0 8478 bra t_inx2 8478 bra t_inx2 8479 8479 8480 #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID 8480 #--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID 8481 LOGNEG: 8481 LOGNEG: 8482 bra t_operr 8482 bra t_operr 8483 8483 8484 global slognd 8484 global slognd 8485 slognd: 8485 slognd: 8486 #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED IN 8486 #--ENTRY POINT FOR LOG(X) FOR DENORMALIZED INPUT 8487 8487 8488 mov.l &-100,ADJK(%a6) 8488 mov.l &-100,ADJK(%a6) # INPUT = 2^(ADJK) * FP0 8489 8489 8490 #----normalize the input value by left shifti 8490 #----normalize the input value by left shifting k bits (k to be determined 8491 #----below), adjusting exponent and storing - 8491 #----below), adjusting exponent and storing -k to ADJK 8492 #----the value TWOTO100 is no longer needed. 8492 #----the value TWOTO100 is no longer needed. 8493 #----Note that this code assumes the denormal 8493 #----Note that this code assumes the denormalized input is NON-ZERO. 8494 8494 8495 movm.l &0x3f00,-(%sp) 8495 movm.l &0x3f00,-(%sp) # save some registers {d2-d7} 8496 mov.l (%a0),%d3 8496 mov.l (%a0),%d3 # D3 is exponent of smallest norm. # 8497 mov.l 4(%a0),%d4 8497 mov.l 4(%a0),%d4 8498 mov.l 8(%a0),%d5 8498 mov.l 8(%a0),%d5 # (D4,D5) is (Hi_X,Lo_X) 8499 clr.l %d2 8499 clr.l %d2 # D2 used for holding K 8500 8500 8501 tst.l %d4 8501 tst.l %d4 8502 bne.b Hi_not0 8502 bne.b Hi_not0 8503 8503 8504 Hi_0: 8504 Hi_0: 8505 mov.l %d5,%d4 8505 mov.l %d5,%d4 8506 clr.l %d5 8506 clr.l %d5 8507 mov.l &32,%d2 8507 mov.l &32,%d2 8508 clr.l %d6 8508 clr.l %d6 8509 bfffo %d4{&0:&32},%d6 8509 bfffo %d4{&0:&32},%d6 8510 lsl.l %d6,%d4 8510 lsl.l %d6,%d4 8511 add.l %d6,%d2 8511 add.l %d6,%d2 # (D3,D4,D5) is normalized 8512 8512 8513 mov.l %d3,X(%a6) 8513 mov.l %d3,X(%a6) 8514 mov.l %d4,XFRAC(%a6) 8514 mov.l %d4,XFRAC(%a6) 8515 mov.l %d5,XFRAC+4(%a6) 8515 mov.l %d5,XFRAC+4(%a6) 8516 neg.l %d2 8516 neg.l %d2 8517 mov.l %d2,ADJK(%a6) 8517 mov.l %d2,ADJK(%a6) 8518 fmov.x X(%a6),%fp0 8518 fmov.x X(%a6),%fp0 8519 movm.l (%sp)+,&0xfc 8519 movm.l (%sp)+,&0xfc # restore registers {d2-d7} 8520 lea X(%a6),%a0 8520 lea X(%a6),%a0 8521 bra.w LOGBGN 8521 bra.w LOGBGN # begin regular log(X) 8522 8522 8523 Hi_not0: 8523 Hi_not0: 8524 clr.l %d6 8524 clr.l %d6 8525 bfffo %d4{&0:&32},%d6 8525 bfffo %d4{&0:&32},%d6 # find first 1 8526 mov.l %d6,%d2 8526 mov.l %d6,%d2 # get k 8527 lsl.l %d6,%d4 8527 lsl.l %d6,%d4 8528 mov.l %d5,%d7 8528 mov.l %d5,%d7 # a copy of D5 8529 lsl.l %d6,%d5 8529 lsl.l %d6,%d5 8530 neg.l %d6 8530 neg.l %d6 8531 add.l &32,%d6 8531 add.l &32,%d6 8532 lsr.l %d6,%d7 8532 lsr.l %d6,%d7 8533 or.l %d7,%d4 8533 or.l %d7,%d4 # (D3,D4,D5) normalized 8534 8534 8535 mov.l %d3,X(%a6) 8535 mov.l %d3,X(%a6) 8536 mov.l %d4,XFRAC(%a6) 8536 mov.l %d4,XFRAC(%a6) 8537 mov.l %d5,XFRAC+4(%a6) 8537 mov.l %d5,XFRAC+4(%a6) 8538 neg.l %d2 8538 neg.l %d2 8539 mov.l %d2,ADJK(%a6) 8539 mov.l %d2,ADJK(%a6) 8540 fmov.x X(%a6),%fp0 8540 fmov.x X(%a6),%fp0 8541 movm.l (%sp)+,&0xfc 8541 movm.l (%sp)+,&0xfc # restore registers {d2-d7} 8542 lea X(%a6),%a0 8542 lea X(%a6),%a0 8543 bra.w LOGBGN 8543 bra.w LOGBGN # begin regular log(X) 8544 8544 8545 global slognp1 8545 global slognp1 8546 #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON 8546 #--ENTRY POINT FOR LOG(1+X) FOR X FINITE, NON-ZERO, NOT NAN'S 8547 slognp1: 8547 slognp1: 8548 fmov.x (%a0),%fp0 8548 fmov.x (%a0),%fp0 # LOAD INPUT 8549 fabs.x %fp0 8549 fabs.x %fp0 # test magnitude 8550 fcmp.x %fp0,LTHOLD(%pc) 8550 fcmp.x %fp0,LTHOLD(%pc) # compare with min threshold 8551 fbgt.w LP1REAL 8551 fbgt.w LP1REAL # if greater, continue 8552 fmov.l %d0,%fpcr 8552 fmov.l %d0,%fpcr 8553 mov.b &FMOV_OP,%d1 8553 mov.b &FMOV_OP,%d1 # last inst is MOVE 8554 fmov.x (%a0),%fp0 8554 fmov.x (%a0),%fp0 # return signed argument 8555 bra t_catch 8555 bra t_catch 8556 8556 8557 LP1REAL: 8557 LP1REAL: 8558 fmov.x (%a0),%fp0 8558 fmov.x (%a0),%fp0 # LOAD INPUT 8559 mov.l &0x00000000,ADJK(%a6) 8559 mov.l &0x00000000,ADJK(%a6) 8560 fmov.x %fp0,%fp1 8560 fmov.x %fp0,%fp1 # FP1 IS INPUT Z 8561 fadd.s one(%pc),%fp0 8561 fadd.s one(%pc),%fp0 # X := ROUND(1+Z) 8562 fmov.x %fp0,X(%a6) 8562 fmov.x %fp0,X(%a6) 8563 mov.w XFRAC(%a6),XDCARE(%a6 8563 mov.w XFRAC(%a6),XDCARE(%a6) 8564 mov.l X(%a6),%d1 8564 mov.l X(%a6),%d1 8565 cmp.l %d1,&0 8565 cmp.l %d1,&0 8566 ble.w LP1NEG0 8566 ble.w LP1NEG0 # LOG OF ZERO OR -VE 8567 cmp.l %d1,&0x3ffe8000 8567 cmp.l %d1,&0x3ffe8000 # IS BOUNDS [1/2,3/2]? 8568 blt.w LOGMAIN 8568 blt.w LOGMAIN 8569 cmp.l %d1,&0x3fffc000 8569 cmp.l %d1,&0x3fffc000 8570 bgt.w LOGMAIN 8570 bgt.w LOGMAIN 8571 #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH I 8571 #--IF 1+Z > 3/2 OR 1+Z < 1/2, THEN X, WHICH IS ROUNDING 1+Z, 8572 #--CONTAINS AT LEAST 63 BITS OF INFORMATION O 8572 #--CONTAINS AT LEAST 63 BITS OF INFORMATION OF Z. IN THAT CASE, 8573 #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z). 8573 #--SIMPLY INVOKE LOG(X) FOR LOG(1+Z). 8574 8574 8575 LP1NEAR1: 8575 LP1NEAR1: 8576 #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16) 8576 #--NEXT SEE IF EXP(-1/16) < X < EXP(1/16) 8577 cmp.l %d1,&0x3ffef07d 8577 cmp.l %d1,&0x3ffef07d 8578 blt.w LP1CARE 8578 blt.w LP1CARE 8579 cmp.l %d1,&0x3fff8841 8579 cmp.l %d1,&0x3fff8841 8580 bgt.w LP1CARE 8580 bgt.w LP1CARE 8581 8581 8582 LP1ONE16: 8582 LP1ONE16: 8583 #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG 8583 #--EXP(-1/16) < X < EXP(1/16). LOG(1+Z) = LOG(1+U/2) - LOG(1-U/2) 8584 #--WHERE U = 2Z/(2+Z) = 2Z/(1+X). 8584 #--WHERE U = 2Z/(2+Z) = 2Z/(1+X). 8585 fadd.x %fp1,%fp1 8585 fadd.x %fp1,%fp1 # FP1 IS 2Z 8586 fadd.s one(%pc),%fp0 8586 fadd.s one(%pc),%fp0 # FP0 IS 1+X 8587 #--U = FP1/FP0 8587 #--U = FP1/FP0 8588 bra.w LP1CONT2 8588 bra.w LP1CONT2 8589 8589 8590 LP1CARE: 8590 LP1CARE: 8591 #--HERE WE USE THE USUAL TABLE DRIVEN APPROAC 8591 #--HERE WE USE THE USUAL TABLE DRIVEN APPROACH. CARE HAS TO BE 8592 #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFO 8592 #--TAKEN BECAUSE 1+Z CAN HAVE 67 BITS OF INFORMATION AND WE MUST 8593 #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z 8593 #--PRESERVE ALL THE INFORMATION. BECAUSE 1+Z IS IN [1/2,3/2], 8594 #--THERE ARE ONLY TWO CASES. 8594 #--THERE ARE ONLY TWO CASES. 8595 #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2- 8595 #--CASE 1: 1+Z < 1, THEN K = -1 AND Y-F = (2-F) + 2Z 8596 #--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1- 8596 #--CASE 2: 1+Z > 1, THEN K = 0 AND Y-F = (1-F) + Z 8597 #--ON RETURNING TO LP1CONT1, WE MUST HAVE K I 8597 #--ON RETURNING TO LP1CONT1, WE MUST HAVE K IN FP1, ADDRESS OF 8598 #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED. 8598 #--(1/F) IN A0, Y-F IN FP0, AND FP2 SAVED. 8599 8599 8600 mov.l XFRAC(%a6),FFRAC(%a6) 8600 mov.l XFRAC(%a6),FFRAC(%a6) 8601 and.l &0xFE000000,FFRAC(%a6 8601 and.l &0xFE000000,FFRAC(%a6) 8602 or.l &0x01000000,FFRAC(%a6 8602 or.l &0x01000000,FFRAC(%a6) # F OBTAINED 8603 cmp.l %d1,&0x3FFF8000 8603 cmp.l %d1,&0x3FFF8000 # SEE IF 1+Z > 1 8604 bge.b KISZERO 8604 bge.b KISZERO 8605 8605 8606 KISNEG1: 8606 KISNEG1: 8607 fmov.s TWO(%pc),%fp0 8607 fmov.s TWO(%pc),%fp0 8608 mov.l &0x3fff0000,F(%a6) 8608 mov.l &0x3fff0000,F(%a6) 8609 clr.l F+8(%a6) 8609 clr.l F+8(%a6) 8610 fsub.x F(%a6),%fp0 8610 fsub.x F(%a6),%fp0 # 2-F 8611 mov.l FFRAC(%a6),%d1 8611 mov.l FFRAC(%a6),%d1 8612 and.l &0x7E000000,%d1 8612 and.l &0x7E000000,%d1 8613 asr.l &8,%d1 8613 asr.l &8,%d1 8614 asr.l &8,%d1 8614 asr.l &8,%d1 8615 asr.l &4,%d1 8615 asr.l &4,%d1 # D0 CONTAINS DISPLACEMENT FOR 1/F 8616 fadd.x %fp1,%fp1 8616 fadd.x %fp1,%fp1 # GET 2Z 8617 fmovm.x &0xc,-(%sp) 8617 fmovm.x &0xc,-(%sp) # SAVE FP2 {%fp2/%fp3} 8618 fadd.x %fp1,%fp0 8618 fadd.x %fp1,%fp0 # FP0 IS Y-F = (2-F)+2Z 8619 lea LOGTBL(%pc),%a0 8619 lea LOGTBL(%pc),%a0 # A0 IS ADDRESS OF 1/F 8620 add.l %d1,%a0 8620 add.l %d1,%a0 8621 fmov.s negone(%pc),%fp1 8621 fmov.s negone(%pc),%fp1 # FP1 IS K = -1 8622 bra.w LP1CONT1 8622 bra.w LP1CONT1 8623 8623 8624 KISZERO: 8624 KISZERO: 8625 fmov.s one(%pc),%fp0 8625 fmov.s one(%pc),%fp0 8626 mov.l &0x3fff0000,F(%a6) 8626 mov.l &0x3fff0000,F(%a6) 8627 clr.l F+8(%a6) 8627 clr.l F+8(%a6) 8628 fsub.x F(%a6),%fp0 8628 fsub.x F(%a6),%fp0 # 1-F 8629 mov.l FFRAC(%a6),%d1 8629 mov.l FFRAC(%a6),%d1 8630 and.l &0x7E000000,%d1 8630 and.l &0x7E000000,%d1 8631 asr.l &8,%d1 8631 asr.l &8,%d1 8632 asr.l &8,%d1 8632 asr.l &8,%d1 8633 asr.l &4,%d1 8633 asr.l &4,%d1 8634 fadd.x %fp1,%fp0 8634 fadd.x %fp1,%fp0 # FP0 IS Y-F 8635 fmovm.x &0xc,-(%sp) 8635 fmovm.x &0xc,-(%sp) # FP2 SAVED {%fp2/%fp3} 8636 lea LOGTBL(%pc),%a0 8636 lea LOGTBL(%pc),%a0 8637 add.l %d1,%a0 8637 add.l %d1,%a0 # A0 IS ADDRESS OF 1/F 8638 fmov.s zero(%pc),%fp1 8638 fmov.s zero(%pc),%fp1 # FP1 IS K = 0 8639 bra.w LP1CONT1 8639 bra.w LP1CONT1 8640 8640 8641 LP1NEG0: 8641 LP1NEG0: 8642 #--FPCR SAVED. D0 IS X IN COMPACT FORM. 8642 #--FPCR SAVED. D0 IS X IN COMPACT FORM. 8643 cmp.l %d1,&0 8643 cmp.l %d1,&0 8644 blt.b LP1NEG 8644 blt.b LP1NEG 8645 LP1ZERO: 8645 LP1ZERO: 8646 fmov.s negone(%pc),%fp0 8646 fmov.s negone(%pc),%fp0 8647 8647 8648 fmov.l %d0,%fpcr 8648 fmov.l %d0,%fpcr 8649 bra t_dz 8649 bra t_dz 8650 8650 8651 LP1NEG: 8651 LP1NEG: 8652 fmov.s zero(%pc),%fp0 8652 fmov.s zero(%pc),%fp0 8653 8653 8654 fmov.l %d0,%fpcr 8654 fmov.l %d0,%fpcr 8655 bra t_operr 8655 bra t_operr 8656 8656 8657 global slognp1d 8657 global slognp1d 8658 #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED 8658 #--ENTRY POINT FOR LOG(1+Z) FOR DENORMALIZED INPUT 8659 # Simply return the denorm 8659 # Simply return the denorm 8660 slognp1d: 8660 slognp1d: 8661 bra t_extdnrm 8661 bra t_extdnrm 8662 8662 8663 ############################################# 8663 ######################################################################### 8664 # satanh(): computes the inverse hyperbolic 8664 # satanh(): computes the inverse hyperbolic tangent of a norm input # 8665 # satanhd(): computes the inverse hyperbolic 8665 # satanhd(): computes the inverse hyperbolic tangent of a denorm input # 8666 # 8666 # # 8667 # INPUT ************************************* 8667 # INPUT *************************************************************** # 8668 # a0 = pointer to extended precision in 8668 # a0 = pointer to extended precision input # 8669 # d0 = round precision,mode 8669 # d0 = round precision,mode # 8670 # 8670 # # 8671 # OUTPUT ************************************ 8671 # OUTPUT ************************************************************** # 8672 # fp0 = arctanh(X) 8672 # fp0 = arctanh(X) # 8673 # 8673 # # 8674 # ACCURACY and MONOTONICITY ***************** 8674 # ACCURACY and MONOTONICITY ******************************************* # 8675 # The returned result is within 3 ulps 8675 # The returned result is within 3 ulps in 64 significant bit, # 8676 # i.e. within 0.5001 ulp to 53 bits if 8676 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 8677 # rounded to double precision. The resu 8677 # rounded to double precision. The result is provably monotonic # 8678 # in double precision. 8678 # in double precision. # 8679 # 8679 # # 8680 # ALGORITHM ********************************* 8680 # ALGORITHM *********************************************************** # 8681 # 8681 # # 8682 # ATANH 8682 # ATANH # 8683 # 1. If |X| >= 1, go to 3. 8683 # 1. If |X| >= 1, go to 3. # 8684 # 8684 # # 8685 # 2. (|X| < 1) Calculate atanh(X) by 8685 # 2. (|X| < 1) Calculate atanh(X) by # 8686 # sgn := sign(X) 8686 # sgn := sign(X) # 8687 # y := |X| 8687 # y := |X| # 8688 # z := 2y/(1-y) 8688 # z := 2y/(1-y) # 8689 # atanh(X) := sgn * (1/2) * log 8689 # atanh(X) := sgn * (1/2) * logp1(z) # 8690 # Exit. 8690 # Exit. # 8691 # 8691 # # 8692 # 3. If |X| > 1, go to 5. 8692 # 3. If |X| > 1, go to 5. # 8693 # 8693 # # 8694 # 4. (|X| = 1) Generate infinity with a 8694 # 4. (|X| = 1) Generate infinity with an appropriate sign and # 8695 # divide-by-zero by 8695 # divide-by-zero by # 8696 # sgn := sign(X) 8696 # sgn := sign(X) # 8697 # atan(X) := sgn / (+0). 8697 # atan(X) := sgn / (+0). # 8698 # Exit. 8698 # Exit. # 8699 # 8699 # # 8700 # 5. (|X| > 1) Generate an invalid oper 8700 # 5. (|X| > 1) Generate an invalid operation by 0 * infinity. # 8701 # Exit. 8701 # Exit. # 8702 # 8702 # # 8703 ############################################# 8703 ######################################################################### 8704 8704 8705 global satanh 8705 global satanh 8706 satanh: 8706 satanh: 8707 mov.l (%a0),%d1 8707 mov.l (%a0),%d1 8708 mov.w 4(%a0),%d1 8708 mov.w 4(%a0),%d1 8709 and.l &0x7FFFFFFF,%d1 8709 and.l &0x7FFFFFFF,%d1 8710 cmp.l %d1,&0x3FFF8000 8710 cmp.l %d1,&0x3FFF8000 8711 bge.b ATANHBIG 8711 bge.b ATANHBIG 8712 8712 8713 #--THIS IS THE USUAL CASE, |X| < 1 8713 #--THIS IS THE USUAL CASE, |X| < 1 8714 #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) 8714 #--Y = |X|, Z = 2Y/(1-Y), ATANH(X) = SIGN(X) * (1/2) * LOG1P(Z). 8715 8715 8716 fabs.x (%a0),%fp0 8716 fabs.x (%a0),%fp0 # Y = |X| 8717 fmov.x %fp0,%fp1 8717 fmov.x %fp0,%fp1 8718 fneg.x %fp1 8718 fneg.x %fp1 # -Y 8719 fadd.x %fp0,%fp0 8719 fadd.x %fp0,%fp0 # 2Y 8720 fadd.s &0x3F800000,%fp1 8720 fadd.s &0x3F800000,%fp1 # 1-Y 8721 fdiv.x %fp1,%fp0 8721 fdiv.x %fp1,%fp0 # 2Y/(1-Y) 8722 mov.l (%a0),%d1 8722 mov.l (%a0),%d1 8723 and.l &0x80000000,%d1 8723 and.l &0x80000000,%d1 8724 or.l &0x3F000000,%d1 8724 or.l &0x3F000000,%d1 # SIGN(X)*HALF 8725 mov.l %d1,-(%sp) 8725 mov.l %d1,-(%sp) 8726 8726 8727 mov.l %d0,-(%sp) 8727 mov.l %d0,-(%sp) # save rnd prec,mode 8728 clr.l %d0 8728 clr.l %d0 # pass ext prec,RN 8729 fmovm.x &0x01,-(%sp) 8729 fmovm.x &0x01,-(%sp) # save Z on stack 8730 lea (%sp),%a0 8730 lea (%sp),%a0 # pass ptr to Z 8731 bsr slognp1 8731 bsr slognp1 # LOG1P(Z) 8732 add.l &0xc,%sp 8732 add.l &0xc,%sp # clear Z from stack 8733 8733 8734 mov.l (%sp)+,%d0 8734 mov.l (%sp)+,%d0 # fetch old prec,mode 8735 fmov.l %d0,%fpcr 8735 fmov.l %d0,%fpcr # load it 8736 mov.b &FMUL_OP,%d1 8736 mov.b &FMUL_OP,%d1 # last inst is MUL 8737 fmul.s (%sp)+,%fp0 8737 fmul.s (%sp)+,%fp0 8738 bra t_catch 8738 bra t_catch 8739 8739 8740 ATANHBIG: 8740 ATANHBIG: 8741 fabs.x (%a0),%fp0 8741 fabs.x (%a0),%fp0 # |X| 8742 fcmp.s %fp0,&0x3F800000 8742 fcmp.s %fp0,&0x3F800000 8743 fbgt t_operr 8743 fbgt t_operr 8744 bra t_dz 8744 bra t_dz 8745 8745 8746 global satanhd 8746 global satanhd 8747 #--ATANH(X) = X FOR DENORMALIZED X 8747 #--ATANH(X) = X FOR DENORMALIZED X 8748 satanhd: 8748 satanhd: 8749 bra t_extdnrm 8749 bra t_extdnrm 8750 8750 8751 ############################################# 8751 ######################################################################### 8752 # slog10(): computes the base-10 logarithm o 8752 # slog10(): computes the base-10 logarithm of a normalized input # 8753 # slog10d(): computes the base-10 logarithm o 8753 # slog10d(): computes the base-10 logarithm of a denormalized input # 8754 # slog2(): computes the base-2 logarithm of 8754 # slog2(): computes the base-2 logarithm of a normalized input # 8755 # slog2d(): computes the base-2 logarithm of 8755 # slog2d(): computes the base-2 logarithm of a denormalized input # 8756 # 8756 # # 8757 # INPUT ************************************* 8757 # INPUT *************************************************************** # 8758 # a0 = pointer to extended precision in 8758 # a0 = pointer to extended precision input # 8759 # d0 = round precision,mode 8759 # d0 = round precision,mode # 8760 # 8760 # # 8761 # OUTPUT ************************************ 8761 # OUTPUT ************************************************************** # 8762 # fp0 = log_10(X) or log_2(X) 8762 # fp0 = log_10(X) or log_2(X) # 8763 # 8763 # # 8764 # ACCURACY and MONOTONICITY ***************** 8764 # ACCURACY and MONOTONICITY ******************************************* # 8765 # The returned result is within 1.7 ulp 8765 # The returned result is within 1.7 ulps in 64 significant bit, # 8766 # i.e. within 0.5003 ulp to 53 bits if 8766 # i.e. within 0.5003 ulp to 53 bits if the result is subsequently # 8767 # rounded to double precision. The resu 8767 # rounded to double precision. The result is provably monotonic # 8768 # in double precision. 8768 # in double precision. # 8769 # 8769 # # 8770 # ALGORITHM ********************************* 8770 # ALGORITHM *********************************************************** # 8771 # 8771 # # 8772 # slog10d: 8772 # slog10d: # 8773 # 8773 # # 8774 # Step 0. If X < 0, create a NaN and ra 8774 # Step 0. If X < 0, create a NaN and raise the invalid operation # 8775 # flag. Otherwise, save FPCR in 8775 # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8776 # Notes: Default means round-to-neares 8776 # Notes: Default means round-to-nearest mode, no floating-point # 8777 # traps, and precision control 8777 # traps, and precision control = double extended. # 8778 # 8778 # # 8779 # Step 1. Call slognd to obtain Y = log 8779 # Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 8780 # Notes: Even if X is denormalized, lo 8780 # Notes: Even if X is denormalized, log(X) is always normalized. # 8781 # 8781 # # 8782 # Step 2. Compute log_10(X) = log(X) * 8782 # Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 8783 # 2.1 Restore the user FPCR 8783 # 2.1 Restore the user FPCR # 8784 # 2.2 Return ans := Y * INV_L10. 8784 # 2.2 Return ans := Y * INV_L10. # 8785 # 8785 # # 8786 # slog10: 8786 # slog10: # 8787 # 8787 # # 8788 # Step 0. If X < 0, create a NaN and ra 8788 # Step 0. If X < 0, create a NaN and raise the invalid operation # 8789 # flag. Otherwise, save FPCR in 8789 # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8790 # Notes: Default means round-to-neares 8790 # Notes: Default means round-to-nearest mode, no floating-point # 8791 # traps, and precision control 8791 # traps, and precision control = double extended. # 8792 # 8792 # # 8793 # Step 1. Call sLogN to obtain Y = log( 8793 # Step 1. Call sLogN to obtain Y = log(X), the natural log of X. # 8794 # 8794 # # 8795 # Step 2. Compute log_10(X) = log(X) 8795 # Step 2. Compute log_10(X) = log(X) * (1/log(10)). # 8796 # 2.1 Restore the user FPCR 8796 # 2.1 Restore the user FPCR # 8797 # 2.2 Return ans := Y * INV_L10. 8797 # 2.2 Return ans := Y * INV_L10. # 8798 # 8798 # # 8799 # sLog2d: 8799 # sLog2d: # 8800 # 8800 # # 8801 # Step 0. If X < 0, create a NaN and ra 8801 # Step 0. If X < 0, create a NaN and raise the invalid operation # 8802 # flag. Otherwise, save FPCR in 8802 # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8803 # Notes: Default means round-to-neares 8803 # Notes: Default means round-to-nearest mode, no floating-point # 8804 # traps, and precision control 8804 # traps, and precision control = double extended. # 8805 # 8805 # # 8806 # Step 1. Call slognd to obtain Y = log 8806 # Step 1. Call slognd to obtain Y = log(X), the natural log of X. # 8807 # Notes: Even if X is denormalized, lo 8807 # Notes: Even if X is denormalized, log(X) is always normalized. # 8808 # 8808 # # 8809 # Step 2. Compute log_10(X) = log(X) 8809 # Step 2. Compute log_10(X) = log(X) * (1/log(2)). # 8810 # 2.1 Restore the user FPCR 8810 # 2.1 Restore the user FPCR # 8811 # 2.2 Return ans := Y * INV_L2. 8811 # 2.2 Return ans := Y * INV_L2. # 8812 # 8812 # # 8813 # sLog2: 8813 # sLog2: # 8814 # 8814 # # 8815 # Step 0. If X < 0, create a NaN and ra 8815 # Step 0. If X < 0, create a NaN and raise the invalid operation # 8816 # flag. Otherwise, save FPCR in 8816 # flag. Otherwise, save FPCR in D1; set FpCR to default. # 8817 # Notes: Default means round-to-neares 8817 # Notes: Default means round-to-nearest mode, no floating-point # 8818 # traps, and precision control 8818 # traps, and precision control = double extended. # 8819 # 8819 # # 8820 # Step 1. If X is not an integer power 8820 # Step 1. If X is not an integer power of two, i.e., X != 2^k, # 8821 # go to Step 3. 8821 # go to Step 3. # 8822 # 8822 # # 8823 # Step 2. Return k. 8823 # Step 2. Return k. # 8824 # 2.1 Get integer k, X = 2^k. 8824 # 2.1 Get integer k, X = 2^k. # 8825 # 2.2 Restore the user FPCR. 8825 # 2.2 Restore the user FPCR. # 8826 # 2.3 Return ans := convert-to-do 8826 # 2.3 Return ans := convert-to-double-extended(k). # 8827 # 8827 # # 8828 # Step 3. Call sLogN to obtain Y = log( 8828 # Step 3. Call sLogN to obtain Y = log(X), the natural log of X. # 8829 # 8829 # # 8830 # Step 4. Compute log_2(X) = log(X) * 8830 # Step 4. Compute log_2(X) = log(X) * (1/log(2)). # 8831 # 4.1 Restore the user FPCR 8831 # 4.1 Restore the user FPCR # 8832 # 4.2 Return ans := Y * INV_L2. 8832 # 4.2 Return ans := Y * INV_L2. # 8833 # 8833 # # 8834 ############################################# 8834 ######################################################################### 8835 8835 8836 INV_L10: 8836 INV_L10: 8837 long 0x3FFD0000,0xDE5BD8A9 8837 long 0x3FFD0000,0xDE5BD8A9,0x37287195,0x00000000 8838 8838 8839 INV_L2: 8839 INV_L2: 8840 long 0x3FFF0000,0xB8AA3B29 8840 long 0x3FFF0000,0xB8AA3B29,0x5C17F0BC,0x00000000 8841 8841 8842 global slog10 8842 global slog10 8843 #--entry point for Log10(X), X is normalized 8843 #--entry point for Log10(X), X is normalized 8844 slog10: 8844 slog10: 8845 fmov.b &0x1,%fp0 8845 fmov.b &0x1,%fp0 8846 fcmp.x %fp0,(%a0) 8846 fcmp.x %fp0,(%a0) # if operand == 1, 8847 fbeq.l ld_pzero 8847 fbeq.l ld_pzero # return an EXACT zero 8848 8848 8849 mov.l (%a0),%d1 8849 mov.l (%a0),%d1 8850 blt.w invalid 8850 blt.w invalid 8851 mov.l %d0,-(%sp) 8851 mov.l %d0,-(%sp) 8852 clr.l %d0 8852 clr.l %d0 8853 bsr slogn 8853 bsr slogn # log(X), X normal. 8854 fmov.l (%sp)+,%fpcr 8854 fmov.l (%sp)+,%fpcr 8855 fmul.x INV_L10(%pc),%fp0 8855 fmul.x INV_L10(%pc),%fp0 8856 bra t_inx2 8856 bra t_inx2 8857 8857 8858 global slog10d 8858 global slog10d 8859 #--entry point for Log10(X), X is denormalize 8859 #--entry point for Log10(X), X is denormalized 8860 slog10d: 8860 slog10d: 8861 mov.l (%a0),%d1 8861 mov.l (%a0),%d1 8862 blt.w invalid 8862 blt.w invalid 8863 mov.l %d0,-(%sp) 8863 mov.l %d0,-(%sp) 8864 clr.l %d0 8864 clr.l %d0 8865 bsr slognd 8865 bsr slognd # log(X), X denorm. 8866 fmov.l (%sp)+,%fpcr 8866 fmov.l (%sp)+,%fpcr 8867 fmul.x INV_L10(%pc),%fp0 8867 fmul.x INV_L10(%pc),%fp0 8868 bra t_minx2 8868 bra t_minx2 8869 8869 8870 global slog2 8870 global slog2 8871 #--entry point for Log2(X), X is normalized 8871 #--entry point for Log2(X), X is normalized 8872 slog2: 8872 slog2: 8873 mov.l (%a0),%d1 8873 mov.l (%a0),%d1 8874 blt.w invalid 8874 blt.w invalid 8875 8875 8876 mov.l 8(%a0),%d1 8876 mov.l 8(%a0),%d1 8877 bne.b continue 8877 bne.b continue # X is not 2^k 8878 8878 8879 mov.l 4(%a0),%d1 8879 mov.l 4(%a0),%d1 8880 and.l &0x7FFFFFFF,%d1 8880 and.l &0x7FFFFFFF,%d1 8881 bne.b continue 8881 bne.b continue 8882 8882 8883 #--X = 2^k. 8883 #--X = 2^k. 8884 mov.w (%a0),%d1 8884 mov.w (%a0),%d1 8885 and.l &0x00007FFF,%d1 8885 and.l &0x00007FFF,%d1 8886 sub.l &0x3FFF,%d1 8886 sub.l &0x3FFF,%d1 8887 beq.l ld_pzero 8887 beq.l ld_pzero 8888 fmov.l %d0,%fpcr 8888 fmov.l %d0,%fpcr 8889 fmov.l %d1,%fp0 8889 fmov.l %d1,%fp0 8890 bra t_inx2 8890 bra t_inx2 8891 8891 8892 continue: 8892 continue: 8893 mov.l %d0,-(%sp) 8893 mov.l %d0,-(%sp) 8894 clr.l %d0 8894 clr.l %d0 8895 bsr slogn 8895 bsr slogn # log(X), X normal. 8896 fmov.l (%sp)+,%fpcr 8896 fmov.l (%sp)+,%fpcr 8897 fmul.x INV_L2(%pc),%fp0 8897 fmul.x INV_L2(%pc),%fp0 8898 bra t_inx2 8898 bra t_inx2 8899 8899 8900 invalid: 8900 invalid: 8901 bra t_operr 8901 bra t_operr 8902 8902 8903 global slog2d 8903 global slog2d 8904 #--entry point for Log2(X), X is denormalized 8904 #--entry point for Log2(X), X is denormalized 8905 slog2d: 8905 slog2d: 8906 mov.l (%a0),%d1 8906 mov.l (%a0),%d1 8907 blt.w invalid 8907 blt.w invalid 8908 mov.l %d0,-(%sp) 8908 mov.l %d0,-(%sp) 8909 clr.l %d0 8909 clr.l %d0 8910 bsr slognd 8910 bsr slognd # log(X), X denorm. 8911 fmov.l (%sp)+,%fpcr 8911 fmov.l (%sp)+,%fpcr 8912 fmul.x INV_L2(%pc),%fp0 8912 fmul.x INV_L2(%pc),%fp0 8913 bra t_minx2 8913 bra t_minx2 8914 8914 8915 ############################################# 8915 ######################################################################### 8916 # stwotox(): computes 2**X for a normalized 8916 # stwotox(): computes 2**X for a normalized input # 8917 # stwotoxd(): computes 2**X for a denormalize 8917 # stwotoxd(): computes 2**X for a denormalized input # 8918 # stentox(): computes 10**X for a normalized 8918 # stentox(): computes 10**X for a normalized input # 8919 # stentoxd(): computes 10**X for a denormaliz 8919 # stentoxd(): computes 10**X for a denormalized input # 8920 # 8920 # # 8921 # INPUT ************************************* 8921 # INPUT *************************************************************** # 8922 # a0 = pointer to extended precision in 8922 # a0 = pointer to extended precision input # 8923 # d0 = round precision,mode 8923 # d0 = round precision,mode # 8924 # 8924 # # 8925 # OUTPUT ************************************ 8925 # OUTPUT ************************************************************** # 8926 # fp0 = 2**X or 10**X 8926 # fp0 = 2**X or 10**X # 8927 # 8927 # # 8928 # ACCURACY and MONOTONICITY ***************** 8928 # ACCURACY and MONOTONICITY ******************************************* # 8929 # The returned result is within 2 ulps 8929 # The returned result is within 2 ulps in 64 significant bit, # 8930 # i.e. within 0.5001 ulp to 53 bits if 8930 # i.e. within 0.5001 ulp to 53 bits if the result is subsequently # 8931 # rounded to double precision. The resu 8931 # rounded to double precision. The result is provably monotonic # 8932 # in double precision. 8932 # in double precision. # 8933 # 8933 # # 8934 # ALGORITHM ********************************* 8934 # ALGORITHM *********************************************************** # 8935 # 8935 # # 8936 # twotox 8936 # twotox # 8937 # 1. If |X| > 16480, go to ExpBig. 8937 # 1. If |X| > 16480, go to ExpBig. # 8938 # 8938 # # 8939 # 2. If |X| < 2**(-70), go to ExpSm. 8939 # 2. If |X| < 2**(-70), go to ExpSm. # 8940 # 8940 # # 8941 # 3. Decompose X as X = N/64 + r where 8941 # 3. Decompose X as X = N/64 + r where |r| <= 1/128. Furthermore # 8942 # decompose N as 8942 # decompose N as # 8943 # N = 64(M + M') + j, j = 0,1 8943 # N = 64(M + M') + j, j = 0,1,2,...,63. # 8944 # 8944 # # 8945 # 4. Overwrite r := r * log2. Then 8945 # 4. Overwrite r := r * log2. Then # 8946 # 2**X = 2**(M') * 2**(M) * 2** 8946 # 2**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 8947 # Go to expr to compute that ex 8947 # Go to expr to compute that expression. # 8948 # 8948 # # 8949 # tentox 8949 # tentox # 8950 # 1. If |X| > 16480*log_10(2) (base 10 8950 # 1. If |X| > 16480*log_10(2) (base 10 log of 2), go to ExpBig. # 8951 # 8951 # # 8952 # 2. If |X| < 2**(-70), go to ExpSm. 8952 # 2. If |X| < 2**(-70), go to ExpSm. # 8953 # 8953 # # 8954 # 3. Set y := X*log_2(10)*64 (base 2 lo 8954 # 3. Set y := X*log_2(10)*64 (base 2 log of 10). Set # 8955 # N := round-to-int(y). Decompo 8955 # N := round-to-int(y). Decompose N as # 8956 # N = 64(M + M') + j, j = 0,1 8956 # N = 64(M + M') + j, j = 0,1,2,...,63. # 8957 # 8957 # # 8958 # 4. Define r as 8958 # 4. Define r as # 8959 # r := ((X - N*L1)-N*L2) * L10 8959 # r := ((X - N*L1)-N*L2) * L10 # 8960 # where L1, L2 are the leading 8960 # where L1, L2 are the leading and trailing parts of # 8961 # log_10(2)/64 and L10 is the n 8961 # log_10(2)/64 and L10 is the natural log of 10. Then # 8962 # 10**X = 2**(M') * 2**(M) * 2* 8962 # 10**X = 2**(M') * 2**(M) * 2**(j/64) * exp(r). # 8963 # Go to expr to compute that ex 8963 # Go to expr to compute that expression. # 8964 # 8964 # # 8965 # expr 8965 # expr # 8966 # 1. Fetch 2**(j/64) from table as Fact 8966 # 1. Fetch 2**(j/64) from table as Fact1 and Fact2. # 8967 # 8967 # # 8968 # 2. Overwrite Fact1 and Fact2 by 8968 # 2. Overwrite Fact1 and Fact2 by # 8969 # Fact1 := 2**(M) * Fact1 8969 # Fact1 := 2**(M) * Fact1 # 8970 # Fact2 := 2**(M) * Fact2 8970 # Fact2 := 2**(M) * Fact2 # 8971 # Thus Fact1 + Fact2 = 2**(M) * 8971 # Thus Fact1 + Fact2 = 2**(M) * 2**(j/64). # 8972 # 8972 # # 8973 # 3. Calculate P where 1 + P approximat 8973 # 3. Calculate P where 1 + P approximates exp(r): # 8974 # P = r + r*r*(A1+r*(A2+...+r*A 8974 # P = r + r*r*(A1+r*(A2+...+r*A5)). # 8975 # 8975 # # 8976 # 4. Let AdjFact := 2**(M'). Return 8976 # 4. Let AdjFact := 2**(M'). Return # 8977 # AdjFact * ( Fact1 + ((Fact1*P 8977 # AdjFact * ( Fact1 + ((Fact1*P) + Fact2) ). # 8978 # Exit. 8978 # Exit. # 8979 # 8979 # # 8980 # ExpBig 8980 # ExpBig # 8981 # 1. Generate overflow by Huge * Huge i 8981 # 1. Generate overflow by Huge * Huge if X > 0; otherwise, # 8982 # generate underflow by Tiny * 8982 # generate underflow by Tiny * Tiny. # 8983 # 8983 # # 8984 # ExpSm 8984 # ExpSm # 8985 # 1. Return 1 + X. 8985 # 1. Return 1 + X. # 8986 # 8986 # # 8987 ############################################# 8987 ######################################################################### 8988 8988 8989 L2TEN64: 8989 L2TEN64: 8990 long 0x406A934F,0x0979A371 8990 long 0x406A934F,0x0979A371 # 64LOG10/LOG2 8991 L10TWO1: 8991 L10TWO1: 8992 long 0x3F734413,0x509F8000 8992 long 0x3F734413,0x509F8000 # LOG2/64LOG10 8993 8993 8994 L10TWO2: 8994 L10TWO2: 8995 long 0xBFCD0000,0xC0219DC1 8995 long 0xBFCD0000,0xC0219DC1,0xDA994FD2,0x00000000 8996 8996 8997 LOG10: long 0x40000000,0x935D8DDD 8997 LOG10: long 0x40000000,0x935D8DDD,0xAAA8AC17,0x00000000 8998 8998 8999 LOG2: long 0x3FFE0000,0xB17217F7 8999 LOG2: long 0x3FFE0000,0xB17217F7,0xD1CF79AC,0x00000000 9000 9000 9001 EXPA5: long 0x3F56C16D,0x6F7BD0B2 9001 EXPA5: long 0x3F56C16D,0x6F7BD0B2 9002 EXPA4: long 0x3F811112,0x302C712C 9002 EXPA4: long 0x3F811112,0x302C712C 9003 EXPA3: long 0x3FA55555,0x55554CC1 9003 EXPA3: long 0x3FA55555,0x55554CC1 9004 EXPA2: long 0x3FC55555,0x55554A54 9004 EXPA2: long 0x3FC55555,0x55554A54 9005 EXPA1: long 0x3FE00000,0x00000000 9005 EXPA1: long 0x3FE00000,0x00000000,0x00000000,0x00000000 9006 9006 9007 TEXPTBL: 9007 TEXPTBL: 9008 long 0x3FFF0000,0x80000000 9008 long 0x3FFF0000,0x80000000,0x00000000,0x3F738000 9009 long 0x3FFF0000,0x8164D1F3 9009 long 0x3FFF0000,0x8164D1F3,0xBC030773,0x3FBEF7CA 9010 long 0x3FFF0000,0x82CD8698 9010 long 0x3FFF0000,0x82CD8698,0xAC2BA1D7,0x3FBDF8A9 9011 long 0x3FFF0000,0x843A28C3 9011 long 0x3FFF0000,0x843A28C3,0xACDE4046,0x3FBCD7C9 9012 long 0x3FFF0000,0x85AAC367 9012 long 0x3FFF0000,0x85AAC367,0xCC487B15,0xBFBDE8DA 9013 long 0x3FFF0000,0x871F6196 9013 long 0x3FFF0000,0x871F6196,0x9E8D1010,0x3FBDE85C 9014 long 0x3FFF0000,0x88980E80 9014 long 0x3FFF0000,0x88980E80,0x92DA8527,0x3FBEBBF1 9015 long 0x3FFF0000,0x8A14D575 9015 long 0x3FFF0000,0x8A14D575,0x496EFD9A,0x3FBB80CA 9016 long 0x3FFF0000,0x8B95C1E3 9016 long 0x3FFF0000,0x8B95C1E3,0xEA8BD6E7,0xBFBA8373 9017 long 0x3FFF0000,0x8D1ADF5B 9017 long 0x3FFF0000,0x8D1ADF5B,0x7E5BA9E6,0xBFBE9670 9018 long 0x3FFF0000,0x8EA4398B 9018 long 0x3FFF0000,0x8EA4398B,0x45CD53C0,0x3FBDB700 9019 long 0x3FFF0000,0x9031DC43 9019 long 0x3FFF0000,0x9031DC43,0x1466B1DC,0x3FBEEEB0 9020 long 0x3FFF0000,0x91C3D373 9020 long 0x3FFF0000,0x91C3D373,0xAB11C336,0x3FBBFD6D 9021 long 0x3FFF0000,0x935A2B2F 9021 long 0x3FFF0000,0x935A2B2F,0x13E6E92C,0xBFBDB319 9022 long 0x3FFF0000,0x94F4EFA8 9022 long 0x3FFF0000,0x94F4EFA8,0xFEF70961,0x3FBDBA2B 9023 long 0x3FFF0000,0x96942D37 9023 long 0x3FFF0000,0x96942D37,0x20185A00,0x3FBE91D5 9024 long 0x3FFF0000,0x9837F051 9024 long 0x3FFF0000,0x9837F051,0x8DB8A96F,0x3FBE8D5A 9025 long 0x3FFF0000,0x99E04593 9025 long 0x3FFF0000,0x99E04593,0x20B7FA65,0xBFBCDE7B 9026 long 0x3FFF0000,0x9B8D39B9 9026 long 0x3FFF0000,0x9B8D39B9,0xD54E5539,0xBFBEBAAF 9027 long 0x3FFF0000,0x9D3ED9A7 9027 long 0x3FFF0000,0x9D3ED9A7,0x2CFFB751,0xBFBD86DA 9028 long 0x3FFF0000,0x9EF53260 9028 long 0x3FFF0000,0x9EF53260,0x91A111AE,0xBFBEBEDD 9029 long 0x3FFF0000,0xA0B0510F 9029 long 0x3FFF0000,0xA0B0510F,0xB9714FC2,0x3FBCC96E 9030 long 0x3FFF0000,0xA2704303 9030 long 0x3FFF0000,0xA2704303,0x0C496819,0xBFBEC90B 9031 long 0x3FFF0000,0xA43515AE 9031 long 0x3FFF0000,0xA43515AE,0x09E6809E,0x3FBBD1DB 9032 long 0x3FFF0000,0xA5FED6A9 9032 long 0x3FFF0000,0xA5FED6A9,0xB15138EA,0x3FBCE5EB 9033 long 0x3FFF0000,0xA7CD93B4 9033 long 0x3FFF0000,0xA7CD93B4,0xE965356A,0xBFBEC274 9034 long 0x3FFF0000,0xA9A15AB4 9034 long 0x3FFF0000,0xA9A15AB4,0xEA7C0EF8,0x3FBEA83C 9035 long 0x3FFF0000,0xAB7A39B5 9035 long 0x3FFF0000,0xAB7A39B5,0xA93ED337,0x3FBECB00 9036 long 0x3FFF0000,0xAD583EEA 9036 long 0x3FFF0000,0xAD583EEA,0x42A14AC6,0x3FBE9301 9037 long 0x3FFF0000,0xAF3B78AD 9037 long 0x3FFF0000,0xAF3B78AD,0x690A4375,0xBFBD8367 9038 long 0x3FFF0000,0xB123F581 9038 long 0x3FFF0000,0xB123F581,0xD2AC2590,0xBFBEF05F 9039 long 0x3FFF0000,0xB311C412 9039 long 0x3FFF0000,0xB311C412,0xA9112489,0x3FBDFB3C 9040 long 0x3FFF0000,0xB504F333 9040 long 0x3FFF0000,0xB504F333,0xF9DE6484,0x3FBEB2FB 9041 long 0x3FFF0000,0xB6FD91E3 9041 long 0x3FFF0000,0xB6FD91E3,0x28D17791,0x3FBAE2CB 9042 long 0x3FFF0000,0xB8FBAF47 9042 long 0x3FFF0000,0xB8FBAF47,0x62FB9EE9,0x3FBCDC3C 9043 long 0x3FFF0000,0xBAFF5AB2 9043 long 0x3FFF0000,0xBAFF5AB2,0x133E45FB,0x3FBEE9AA 9044 long 0x3FFF0000,0xBD08A39F 9044 long 0x3FFF0000,0xBD08A39F,0x580C36BF,0xBFBEAEFD 9045 long 0x3FFF0000,0xBF1799B6 9045 long 0x3FFF0000,0xBF1799B6,0x7A731083,0xBFBCBF51 9046 long 0x3FFF0000,0xC12C4CCA 9046 long 0x3FFF0000,0xC12C4CCA,0x66709456,0x3FBEF88A 9047 long 0x3FFF0000,0xC346CCDA 9047 long 0x3FFF0000,0xC346CCDA,0x24976407,0x3FBD83B2 9048 long 0x3FFF0000,0xC5672A11 9048 long 0x3FFF0000,0xC5672A11,0x5506DADD,0x3FBDF8AB 9049 long 0x3FFF0000,0xC78D74C8 9049 long 0x3FFF0000,0xC78D74C8,0xABB9B15D,0xBFBDFB17 9050 long 0x3FFF0000,0xC9B9BD86 9050 long 0x3FFF0000,0xC9B9BD86,0x6E2F27A3,0xBFBEFE3C 9051 long 0x3FFF0000,0xCBEC14FE 9051 long 0x3FFF0000,0xCBEC14FE,0xF2727C5D,0xBFBBB6F8 9052 long 0x3FFF0000,0xCE248C15 9052 long 0x3FFF0000,0xCE248C15,0x1F8480E4,0xBFBCEE53 9053 long 0x3FFF0000,0xD06333DA 9053 long 0x3FFF0000,0xD06333DA,0xEF2B2595,0xBFBDA4AE 9054 long 0x3FFF0000,0xD2A81D91 9054 long 0x3FFF0000,0xD2A81D91,0xF12AE45A,0x3FBC9124 9055 long 0x3FFF0000,0xD4F35AAB 9055 long 0x3FFF0000,0xD4F35AAB,0xCFEDFA1F,0x3FBEB243 9056 long 0x3FFF0000,0xD744FCCA 9056 long 0x3FFF0000,0xD744FCCA,0xD69D6AF4,0x3FBDE69A 9057 long 0x3FFF0000,0xD99D15C2 9057 long 0x3FFF0000,0xD99D15C2,0x78AFD7B6,0xBFB8BC61 9058 long 0x3FFF0000,0xDBFBB797 9058 long 0x3FFF0000,0xDBFBB797,0xDAF23755,0x3FBDF610 9059 long 0x3FFF0000,0xDE60F482 9059 long 0x3FFF0000,0xDE60F482,0x5E0E9124,0xBFBD8BE1 9060 long 0x3FFF0000,0xE0CCDEEC 9060 long 0x3FFF0000,0xE0CCDEEC,0x2A94E111,0x3FBACB12 9061 long 0x3FFF0000,0xE33F8972 9061 long 0x3FFF0000,0xE33F8972,0xBE8A5A51,0x3FBB9BFE 9062 long 0x3FFF0000,0xE5B906E7 9062 long 0x3FFF0000,0xE5B906E7,0x7C8348A8,0x3FBCF2F4 9063 long 0x3FFF0000,0xE8396A50 9063 long 0x3FFF0000,0xE8396A50,0x3C4BDC68,0x3FBEF22F 9064 long 0x3FFF0000,0xEAC0C6E7 9064 long 0x3FFF0000,0xEAC0C6E7,0xDD24392F,0xBFBDBF4A 9065 long 0x3FFF0000,0xED4F301E 9065 long 0x3FFF0000,0xED4F301E,0xD9942B84,0x3FBEC01A 9066 long 0x3FFF0000,0xEFE4B99B 9066 long 0x3FFF0000,0xEFE4B99B,0xDCDAF5CB,0x3FBE8CAC 9067 long 0x3FFF0000,0xF281773C 9067 long 0x3FFF0000,0xF281773C,0x59FFB13A,0xBFBCBB3F 9068 long 0x3FFF0000,0xF5257D15 9068 long 0x3FFF0000,0xF5257D15,0x2486CC2C,0x3FBEF73A 9069 long 0x3FFF0000,0xF7D0DF73 9069 long 0x3FFF0000,0xF7D0DF73,0x0AD13BB9,0xBFB8B795 9070 long 0x3FFF0000,0xFA83B2DB 9070 long 0x3FFF0000,0xFA83B2DB,0x722A033A,0x3FBEF84B 9071 long 0x3FFF0000,0xFD3E0C0C 9071 long 0x3FFF0000,0xFD3E0C0C,0xF486C175,0xBFBEF581 9072 9072 9073 set INT,L_SCR1 9073 set INT,L_SCR1 9074 9074 9075 set X,FP_SCR0 9075 set X,FP_SCR0 9076 set XDCARE,X+2 9076 set XDCARE,X+2 9077 set XFRAC,X+4 9077 set XFRAC,X+4 9078 9078 9079 set ADJFACT,FP_SCR0 9079 set ADJFACT,FP_SCR0 9080 9080 9081 set FACT1,FP_SCR0 9081 set FACT1,FP_SCR0 9082 set FACT1HI,FACT1+4 9082 set FACT1HI,FACT1+4 9083 set FACT1LOW,FACT1+8 9083 set FACT1LOW,FACT1+8 9084 9084 9085 set FACT2,FP_SCR1 9085 set FACT2,FP_SCR1 9086 set FACT2HI,FACT2+4 9086 set FACT2HI,FACT2+4 9087 set FACT2LOW,FACT2+8 9087 set FACT2LOW,FACT2+8 9088 9088 9089 global stwotox 9089 global stwotox 9090 #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, 9090 #--ENTRY POINT FOR 2**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 9091 stwotox: 9091 stwotox: 9092 fmovm.x (%a0),&0x80 9092 fmovm.x (%a0),&0x80 # LOAD INPUT 9093 9093 9094 mov.l (%a0),%d1 9094 mov.l (%a0),%d1 9095 mov.w 4(%a0),%d1 9095 mov.w 4(%a0),%d1 9096 fmov.x %fp0,X(%a6) 9096 fmov.x %fp0,X(%a6) 9097 and.l &0x7FFFFFFF,%d1 9097 and.l &0x7FFFFFFF,%d1 9098 9098 9099 cmp.l %d1,&0x3FB98000 9099 cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 9100 bge.b TWOOK1 9100 bge.b TWOOK1 9101 bra.w EXPBORS 9101 bra.w EXPBORS 9102 9102 9103 TWOOK1: 9103 TWOOK1: 9104 cmp.l %d1,&0x400D80C0 9104 cmp.l %d1,&0x400D80C0 # |X| > 16480? 9105 ble.b TWOMAIN 9105 ble.b TWOMAIN 9106 bra.w EXPBORS 9106 bra.w EXPBORS 9107 9107 9108 TWOMAIN: 9108 TWOMAIN: 9109 #--USUAL CASE, 2^(-70) <= |X| <= 16480 9109 #--USUAL CASE, 2^(-70) <= |X| <= 16480 9110 9110 9111 fmov.x %fp0,%fp1 9111 fmov.x %fp0,%fp1 9112 fmul.s &0x42800000,%fp1 9112 fmul.s &0x42800000,%fp1 # 64 * X 9113 fmov.l %fp1,INT(%a6) 9113 fmov.l %fp1,INT(%a6) # N = ROUND-TO-INT(64 X) 9114 mov.l %d2,-(%sp) 9114 mov.l %d2,-(%sp) 9115 lea TEXPTBL(%pc),%a1 9115 lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 9116 fmov.l INT(%a6),%fp1 9116 fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 9117 mov.l INT(%a6),%d1 9117 mov.l INT(%a6),%d1 9118 mov.l %d1,%d2 9118 mov.l %d1,%d2 9119 and.l &0x3F,%d1 9119 and.l &0x3F,%d1 # D0 IS J 9120 asl.l &4,%d1 9120 asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 9121 add.l %d1,%a1 9121 add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 9122 asr.l &6,%d2 9122 asr.l &6,%d2 # d2 IS L, N = 64L + J 9123 mov.l %d2,%d1 9123 mov.l %d2,%d1 9124 asr.l &1,%d1 9124 asr.l &1,%d1 # D0 IS M 9125 sub.l %d1,%d2 9125 sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 9126 add.l &0x3FFF,%d2 9126 add.l &0x3FFF,%d2 9127 9127 9128 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING POR 9128 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 9129 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT 9129 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 9130 #--ADJFACT = 2^(M'). 9130 #--ADJFACT = 2^(M'). 9131 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR 9131 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 9132 9132 9133 fmovm.x &0x0c,-(%sp) 9133 fmovm.x &0x0c,-(%sp) # save fp2/fp3 9134 9134 9135 fmul.s &0x3C800000,%fp1 9135 fmul.s &0x3C800000,%fp1 # (1/64)*N 9136 mov.l (%a1)+,FACT1(%a6) 9136 mov.l (%a1)+,FACT1(%a6) 9137 mov.l (%a1)+,FACT1HI(%a6) 9137 mov.l (%a1)+,FACT1HI(%a6) 9138 mov.l (%a1)+,FACT1LOW(%a6) 9138 mov.l (%a1)+,FACT1LOW(%a6) 9139 mov.w (%a1)+,FACT2(%a6) 9139 mov.w (%a1)+,FACT2(%a6) 9140 9140 9141 fsub.x %fp1,%fp0 9141 fsub.x %fp1,%fp0 # X - (1/64)*INT(64 X) 9142 9142 9143 mov.w (%a1)+,FACT2HI(%a6) 9143 mov.w (%a1)+,FACT2HI(%a6) 9144 clr.w FACT2HI+2(%a6) 9144 clr.w FACT2HI+2(%a6) 9145 clr.l FACT2LOW(%a6) 9145 clr.l FACT2LOW(%a6) 9146 add.w %d1,FACT1(%a6) 9146 add.w %d1,FACT1(%a6) 9147 fmul.x LOG2(%pc),%fp0 9147 fmul.x LOG2(%pc),%fp0 # FP0 IS R 9148 add.w %d1,FACT2(%a6) 9148 add.w %d1,FACT2(%a6) 9149 9149 9150 bra.w expr 9150 bra.w expr 9151 9151 9152 EXPBORS: 9152 EXPBORS: 9153 #--FPCR, D0 SAVED 9153 #--FPCR, D0 SAVED 9154 cmp.l %d1,&0x3FFF8000 9154 cmp.l %d1,&0x3FFF8000 9155 bgt.b TEXPBIG 9155 bgt.b TEXPBIG 9156 9156 9157 #--|X| IS SMALL, RETURN 1 + X 9157 #--|X| IS SMALL, RETURN 1 + X 9158 9158 9159 fmov.l %d0,%fpcr 9159 fmov.l %d0,%fpcr # restore users round prec,mode 9160 fadd.s &0x3F800000,%fp0 9160 fadd.s &0x3F800000,%fp0 # RETURN 1 + X 9161 bra t_pinx2 9161 bra t_pinx2 9162 9162 9163 TEXPBIG: 9163 TEXPBIG: 9164 #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; 9164 #--|X| IS LARGE, GENERATE OVERFLOW IF X > 0; ELSE GENERATE UNDERFLOW 9165 #--REGISTERS SAVE SO FAR ARE FPCR AND D0 9165 #--REGISTERS SAVE SO FAR ARE FPCR AND D0 9166 mov.l X(%a6),%d1 9166 mov.l X(%a6),%d1 9167 cmp.l %d1,&0 9167 cmp.l %d1,&0 9168 blt.b EXPNEG 9168 blt.b EXPNEG 9169 9169 9170 bra t_ovfl2 9170 bra t_ovfl2 # t_ovfl expects positive value 9171 9171 9172 EXPNEG: 9172 EXPNEG: 9173 bra t_unfl2 9173 bra t_unfl2 # t_unfl expects positive value 9174 9174 9175 global stwotoxd 9175 global stwotoxd 9176 stwotoxd: 9176 stwotoxd: 9177 #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED AR 9177 #--ENTRY POINT FOR 2**(X) FOR DENORMALIZED ARGUMENT 9178 9178 9179 fmov.l %d0,%fpcr 9179 fmov.l %d0,%fpcr # set user's rounding mode/precision 9180 fmov.s &0x3F800000,%fp0 9180 fmov.s &0x3F800000,%fp0 # RETURN 1 + X 9181 mov.l (%a0),%d1 9181 mov.l (%a0),%d1 9182 or.l &0x00800001,%d1 9182 or.l &0x00800001,%d1 9183 fadd.s %d1,%fp0 9183 fadd.s %d1,%fp0 9184 bra t_pinx2 9184 bra t_pinx2 9185 9185 9186 global stentox 9186 global stentox 9187 #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, 9187 #--ENTRY POINT FOR 10**(X), HERE X IS FINITE, NON-ZERO, AND NOT NAN'S 9188 stentox: 9188 stentox: 9189 fmovm.x (%a0),&0x80 9189 fmovm.x (%a0),&0x80 # LOAD INPUT 9190 9190 9191 mov.l (%a0),%d1 9191 mov.l (%a0),%d1 9192 mov.w 4(%a0),%d1 9192 mov.w 4(%a0),%d1 9193 fmov.x %fp0,X(%a6) 9193 fmov.x %fp0,X(%a6) 9194 and.l &0x7FFFFFFF,%d1 9194 and.l &0x7FFFFFFF,%d1 9195 9195 9196 cmp.l %d1,&0x3FB98000 9196 cmp.l %d1,&0x3FB98000 # |X| >= 2**(-70)? 9197 bge.b TENOK1 9197 bge.b TENOK1 9198 bra.w EXPBORS 9198 bra.w EXPBORS 9199 9199 9200 TENOK1: 9200 TENOK1: 9201 cmp.l %d1,&0x400B9B07 9201 cmp.l %d1,&0x400B9B07 # |X| <= 16480*log2/log10 ? 9202 ble.b TENMAIN 9202 ble.b TENMAIN 9203 bra.w EXPBORS 9203 bra.w EXPBORS 9204 9204 9205 TENMAIN: 9205 TENMAIN: 9206 #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 9206 #--USUAL CASE, 2^(-70) <= |X| <= 16480 LOG 2 / LOG 10 9207 9207 9208 fmov.x %fp0,%fp1 9208 fmov.x %fp0,%fp1 9209 fmul.d L2TEN64(%pc),%fp1 9209 fmul.d L2TEN64(%pc),%fp1 # X*64*LOG10/LOG2 9210 fmov.l %fp1,INT(%a6) 9210 fmov.l %fp1,INT(%a6) # N=INT(X*64*LOG10/LOG2) 9211 mov.l %d2,-(%sp) 9211 mov.l %d2,-(%sp) 9212 lea TEXPTBL(%pc),%a1 9212 lea TEXPTBL(%pc),%a1 # LOAD ADDRESS OF TABLE OF 2^(J/64) 9213 fmov.l INT(%a6),%fp1 9213 fmov.l INT(%a6),%fp1 # N --> FLOATING FMT 9214 mov.l INT(%a6),%d1 9214 mov.l INT(%a6),%d1 9215 mov.l %d1,%d2 9215 mov.l %d1,%d2 9216 and.l &0x3F,%d1 9216 and.l &0x3F,%d1 # D0 IS J 9217 asl.l &4,%d1 9217 asl.l &4,%d1 # DISPLACEMENT FOR 2^(J/64) 9218 add.l %d1,%a1 9218 add.l %d1,%a1 # ADDRESS FOR 2^(J/64) 9219 asr.l &6,%d2 9219 asr.l &6,%d2 # d2 IS L, N = 64L + J 9220 mov.l %d2,%d1 9220 mov.l %d2,%d1 9221 asr.l &1,%d1 9221 asr.l &1,%d1 # D0 IS M 9222 sub.l %d1,%d2 9222 sub.l %d1,%d2 # d2 IS M', N = 64(M+M') + J 9223 add.l &0x3FFF,%d2 9223 add.l &0x3FFF,%d2 9224 9224 9225 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING POR 9225 #--SUMMARY: a1 IS ADDRESS FOR THE LEADING PORTION OF 2^(J/64), 9226 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT 9226 #--D0 IS M WHERE N = 64(M+M') + J. NOTE THAT |M| <= 16140 BY DESIGN. 9227 #--ADJFACT = 2^(M'). 9227 #--ADJFACT = 2^(M'). 9228 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR 9228 #--REGISTERS SAVED SO FAR ARE (IN ORDER) FPCR, D0, FP1, a1, AND FP2. 9229 fmovm.x &0x0c,-(%sp) 9229 fmovm.x &0x0c,-(%sp) # save fp2/fp3 9230 9230 9231 fmov.x %fp1,%fp2 9231 fmov.x %fp1,%fp2 9232 9232 9233 fmul.d L10TWO1(%pc),%fp1 9233 fmul.d L10TWO1(%pc),%fp1 # N*(LOG2/64LOG10)_LEAD 9234 mov.l (%a1)+,FACT1(%a6) 9234 mov.l (%a1)+,FACT1(%a6) 9235 9235 9236 fmul.x L10TWO2(%pc),%fp2 9236 fmul.x L10TWO2(%pc),%fp2 # N*(LOG2/64LOG10)_TRAIL 9237 9237 9238 mov.l (%a1)+,FACT1HI(%a6) 9238 mov.l (%a1)+,FACT1HI(%a6) 9239 mov.l (%a1)+,FACT1LOW(%a6) 9239 mov.l (%a1)+,FACT1LOW(%a6) 9240 fsub.x %fp1,%fp0 9240 fsub.x %fp1,%fp0 # X - N L_LEAD 9241 mov.w (%a1)+,FACT2(%a6) 9241 mov.w (%a1)+,FACT2(%a6) 9242 9242 9243 fsub.x %fp2,%fp0 9243 fsub.x %fp2,%fp0 # X - N L_TRAIL 9244 9244 9245 mov.w (%a1)+,FACT2HI(%a6) 9245 mov.w (%a1)+,FACT2HI(%a6) 9246 clr.w FACT2HI+2(%a6) 9246 clr.w FACT2HI+2(%a6) 9247 clr.l FACT2LOW(%a6) 9247 clr.l FACT2LOW(%a6) 9248 9248 9249 fmul.x LOG10(%pc),%fp0 9249 fmul.x LOG10(%pc),%fp0 # FP0 IS R 9250 add.w %d1,FACT1(%a6) 9250 add.w %d1,FACT1(%a6) 9251 add.w %d1,FACT2(%a6) 9251 add.w %d1,FACT2(%a6) 9252 9252 9253 expr: 9253 expr: 9254 #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN 9254 #--FPCR, FP2, FP3 ARE SAVED IN ORDER AS SHOWN. 9255 #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 9255 #--ADJFACT CONTAINS 2**(M'), FACT1 + FACT2 = 2**(M) * 2**(J/64). 9256 #--FP0 IS R. THE FOLLOWING CODE COMPUTES 9256 #--FP0 IS R. THE FOLLOWING CODE COMPUTES 9257 #-- 2**(M'+M) * 2**(J/64) * EXP(R) 9257 #-- 2**(M'+M) * 2**(J/64) * EXP(R) 9258 9258 9259 fmov.x %fp0,%fp1 9259 fmov.x %fp0,%fp1 9260 fmul.x %fp1,%fp1 9260 fmul.x %fp1,%fp1 # FP1 IS S = R*R 9261 9261 9262 fmov.d EXPA5(%pc),%fp2 9262 fmov.d EXPA5(%pc),%fp2 # FP2 IS A5 9263 fmov.d EXPA4(%pc),%fp3 9263 fmov.d EXPA4(%pc),%fp3 # FP3 IS A4 9264 9264 9265 fmul.x %fp1,%fp2 9265 fmul.x %fp1,%fp2 # FP2 IS S*A5 9266 fmul.x %fp1,%fp3 9266 fmul.x %fp1,%fp3 # FP3 IS S*A4 9267 9267 9268 fadd.d EXPA3(%pc),%fp2 9268 fadd.d EXPA3(%pc),%fp2 # FP2 IS A3+S*A5 9269 fadd.d EXPA2(%pc),%fp3 9269 fadd.d EXPA2(%pc),%fp3 # FP3 IS A2+S*A4 9270 9270 9271 fmul.x %fp1,%fp2 9271 fmul.x %fp1,%fp2 # FP2 IS S*(A3+S*A5) 9272 fmul.x %fp1,%fp3 9272 fmul.x %fp1,%fp3 # FP3 IS S*(A2+S*A4) 9273 9273 9274 fadd.d EXPA1(%pc),%fp2 9274 fadd.d EXPA1(%pc),%fp2 # FP2 IS A1+S*(A3+S*A5) 9275 fmul.x %fp0,%fp3 9275 fmul.x %fp0,%fp3 # FP3 IS R*S*(A2+S*A4) 9276 9276 9277 fmul.x %fp1,%fp2 9277 fmul.x %fp1,%fp2 # FP2 IS S*(A1+S*(A3+S*A5)) 9278 fadd.x %fp3,%fp0 9278 fadd.x %fp3,%fp0 # FP0 IS R+R*S*(A2+S*A4) 9279 fadd.x %fp2,%fp0 9279 fadd.x %fp2,%fp0 # FP0 IS EXP(R) - 1 9280 9280 9281 fmovm.x (%sp)+,&0x30 9281 fmovm.x (%sp)+,&0x30 # restore fp2/fp3 9282 9282 9283 #--FINAL RECONSTRUCTION PROCESS 9283 #--FINAL RECONSTRUCTION PROCESS 9284 #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP( 9284 #--EXP(X) = 2^M*2^(J/64) + 2^M*2^(J/64)*(EXP(R)-1) - (1 OR 0) 9285 9285 9286 fmul.x FACT1(%a6),%fp0 9286 fmul.x FACT1(%a6),%fp0 9287 fadd.x FACT2(%a6),%fp0 9287 fadd.x FACT2(%a6),%fp0 9288 fadd.x FACT1(%a6),%fp0 9288 fadd.x FACT1(%a6),%fp0 9289 9289 9290 fmov.l %d0,%fpcr 9290 fmov.l %d0,%fpcr # restore users round prec,mode 9291 mov.w %d2,ADJFACT(%a6) 9291 mov.w %d2,ADJFACT(%a6) # INSERT EXPONENT 9292 mov.l (%sp)+,%d2 9292 mov.l (%sp)+,%d2 9293 mov.l &0x80000000,ADJFACT+4 9293 mov.l &0x80000000,ADJFACT+4(%a6) 9294 clr.l ADJFACT+8(%a6) 9294 clr.l ADJFACT+8(%a6) 9295 mov.b &FMUL_OP,%d1 9295 mov.b &FMUL_OP,%d1 # last inst is MUL 9296 fmul.x ADJFACT(%a6),%fp0 9296 fmul.x ADJFACT(%a6),%fp0 # FINAL ADJUSTMENT 9297 bra t_catch 9297 bra t_catch 9298 9298 9299 global stentoxd 9299 global stentoxd 9300 stentoxd: 9300 stentoxd: 9301 #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED A 9301 #--ENTRY POINT FOR 10**(X) FOR DENORMALIZED ARGUMENT 9302 9302 9303 fmov.l %d0,%fpcr 9303 fmov.l %d0,%fpcr # set user's rounding mode/precision 9304 fmov.s &0x3F800000,%fp0 9304 fmov.s &0x3F800000,%fp0 # RETURN 1 + X 9305 mov.l (%a0),%d1 9305 mov.l (%a0),%d1 9306 or.l &0x00800001,%d1 9306 or.l &0x00800001,%d1 9307 fadd.s %d1,%fp0 9307 fadd.s %d1,%fp0 9308 bra t_pinx2 9308 bra t_pinx2 9309 9309 9310 ############################################# 9310 ######################################################################### 9311 # smovcr(): returns the ROM constant at the o 9311 # smovcr(): returns the ROM constant at the offset specified in d1 # 9312 # rounded to the mode and precision 9312 # rounded to the mode and precision specified in d0. # 9313 # 9313 # # 9314 # INPUT ************************************* 9314 # INPUT *************************************************************** # 9315 # d0 = rnd prec,mode 9315 # d0 = rnd prec,mode # 9316 # d1 = ROM offset 9316 # d1 = ROM offset # 9317 # 9317 # # 9318 # OUTPUT ************************************ 9318 # OUTPUT ************************************************************** # 9319 # fp0 = the ROM constant rounded to the 9319 # fp0 = the ROM constant rounded to the user's rounding mode,prec # 9320 # 9320 # # 9321 ############################################# 9321 ######################################################################### 9322 9322 9323 global smovcr 9323 global smovcr 9324 smovcr: 9324 smovcr: 9325 mov.l %d1,-(%sp) 9325 mov.l %d1,-(%sp) # save rom offset for a sec 9326 9326 9327 lsr.b &0x4,%d0 9327 lsr.b &0x4,%d0 # shift ctrl bits to lo 9328 mov.l %d0,%d1 9328 mov.l %d0,%d1 # make a copy 9329 andi.w &0x3,%d1 9329 andi.w &0x3,%d1 # extract rnd mode 9330 andi.w &0xc,%d0 9330 andi.w &0xc,%d0 # extract rnd prec 9331 swap %d0 9331 swap %d0 # put rnd prec in hi 9332 mov.w %d1,%d0 9332 mov.w %d1,%d0 # put rnd mode in lo 9333 9333 9334 mov.l (%sp)+,%d1 9334 mov.l (%sp)+,%d1 # get rom offset 9335 9335 9336 # 9336 # 9337 # check range of offset 9337 # check range of offset 9338 # 9338 # 9339 tst.b %d1 9339 tst.b %d1 # if zero, offset is to pi 9340 beq.b pi_tbl 9340 beq.b pi_tbl # it is pi 9341 cmpi.b %d1,&0x0a 9341 cmpi.b %d1,&0x0a # check range $01 - $0a 9342 ble.b z_val 9342 ble.b z_val # if in this range, return zero 9343 cmpi.b %d1,&0x0e 9343 cmpi.b %d1,&0x0e # check range $0b - $0e 9344 ble.b sm_tbl 9344 ble.b sm_tbl # valid constants in this range 9345 cmpi.b %d1,&0x2f 9345 cmpi.b %d1,&0x2f # check range $10 - $2f 9346 ble.b z_val 9346 ble.b z_val # if in this range, return zero 9347 cmpi.b %d1,&0x3f 9347 cmpi.b %d1,&0x3f # check range $30 - $3f 9348 ble.b bg_tbl 9348 ble.b bg_tbl # valid constants in this range 9349 9349 9350 z_val: 9350 z_val: 9351 bra.l ld_pzero 9351 bra.l ld_pzero # return a zero 9352 9352 9353 # 9353 # 9354 # the answer is PI rounded to the proper prec 9354 # the answer is PI rounded to the proper precision. 9355 # 9355 # 9356 # fetch a pointer to the answer table relatin 9356 # fetch a pointer to the answer table relating to the proper rounding 9357 # precision. 9357 # precision. 9358 # 9358 # 9359 pi_tbl: 9359 pi_tbl: 9360 tst.b %d0 9360 tst.b %d0 # is rmode RN? 9361 bne.b pi_not_rn 9361 bne.b pi_not_rn # no 9362 pi_rn: 9362 pi_rn: 9363 lea.l PIRN(%pc),%a0 9363 lea.l PIRN(%pc),%a0 # yes; load PI RN table addr 9364 bra.w set_finx 9364 bra.w set_finx 9365 pi_not_rn: 9365 pi_not_rn: 9366 cmpi.b %d0,&rp_mode 9366 cmpi.b %d0,&rp_mode # is rmode RP? 9367 beq.b pi_rp 9367 beq.b pi_rp # yes 9368 pi_rzrm: 9368 pi_rzrm: 9369 lea.l PIRZRM(%pc),%a0 9369 lea.l PIRZRM(%pc),%a0 # no; load PI RZ,RM table addr 9370 bra.b set_finx 9370 bra.b set_finx 9371 pi_rp: 9371 pi_rp: 9372 lea.l PIRP(%pc),%a0 9372 lea.l PIRP(%pc),%a0 # load PI RP table addr 9373 bra.b set_finx 9373 bra.b set_finx 9374 9374 9375 # 9375 # 9376 # the answer is one of: 9376 # the answer is one of: 9377 # $0B log10(2) (inexact) 9377 # $0B log10(2) (inexact) 9378 # $0C e (inexact) 9378 # $0C e (inexact) 9379 # $0D log2(e) (inexact) 9379 # $0D log2(e) (inexact) 9380 # $0E log10(e) (exact) 9380 # $0E log10(e) (exact) 9381 # 9381 # 9382 # fetch a pointer to the answer table relatin 9382 # fetch a pointer to the answer table relating to the proper rounding 9383 # precision. 9383 # precision. 9384 # 9384 # 9385 sm_tbl: 9385 sm_tbl: 9386 subi.b &0xb,%d1 9386 subi.b &0xb,%d1 # make offset in 0-4 range 9387 tst.b %d0 9387 tst.b %d0 # is rmode RN? 9388 bne.b sm_not_rn 9388 bne.b sm_not_rn # no 9389 sm_rn: 9389 sm_rn: 9390 lea.l SMALRN(%pc),%a0 9390 lea.l SMALRN(%pc),%a0 # yes; load RN table addr 9391 sm_tbl_cont: 9391 sm_tbl_cont: 9392 cmpi.b %d1,&0x2 9392 cmpi.b %d1,&0x2 # is result log10(e)? 9393 ble.b set_finx 9393 ble.b set_finx # no; answer is inexact 9394 bra.b no_finx 9394 bra.b no_finx # yes; answer is exact 9395 sm_not_rn: 9395 sm_not_rn: 9396 cmpi.b %d0,&rp_mode 9396 cmpi.b %d0,&rp_mode # is rmode RP? 9397 beq.b sm_rp 9397 beq.b sm_rp # yes 9398 sm_rzrm: 9398 sm_rzrm: 9399 lea.l SMALRZRM(%pc),%a0 9399 lea.l SMALRZRM(%pc),%a0 # no; load RZ,RM table addr 9400 bra.b sm_tbl_cont 9400 bra.b sm_tbl_cont 9401 sm_rp: 9401 sm_rp: 9402 lea.l SMALRP(%pc),%a0 9402 lea.l SMALRP(%pc),%a0 # load RP table addr 9403 bra.b sm_tbl_cont 9403 bra.b sm_tbl_cont 9404 9404 9405 # 9405 # 9406 # the answer is one of: 9406 # the answer is one of: 9407 # $30 ln(2) (inexact) 9407 # $30 ln(2) (inexact) 9408 # $31 ln(10) (inexact) 9408 # $31 ln(10) (inexact) 9409 # $32 10^0 (exact) 9409 # $32 10^0 (exact) 9410 # $33 10^1 (exact) 9410 # $33 10^1 (exact) 9411 # $34 10^2 (exact) 9411 # $34 10^2 (exact) 9412 # $35 10^4 (exact) 9412 # $35 10^4 (exact) 9413 # $36 10^8 (exact) 9413 # $36 10^8 (exact) 9414 # $37 10^16 (exact) 9414 # $37 10^16 (exact) 9415 # $38 10^32 (inexact) 9415 # $38 10^32 (inexact) 9416 # $39 10^64 (inexact) 9416 # $39 10^64 (inexact) 9417 # $3A 10^128 (inexact) 9417 # $3A 10^128 (inexact) 9418 # $3B 10^256 (inexact) 9418 # $3B 10^256 (inexact) 9419 # $3C 10^512 (inexact) 9419 # $3C 10^512 (inexact) 9420 # $3D 10^1024 (inexact) 9420 # $3D 10^1024 (inexact) 9421 # $3E 10^2048 (inexact) 9421 # $3E 10^2048 (inexact) 9422 # $3F 10^4096 (inexact) 9422 # $3F 10^4096 (inexact) 9423 # 9423 # 9424 # fetch a pointer to the answer table relatin 9424 # fetch a pointer to the answer table relating to the proper rounding 9425 # precision. 9425 # precision. 9426 # 9426 # 9427 bg_tbl: 9427 bg_tbl: 9428 subi.b &0x30,%d1 9428 subi.b &0x30,%d1 # make offset in 0-f range 9429 tst.b %d0 9429 tst.b %d0 # is rmode RN? 9430 bne.b bg_not_rn 9430 bne.b bg_not_rn # no 9431 bg_rn: 9431 bg_rn: 9432 lea.l BIGRN(%pc),%a0 9432 lea.l BIGRN(%pc),%a0 # yes; load RN table addr 9433 bg_tbl_cont: 9433 bg_tbl_cont: 9434 cmpi.b %d1,&0x1 9434 cmpi.b %d1,&0x1 # is offset <= $31? 9435 ble.b set_finx 9435 ble.b set_finx # yes; answer is inexact 9436 cmpi.b %d1,&0x7 9436 cmpi.b %d1,&0x7 # is $32 <= offset <= $37? 9437 ble.b no_finx 9437 ble.b no_finx # yes; answer is exact 9438 bra.b set_finx 9438 bra.b set_finx # no; answer is inexact 9439 bg_not_rn: 9439 bg_not_rn: 9440 cmpi.b %d0,&rp_mode 9440 cmpi.b %d0,&rp_mode # is rmode RP? 9441 beq.b bg_rp 9441 beq.b bg_rp # yes 9442 bg_rzrm: 9442 bg_rzrm: 9443 lea.l BIGRZRM(%pc),%a0 9443 lea.l BIGRZRM(%pc),%a0 # no; load RZ,RM table addr 9444 bra.b bg_tbl_cont 9444 bra.b bg_tbl_cont 9445 bg_rp: 9445 bg_rp: 9446 lea.l BIGRP(%pc),%a0 9446 lea.l BIGRP(%pc),%a0 # load RP table addr 9447 bra.b bg_tbl_cont 9447 bra.b bg_tbl_cont 9448 9448 9449 # answer is inexact, so set INEX2 and AINEX i 9449 # answer is inexact, so set INEX2 and AINEX in the user's FPSR. 9450 set_finx: 9450 set_finx: 9451 ori.l &inx2a_mask,USER_FPSR 9451 ori.l &inx2a_mask,USER_FPSR(%a6) # set INEX2/AINEX 9452 no_finx: 9452 no_finx: 9453 mulu.w &0xc,%d1 9453 mulu.w &0xc,%d1 # offset points into tables 9454 swap %d0 9454 swap %d0 # put rnd prec in lo word 9455 tst.b %d0 9455 tst.b %d0 # is precision extended? 9456 9456 9457 bne.b not_ext 9457 bne.b not_ext # if xprec, do not call round 9458 9458 9459 # Precision is extended 9459 # Precision is extended 9460 fmovm.x (%a0,%d1.w),&0x80 9460 fmovm.x (%a0,%d1.w),&0x80 # return result in fp0 9461 rts 9461 rts 9462 9462 9463 # Precision is single or double 9463 # Precision is single or double 9464 not_ext: 9464 not_ext: 9465 swap %d0 9465 swap %d0 # rnd prec in upper word 9466 9466 9467 # call round() to round the answer to the pro 9467 # call round() to round the answer to the proper precision. 9468 # exponents out of range for single or double 9468 # exponents out of range for single or double DO NOT cause underflow 9469 # or overflow. 9469 # or overflow. 9470 mov.w 0x0(%a0,%d1.w),FP_SCR 9470 mov.w 0x0(%a0,%d1.w),FP_SCR1_EX(%a6) # load first word 9471 mov.l 0x4(%a0,%d1.w),FP_SCR 9471 mov.l 0x4(%a0,%d1.w),FP_SCR1_HI(%a6) # load second word 9472 mov.l 0x8(%a0,%d1.w),FP_SCR 9472 mov.l 0x8(%a0,%d1.w),FP_SCR1_LO(%a6) # load third word 9473 mov.l %d0,%d1 9473 mov.l %d0,%d1 9474 clr.l %d0 9474 clr.l %d0 # clear g,r,s 9475 lea FP_SCR1(%a6),%a0 9475 lea FP_SCR1(%a6),%a0 # pass ptr to answer 9476 clr.w LOCAL_SGN(%a0) 9476 clr.w LOCAL_SGN(%a0) # sign always positive 9477 bsr.l _round 9477 bsr.l _round # round the mantissa 9478 9478 9479 fmovm.x (%a0),&0x80 9479 fmovm.x (%a0),&0x80 # return rounded result in fp0 9480 rts 9480 rts 9481 9481 9482 align 0x4 9482 align 0x4 9483 9483 9484 PIRN: long 0x40000000,0xc90fdaa2 9484 PIRN: long 0x40000000,0xc90fdaa2,0x2168c235 # pi 9485 PIRZRM: long 0x40000000,0xc90fdaa2 9485 PIRZRM: long 0x40000000,0xc90fdaa2,0x2168c234 # pi 9486 PIRP: long 0x40000000,0xc90fdaa2 9486 PIRP: long 0x40000000,0xc90fdaa2,0x2168c235 # pi 9487 9487 9488 SMALRN: long 0x3ffd0000,0x9a209a84 9488 SMALRN: long 0x3ffd0000,0x9a209a84,0xfbcff798 # log10(2) 9489 long 0x40000000,0xadf85458 9489 long 0x40000000,0xadf85458,0xa2bb4a9a # e 9490 long 0x3fff0000,0xb8aa3b29 9490 long 0x3fff0000,0xb8aa3b29,0x5c17f0bc # log2(e) 9491 long 0x3ffd0000,0xde5bd8a9 9491 long 0x3ffd0000,0xde5bd8a9,0x37287195 # log10(e) 9492 long 0x00000000,0x00000000 9492 long 0x00000000,0x00000000,0x00000000 # 0.0 9493 9493 9494 SMALRZRM: 9494 SMALRZRM: 9495 long 0x3ffd0000,0x9a209a84 9495 long 0x3ffd0000,0x9a209a84,0xfbcff798 # log10(2) 9496 long 0x40000000,0xadf85458 9496 long 0x40000000,0xadf85458,0xa2bb4a9a # e 9497 long 0x3fff0000,0xb8aa3b29 9497 long 0x3fff0000,0xb8aa3b29,0x5c17f0bb # log2(e) 9498 long 0x3ffd0000,0xde5bd8a9 9498 long 0x3ffd0000,0xde5bd8a9,0x37287195 # log10(e) 9499 long 0x00000000,0x00000000 9499 long 0x00000000,0x00000000,0x00000000 # 0.0 9500 9500 9501 SMALRP: long 0x3ffd0000,0x9a209a84 9501 SMALRP: long 0x3ffd0000,0x9a209a84,0xfbcff799 # log10(2) 9502 long 0x40000000,0xadf85458 9502 long 0x40000000,0xadf85458,0xa2bb4a9b # e 9503 long 0x3fff0000,0xb8aa3b29 9503 long 0x3fff0000,0xb8aa3b29,0x5c17f0bc # log2(e) 9504 long 0x3ffd0000,0xde5bd8a9 9504 long 0x3ffd0000,0xde5bd8a9,0x37287195 # log10(e) 9505 long 0x00000000,0x00000000 9505 long 0x00000000,0x00000000,0x00000000 # 0.0 9506 9506 9507 BIGRN: long 0x3ffe0000,0xb17217f7 9507 BIGRN: long 0x3ffe0000,0xb17217f7,0xd1cf79ac # ln(2) 9508 long 0x40000000,0x935d8ddd 9508 long 0x40000000,0x935d8ddd,0xaaa8ac17 # ln(10) 9509 9509 9510 long 0x3fff0000,0x80000000 9510 long 0x3fff0000,0x80000000,0x00000000 # 10 ^ 0 9511 long 0x40020000,0xA0000000 9511 long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1 9512 long 0x40050000,0xC8000000 9512 long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2 9513 long 0x400C0000,0x9C400000 9513 long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4 9514 long 0x40190000,0xBEBC2000 9514 long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8 9515 long 0x40340000,0x8E1BC9BF 9515 long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16 9516 long 0x40690000,0x9DC5ADA8 9516 long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32 9517 long 0x40D30000,0xC2781F49 9517 long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64 9518 long 0x41A80000,0x93BA47C9 9518 long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128 9519 long 0x43510000,0xAA7EEBFB 9519 long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256 9520 long 0x46A30000,0xE319A0AE 9520 long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512 9521 long 0x4D480000,0xC9767586 9521 long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024 9522 long 0x5A920000,0x9E8B3B5D 9522 long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048 9523 long 0x75250000,0xC4605202 9523 long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096 9524 9524 9525 BIGRZRM: 9525 BIGRZRM: 9526 long 0x3ffe0000,0xb17217f7 9526 long 0x3ffe0000,0xb17217f7,0xd1cf79ab # ln(2) 9527 long 0x40000000,0x935d8ddd 9527 long 0x40000000,0x935d8ddd,0xaaa8ac16 # ln(10) 9528 9528 9529 long 0x3fff0000,0x80000000 9529 long 0x3fff0000,0x80000000,0x00000000 # 10 ^ 0 9530 long 0x40020000,0xA0000000 9530 long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1 9531 long 0x40050000,0xC8000000 9531 long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2 9532 long 0x400C0000,0x9C400000 9532 long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4 9533 long 0x40190000,0xBEBC2000 9533 long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8 9534 long 0x40340000,0x8E1BC9BF 9534 long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16 9535 long 0x40690000,0x9DC5ADA8 9535 long 0x40690000,0x9DC5ADA8,0x2B70B59D # 10 ^ 32 9536 long 0x40D30000,0xC2781F49 9536 long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64 9537 long 0x41A80000,0x93BA47C9 9537 long 0x41A80000,0x93BA47C9,0x80E98CDF # 10 ^ 128 9538 long 0x43510000,0xAA7EEBFB 9538 long 0x43510000,0xAA7EEBFB,0x9DF9DE8D # 10 ^ 256 9539 long 0x46A30000,0xE319A0AE 9539 long 0x46A30000,0xE319A0AE,0xA60E91C6 # 10 ^ 512 9540 long 0x4D480000,0xC9767586 9540 long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024 9541 long 0x5A920000,0x9E8B3B5D 9541 long 0x5A920000,0x9E8B3B5D,0xC53D5DE4 # 10 ^ 2048 9542 long 0x75250000,0xC4605202 9542 long 0x75250000,0xC4605202,0x8A20979A # 10 ^ 4096 9543 9543 9544 BIGRP: 9544 BIGRP: 9545 long 0x3ffe0000,0xb17217f7 9545 long 0x3ffe0000,0xb17217f7,0xd1cf79ac # ln(2) 9546 long 0x40000000,0x935d8ddd 9546 long 0x40000000,0x935d8ddd,0xaaa8ac17 # ln(10) 9547 9547 9548 long 0x3fff0000,0x80000000 9548 long 0x3fff0000,0x80000000,0x00000000 # 10 ^ 0 9549 long 0x40020000,0xA0000000 9549 long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1 9550 long 0x40050000,0xC8000000 9550 long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2 9551 long 0x400C0000,0x9C400000 9551 long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4 9552 long 0x40190000,0xBEBC2000 9552 long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8 9553 long 0x40340000,0x8E1BC9BF 9553 long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16 9554 long 0x40690000,0x9DC5ADA8 9554 long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32 9555 long 0x40D30000,0xC2781F49 9555 long 0x40D30000,0xC2781F49,0xFFCFA6D6 # 10 ^ 64 9556 long 0x41A80000,0x93BA47C9 9556 long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128 9557 long 0x43510000,0xAA7EEBFB 9557 long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256 9558 long 0x46A30000,0xE319A0AE 9558 long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512 9559 long 0x4D480000,0xC9767586 9559 long 0x4D480000,0xC9767586,0x81750C18 # 10 ^ 1024 9560 long 0x5A920000,0x9E8B3B5D 9560 long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048 9561 long 0x75250000,0xC4605202 9561 long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096 9562 9562 9563 ############################################# 9563 ######################################################################### 9564 # sscale(): computes the destination operand 9564 # sscale(): computes the destination operand scaled by the source # 9565 # operand. If the absoulute value o 9565 # operand. If the absoulute value of the source operand is # 9566 # >= 2^14, an overflow or underflow 9566 # >= 2^14, an overflow or underflow is returned. # 9567 # 9567 # # 9568 # INPUT ************************************* 9568 # INPUT *************************************************************** # 9569 # a0 = pointer to double-extended sour 9569 # a0 = pointer to double-extended source operand X # 9570 # a1 = pointer to double-extended dest 9570 # a1 = pointer to double-extended destination operand Y # 9571 # 9571 # # 9572 # OUTPUT ************************************ 9572 # OUTPUT ************************************************************** # 9573 # fp0 = scale(X,Y) 9573 # fp0 = scale(X,Y) # 9574 # 9574 # # 9575 ############################################# 9575 ######################################################################### 9576 9576 9577 set SIGN, L_SCR1 9577 set SIGN, L_SCR1 9578 9578 9579 global sscale 9579 global sscale 9580 sscale: 9580 sscale: 9581 mov.l %d0,-(%sp) 9581 mov.l %d0,-(%sp) # store off ctrl bits for now 9582 9582 9583 mov.w DST_EX(%a1),%d1 9583 mov.w DST_EX(%a1),%d1 # get dst exponent 9584 smi.b SIGN(%a6) 9584 smi.b SIGN(%a6) # use SIGN to hold dst sign 9585 andi.l &0x00007fff,%d1 9585 andi.l &0x00007fff,%d1 # strip sign from dst exp 9586 9586 9587 mov.w SRC_EX(%a0),%d0 9587 mov.w SRC_EX(%a0),%d0 # check src bounds 9588 andi.w &0x7fff,%d0 9588 andi.w &0x7fff,%d0 # clr src sign bit 9589 cmpi.w %d0,&0x3fff 9589 cmpi.w %d0,&0x3fff # is src ~ ZERO? 9590 blt.w src_small 9590 blt.w src_small # yes 9591 cmpi.w %d0,&0x400c 9591 cmpi.w %d0,&0x400c # no; is src too big? 9592 bgt.w src_out 9592 bgt.w src_out # yes 9593 9593 9594 # 9594 # 9595 # Source is within 2^14 range. 9595 # Source is within 2^14 range. 9596 # 9596 # 9597 src_ok: 9597 src_ok: 9598 fintrz.x SRC(%a0),%fp0 9598 fintrz.x SRC(%a0),%fp0 # calc int of src 9599 fmov.l %fp0,%d0 9599 fmov.l %fp0,%d0 # int src to d0 9600 # don't want any accrued bits from the fintrz 9600 # don't want any accrued bits from the fintrz showing up later since 9601 # we may need to read the fpsr for the last f 9601 # we may need to read the fpsr for the last fp op in t_catch2(). 9602 fmov.l &0x0,%fpsr 9602 fmov.l &0x0,%fpsr 9603 9603 9604 tst.b DST_HI(%a1) 9604 tst.b DST_HI(%a1) # is dst denormalized? 9605 bmi.b sok_norm 9605 bmi.b sok_norm 9606 9606 9607 # the dst is a DENORM. normalize the DENORM a 9607 # the dst is a DENORM. normalize the DENORM and add the adjustment to 9608 # the src value. then, jump to the norm part 9608 # the src value. then, jump to the norm part of the routine. 9609 sok_dnrm: 9609 sok_dnrm: 9610 mov.l %d0,-(%sp) 9610 mov.l %d0,-(%sp) # save src for now 9611 9611 9612 mov.w DST_EX(%a1),FP_SCR0_E 9612 mov.w DST_EX(%a1),FP_SCR0_EX(%a6) # make a copy 9613 mov.l DST_HI(%a1),FP_SCR0_H 9613 mov.l DST_HI(%a1),FP_SCR0_HI(%a6) 9614 mov.l DST_LO(%a1),FP_SCR0_L 9614 mov.l DST_LO(%a1),FP_SCR0_LO(%a6) 9615 9615 9616 lea FP_SCR0(%a6),%a0 9616 lea FP_SCR0(%a6),%a0 # pass ptr to DENORM 9617 bsr.l norm 9617 bsr.l norm # normalize the DENORM 9618 neg.l %d0 9618 neg.l %d0 9619 add.l (%sp)+,%d0 9619 add.l (%sp)+,%d0 # add adjustment to src 9620 9620 9621 fmovm.x FP_SCR0(%a6),&0x80 9621 fmovm.x FP_SCR0(%a6),&0x80 # load normalized DENORM 9622 9622 9623 cmpi.w %d0,&-0x3fff 9623 cmpi.w %d0,&-0x3fff # is the shft amt really low? 9624 bge.b sok_norm2 9624 bge.b sok_norm2 # thank goodness no 9625 9625 9626 # the multiply factor that we're trying to cr 9626 # the multiply factor that we're trying to create should be a denorm 9627 # for the multiply to work. Therefore, we're 9627 # for the multiply to work. Therefore, we're going to actually do a 9628 # multiply with a denorm which will cause an 9628 # multiply with a denorm which will cause an unimplemented data type 9629 # exception to be put into the machine which 9629 # exception to be put into the machine which will be caught and corrected 9630 # later. we don't do this with the DENORMs ab 9630 # later. we don't do this with the DENORMs above because this method 9631 # is slower. but, don't fret, I don't see it 9631 # is slower. but, don't fret, I don't see it being used much either. 9632 fmov.l (%sp)+,%fpcr 9632 fmov.l (%sp)+,%fpcr # restore user fpcr 9633 mov.l &0x80000000,%d1 9633 mov.l &0x80000000,%d1 # load normalized mantissa 9634 subi.l &-0x3fff,%d0 9634 subi.l &-0x3fff,%d0 # how many should we shift? 9635 neg.l %d0 9635 neg.l %d0 # make it positive 9636 cmpi.b %d0,&0x20 9636 cmpi.b %d0,&0x20 # is it > 32? 9637 bge.b sok_dnrm_32 9637 bge.b sok_dnrm_32 # yes 9638 lsr.l %d0,%d1 9638 lsr.l %d0,%d1 # no; bit stays in upper lw 9639 clr.l -(%sp) 9639 clr.l -(%sp) # insert zero low mantissa 9640 mov.l %d1,-(%sp) 9640 mov.l %d1,-(%sp) # insert new high mantissa 9641 clr.l -(%sp) 9641 clr.l -(%sp) # make zero exponent 9642 bra.b sok_norm_cont 9642 bra.b sok_norm_cont 9643 sok_dnrm_32: 9643 sok_dnrm_32: 9644 subi.b &0x20,%d0 9644 subi.b &0x20,%d0 # get shift count 9645 lsr.l %d0,%d1 9645 lsr.l %d0,%d1 # make low mantissa longword 9646 mov.l %d1,-(%sp) 9646 mov.l %d1,-(%sp) # insert new low mantissa 9647 clr.l -(%sp) 9647 clr.l -(%sp) # insert zero high mantissa 9648 clr.l -(%sp) 9648 clr.l -(%sp) # make zero exponent 9649 bra.b sok_norm_cont 9649 bra.b sok_norm_cont 9650 9650 9651 # the src will force the dst to a DENORM valu 9651 # the src will force the dst to a DENORM value or worse. so, let's 9652 # create an fp multiply that will create the 9652 # create an fp multiply that will create the result. 9653 sok_norm: 9653 sok_norm: 9654 fmovm.x DST(%a1),&0x80 9654 fmovm.x DST(%a1),&0x80 # load fp0 with normalized src 9655 sok_norm2: 9655 sok_norm2: 9656 fmov.l (%sp)+,%fpcr 9656 fmov.l (%sp)+,%fpcr # restore user fpcr 9657 9657 9658 addi.w &0x3fff,%d0 9658 addi.w &0x3fff,%d0 # turn src amt into exp value 9659 swap %d0 9659 swap %d0 # put exponent in high word 9660 clr.l -(%sp) 9660 clr.l -(%sp) # insert new exponent 9661 mov.l &0x80000000,-(%sp) 9661 mov.l &0x80000000,-(%sp) # insert new high mantissa 9662 mov.l %d0,-(%sp) 9662 mov.l %d0,-(%sp) # insert new lo mantissa 9663 9663 9664 sok_norm_cont: 9664 sok_norm_cont: 9665 fmov.l %fpcr,%d0 9665 fmov.l %fpcr,%d0 # d0 needs fpcr for t_catch2 9666 mov.b &FMUL_OP,%d1 9666 mov.b &FMUL_OP,%d1 # last inst is MUL 9667 fmul.x (%sp)+,%fp0 9667 fmul.x (%sp)+,%fp0 # do the multiply 9668 bra t_catch2 9668 bra t_catch2 # catch any exceptions 9669 9669 9670 # 9670 # 9671 # Source is outside of 2^14 range. Test the 9671 # Source is outside of 2^14 range. Test the sign and branch 9672 # to the appropriate exception handler. 9672 # to the appropriate exception handler. 9673 # 9673 # 9674 src_out: 9674 src_out: 9675 mov.l (%sp)+,%d0 9675 mov.l (%sp)+,%d0 # restore ctrl bits 9676 exg %a0,%a1 9676 exg %a0,%a1 # swap src,dst ptrs 9677 tst.b SRC_EX(%a1) 9677 tst.b SRC_EX(%a1) # is src negative? 9678 bmi t_unfl 9678 bmi t_unfl # yes; underflow 9679 bra t_ovfl_sc 9679 bra t_ovfl_sc # no; overflow 9680 9680 9681 # 9681 # 9682 # The source input is below 1, so we check fo 9682 # The source input is below 1, so we check for denormalized numbers 9683 # and set unfl. 9683 # and set unfl. 9684 # 9684 # 9685 src_small: 9685 src_small: 9686 tst.b DST_HI(%a1) 9686 tst.b DST_HI(%a1) # is dst denormalized? 9687 bpl.b ssmall_done 9687 bpl.b ssmall_done # yes 9688 9688 9689 mov.l (%sp)+,%d0 9689 mov.l (%sp)+,%d0 9690 fmov.l %d0,%fpcr 9690 fmov.l %d0,%fpcr # no; load control bits 9691 mov.b &FMOV_OP,%d1 9691 mov.b &FMOV_OP,%d1 # last inst is MOVE 9692 fmov.x DST(%a1),%fp0 9692 fmov.x DST(%a1),%fp0 # simply return dest 9693 bra t_catch2 9693 bra t_catch2 9694 ssmall_done: 9694 ssmall_done: 9695 mov.l (%sp)+,%d0 9695 mov.l (%sp)+,%d0 # load control bits into d1 9696 mov.l %a1,%a0 9696 mov.l %a1,%a0 # pass ptr to dst 9697 bra t_resdnrm 9697 bra t_resdnrm 9698 9698 9699 ############################################# 9699 ######################################################################### 9700 # smod(): computes the fp MOD of the input va 9700 # smod(): computes the fp MOD of the input values X,Y. # 9701 # srem(): computes the fp (IEEE) REM of the i 9701 # srem(): computes the fp (IEEE) REM of the input values X,Y. # 9702 # 9702 # # 9703 # INPUT ************************************* 9703 # INPUT *************************************************************** # 9704 # a0 = pointer to extended precision in 9704 # a0 = pointer to extended precision input X # 9705 # a1 = pointer to extended precision in 9705 # a1 = pointer to extended precision input Y # 9706 # d0 = round precision,mode 9706 # d0 = round precision,mode # 9707 # 9707 # # 9708 # The input operands X and Y can be eit 9708 # The input operands X and Y can be either normalized or # 9709 # denormalized. 9709 # denormalized. # 9710 # 9710 # # 9711 # OUTPUT ************************************ 9711 # OUTPUT ************************************************************** # 9712 # fp0 = FREM(X,Y) or FMOD(X,Y) 9712 # fp0 = FREM(X,Y) or FMOD(X,Y) # 9713 # 9713 # # 9714 # ALGORITHM ********************************* 9714 # ALGORITHM *********************************************************** # 9715 # 9715 # # 9716 # Step 1. Save and strip signs of X an 9716 # Step 1. Save and strip signs of X and Y: signX := sign(X), # 9717 # signY := sign(Y), X := |X|, 9717 # signY := sign(Y), X := |X|, Y := |Y|, # 9718 # signQ := signX EOR signY. Re 9718 # signQ := signX EOR signY. Record whether MOD or REM # 9719 # is requested. 9719 # is requested. # 9720 # 9720 # # 9721 # Step 2. Set L := expo(X)-expo(Y), k 9721 # Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0. # 9722 # If (L < 0) then 9722 # If (L < 0) then # 9723 # R := X, go to Step 4. 9723 # R := X, go to Step 4. # 9724 # else 9724 # else # 9725 # R := 2^(-L)X, j := L. 9725 # R := 2^(-L)X, j := L. # 9726 # endif 9726 # endif # 9727 # 9727 # # 9728 # Step 3. Perform MOD(X,Y) 9728 # Step 3. Perform MOD(X,Y) # 9729 # 3.1 If R = Y, go to Step 9. 9729 # 3.1 If R = Y, go to Step 9. # 9730 # 3.2 If R > Y, then { R := R - Y, 9730 # 3.2 If R > Y, then { R := R - Y, Q := Q + 1} # 9731 # 3.3 If j = 0, go to Step 4. 9731 # 3.3 If j = 0, go to Step 4. # 9732 # 3.4 k := k + 1, j := j - 1, Q := 9732 # 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to # 9733 # Step 3.1. 9733 # Step 3.1. # 9734 # 9734 # # 9735 # Step 4. At this point, R = X - QY = 9735 # Step 4. At this point, R = X - QY = MOD(X,Y). Set # 9736 # Last_Subtract := false (used 9736 # Last_Subtract := false (used in Step 7 below). If # 9737 # MOD is requested, go to Step 9737 # MOD is requested, go to Step 6. # 9738 # 9738 # # 9739 # Step 5. R = MOD(X,Y), but REM(X,Y) i 9739 # Step 5. R = MOD(X,Y), but REM(X,Y) is requested. # 9740 # 5.1 If R < Y/2, then R = MOD(X,Y 9740 # 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to # 9741 # Step 6. 9741 # Step 6. # 9742 # 5.2 If R > Y/2, then { set Last_ 9742 # 5.2 If R > Y/2, then { set Last_Subtract := true, # 9743 # Q := Q + 1, Y := signY*Y }. 9743 # Q := Q + 1, Y := signY*Y }. Go to Step 6. # 9744 # 5.3 This is the tricky case of R 9744 # 5.3 This is the tricky case of R = Y/2. If Q is odd, # 9745 # then { Q := Q + 1, signX := 9745 # then { Q := Q + 1, signX := -signX }. # 9746 # 9746 # # 9747 # Step 6. R := signX*R. 9747 # Step 6. R := signX*R. # 9748 # 9748 # # 9749 # Step 7. If Last_Subtract = true, R : 9749 # Step 7. If Last_Subtract = true, R := R - Y. # 9750 # 9750 # # 9751 # Step 8. Return signQ, last 7 bits of 9751 # Step 8. Return signQ, last 7 bits of Q, and R as required. # 9752 # 9752 # # 9753 # Step 9. At this point, R = 2^(-j)*X 9753 # Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus, # 9754 # X = 2^(j)*(Q+1)Y. set Q := 2 9754 # X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1), # 9755 # R := 0. Return signQ, last 7 9755 # R := 0. Return signQ, last 7 bits of Q, and R. # 9756 # 9756 # # 9757 ############################################# 9757 ######################################################################### 9758 9758 9759 set Mod_Flag,L_SCR3 9759 set Mod_Flag,L_SCR3 9760 set Sc_Flag,L_SCR3+1 9760 set Sc_Flag,L_SCR3+1 9761 9761 9762 set SignY,L_SCR2 9762 set SignY,L_SCR2 9763 set SignX,L_SCR2+2 9763 set SignX,L_SCR2+2 9764 set SignQ,L_SCR3+2 9764 set SignQ,L_SCR3+2 9765 9765 9766 set Y,FP_SCR0 9766 set Y,FP_SCR0 9767 set Y_Hi,Y+4 9767 set Y_Hi,Y+4 9768 set Y_Lo,Y+8 9768 set Y_Lo,Y+8 9769 9769 9770 set R,FP_SCR1 9770 set R,FP_SCR1 9771 set R_Hi,R+4 9771 set R_Hi,R+4 9772 set R_Lo,R+8 9772 set R_Lo,R+8 9773 9773 9774 Scale: 9774 Scale: 9775 long 0x00010000,0x80000000 9775 long 0x00010000,0x80000000,0x00000000,0x00000000 9776 9776 9777 global smod 9777 global smod 9778 smod: 9778 smod: 9779 clr.b FPSR_QBYTE(%a6) 9779 clr.b FPSR_QBYTE(%a6) 9780 mov.l %d0,-(%sp) 9780 mov.l %d0,-(%sp) # save ctrl bits 9781 clr.b Mod_Flag(%a6) 9781 clr.b Mod_Flag(%a6) 9782 bra.b Mod_Rem 9782 bra.b Mod_Rem 9783 9783 9784 global srem 9784 global srem 9785 srem: 9785 srem: 9786 clr.b FPSR_QBYTE(%a6) 9786 clr.b FPSR_QBYTE(%a6) 9787 mov.l %d0,-(%sp) 9787 mov.l %d0,-(%sp) # save ctrl bits 9788 mov.b &0x1,Mod_Flag(%a6) 9788 mov.b &0x1,Mod_Flag(%a6) 9789 9789 9790 Mod_Rem: 9790 Mod_Rem: 9791 #..Save sign of X and Y 9791 #..Save sign of X and Y 9792 movm.l &0x3f00,-(%sp) 9792 movm.l &0x3f00,-(%sp) # save data registers 9793 mov.w SRC_EX(%a0),%d3 9793 mov.w SRC_EX(%a0),%d3 9794 mov.w %d3,SignY(%a6) 9794 mov.w %d3,SignY(%a6) 9795 and.l &0x00007FFF,%d3 9795 and.l &0x00007FFF,%d3 # Y := |Y| 9796 9796 9797 # 9797 # 9798 mov.l SRC_HI(%a0),%d4 9798 mov.l SRC_HI(%a0),%d4 9799 mov.l SRC_LO(%a0),%d5 9799 mov.l SRC_LO(%a0),%d5 # (D3,D4,D5) is |Y| 9800 9800 9801 tst.l %d3 9801 tst.l %d3 9802 bne.b Y_Normal 9802 bne.b Y_Normal 9803 9803 9804 mov.l &0x00003FFE,%d3 9804 mov.l &0x00003FFE,%d3 # $3FFD + 1 9805 tst.l %d4 9805 tst.l %d4 9806 bne.b HiY_not0 9806 bne.b HiY_not0 9807 9807 9808 HiY_0: 9808 HiY_0: 9809 mov.l %d5,%d4 9809 mov.l %d5,%d4 9810 clr.l %d5 9810 clr.l %d5 9811 sub.l &32,%d3 9811 sub.l &32,%d3 9812 clr.l %d6 9812 clr.l %d6 9813 bfffo %d4{&0:&32},%d6 9813 bfffo %d4{&0:&32},%d6 9814 lsl.l %d6,%d4 9814 lsl.l %d6,%d4 9815 sub.l %d6,%d3 9815 sub.l %d6,%d3 # (D3,D4,D5) is normalized 9816 # 9816 # ...with bias $7FFD 9817 bra.b Chk_X 9817 bra.b Chk_X 9818 9818 9819 HiY_not0: 9819 HiY_not0: 9820 clr.l %d6 9820 clr.l %d6 9821 bfffo %d4{&0:&32},%d6 9821 bfffo %d4{&0:&32},%d6 9822 sub.l %d6,%d3 9822 sub.l %d6,%d3 9823 lsl.l %d6,%d4 9823 lsl.l %d6,%d4 9824 mov.l %d5,%d7 9824 mov.l %d5,%d7 # a copy of D5 9825 lsl.l %d6,%d5 9825 lsl.l %d6,%d5 9826 neg.l %d6 9826 neg.l %d6 9827 add.l &32,%d6 9827 add.l &32,%d6 9828 lsr.l %d6,%d7 9828 lsr.l %d6,%d7 9829 or.l %d7,%d4 9829 or.l %d7,%d4 # (D3,D4,D5) normalized 9830 # ...wi 9830 # ...with bias $7FFD 9831 bra.b Chk_X 9831 bra.b Chk_X 9832 9832 9833 Y_Normal: 9833 Y_Normal: 9834 add.l &0x00003FFE,%d3 9834 add.l &0x00003FFE,%d3 # (D3,D4,D5) normalized 9835 # ...wi 9835 # ...with bias $7FFD 9836 9836 9837 Chk_X: 9837 Chk_X: 9838 mov.w DST_EX(%a1),%d0 9838 mov.w DST_EX(%a1),%d0 9839 mov.w %d0,SignX(%a6) 9839 mov.w %d0,SignX(%a6) 9840 mov.w SignY(%a6),%d1 9840 mov.w SignY(%a6),%d1 9841 eor.l %d0,%d1 9841 eor.l %d0,%d1 9842 and.l &0x00008000,%d1 9842 and.l &0x00008000,%d1 9843 mov.w %d1,SignQ(%a6) 9843 mov.w %d1,SignQ(%a6) # sign(Q) obtained 9844 and.l &0x00007FFF,%d0 9844 and.l &0x00007FFF,%d0 9845 mov.l DST_HI(%a1),%d1 9845 mov.l DST_HI(%a1),%d1 9846 mov.l DST_LO(%a1),%d2 9846 mov.l DST_LO(%a1),%d2 # (D0,D1,D2) is |X| 9847 tst.l %d0 9847 tst.l %d0 9848 bne.b X_Normal 9848 bne.b X_Normal 9849 mov.l &0x00003FFE,%d0 9849 mov.l &0x00003FFE,%d0 9850 tst.l %d1 9850 tst.l %d1 9851 bne.b HiX_not0 9851 bne.b HiX_not0 9852 9852 9853 HiX_0: 9853 HiX_0: 9854 mov.l %d2,%d1 9854 mov.l %d2,%d1 9855 clr.l %d2 9855 clr.l %d2 9856 sub.l &32,%d0 9856 sub.l &32,%d0 9857 clr.l %d6 9857 clr.l %d6 9858 bfffo %d1{&0:&32},%d6 9858 bfffo %d1{&0:&32},%d6 9859 lsl.l %d6,%d1 9859 lsl.l %d6,%d1 9860 sub.l %d6,%d0 9860 sub.l %d6,%d0 # (D0,D1,D2) is normalized 9861 # ...wi 9861 # ...with bias $7FFD 9862 bra.b Init 9862 bra.b Init 9863 9863 9864 HiX_not0: 9864 HiX_not0: 9865 clr.l %d6 9865 clr.l %d6 9866 bfffo %d1{&0:&32},%d6 9866 bfffo %d1{&0:&32},%d6 9867 sub.l %d6,%d0 9867 sub.l %d6,%d0 9868 lsl.l %d6,%d1 9868 lsl.l %d6,%d1 9869 mov.l %d2,%d7 9869 mov.l %d2,%d7 # a copy of D2 9870 lsl.l %d6,%d2 9870 lsl.l %d6,%d2 9871 neg.l %d6 9871 neg.l %d6 9872 add.l &32,%d6 9872 add.l &32,%d6 9873 lsr.l %d6,%d7 9873 lsr.l %d6,%d7 9874 or.l %d7,%d1 9874 or.l %d7,%d1 # (D0,D1,D2) normalized 9875 # ...wi 9875 # ...with bias $7FFD 9876 bra.b Init 9876 bra.b Init 9877 9877 9878 X_Normal: 9878 X_Normal: 9879 add.l &0x00003FFE,%d0 9879 add.l &0x00003FFE,%d0 # (D0,D1,D2) normalized 9880 # ...wi 9880 # ...with bias $7FFD 9881 9881 9882 Init: 9882 Init: 9883 # 9883 # 9884 mov.l %d3,L_SCR1(%a6) 9884 mov.l %d3,L_SCR1(%a6) # save biased exp(Y) 9885 mov.l %d0,-(%sp) 9885 mov.l %d0,-(%sp) # save biased exp(X) 9886 sub.l %d3,%d0 9886 sub.l %d3,%d0 # L := expo(X)-expo(Y) 9887 9887 9888 clr.l %d6 9888 clr.l %d6 # D6 := carry <- 0 9889 clr.l %d3 9889 clr.l %d3 # D3 is Q 9890 mov.l &0,%a1 9890 mov.l &0,%a1 # A1 is k; j+k=L, Q=0 9891 9891 9892 #..(Carry,D1,D2) is R 9892 #..(Carry,D1,D2) is R 9893 tst.l %d0 9893 tst.l %d0 9894 bge.b Mod_Loop_pre 9894 bge.b Mod_Loop_pre 9895 9895 9896 #..expo(X) < expo(Y). Thus X = mod(X,Y) 9896 #..expo(X) < expo(Y). Thus X = mod(X,Y) 9897 # 9897 # 9898 mov.l (%sp)+,%d0 9898 mov.l (%sp)+,%d0 # restore d0 9899 bra.w Get_Mod 9899 bra.w Get_Mod 9900 9900 9901 Mod_Loop_pre: 9901 Mod_Loop_pre: 9902 addq.l &0x4,%sp 9902 addq.l &0x4,%sp # erase exp(X) 9903 #..At this point R = 2^(-L)X; Q = 0; k = 0; 9903 #..At this point R = 2^(-L)X; Q = 0; k = 0; and k+j = L 9904 Mod_Loop: 9904 Mod_Loop: 9905 tst.l %d6 9905 tst.l %d6 # test carry bit 9906 bgt.b R_GT_Y 9906 bgt.b R_GT_Y 9907 9907 9908 #..At this point carry = 0, R = (D1,D2), Y = 9908 #..At this point carry = 0, R = (D1,D2), Y = (D4,D5) 9909 cmp.l %d1,%d4 9909 cmp.l %d1,%d4 # compare hi(R) and hi(Y) 9910 bne.b R_NE_Y 9910 bne.b R_NE_Y 9911 cmp.l %d2,%d5 9911 cmp.l %d2,%d5 # compare lo(R) and lo(Y) 9912 bne.b R_NE_Y 9912 bne.b R_NE_Y 9913 9913 9914 #..At this point, R = Y 9914 #..At this point, R = Y 9915 bra.w Rem_is_0 9915 bra.w Rem_is_0 9916 9916 9917 R_NE_Y: 9917 R_NE_Y: 9918 #..use the borrow of the previous compare 9918 #..use the borrow of the previous compare 9919 bcs.b R_LT_Y 9919 bcs.b R_LT_Y # borrow is set iff R < Y 9920 9920 9921 R_GT_Y: 9921 R_GT_Y: 9922 #..If Carry is set, then Y < (Carry,D1,D2) < 9922 #..If Carry is set, then Y < (Carry,D1,D2) < 2Y. Otherwise, Carry = 0 9923 #..and Y < (D1,D2) < 2Y. Either way, perform 9923 #..and Y < (D1,D2) < 2Y. Either way, perform R - Y 9924 sub.l %d5,%d2 9924 sub.l %d5,%d2 # lo(R) - lo(Y) 9925 subx.l %d4,%d1 9925 subx.l %d4,%d1 # hi(R) - hi(Y) 9926 clr.l %d6 9926 clr.l %d6 # clear carry 9927 addq.l &1,%d3 9927 addq.l &1,%d3 # Q := Q + 1 9928 9928 9929 R_LT_Y: 9929 R_LT_Y: 9930 #..At this point, Carry=0, R < Y. R = 2^(k-L) 9930 #..At this point, Carry=0, R < Y. R = 2^(k-L)X - QY; k+j = L; j >= 0. 9931 tst.l %d0 9931 tst.l %d0 # see if j = 0. 9932 beq.b PostLoop 9932 beq.b PostLoop 9933 9933 9934 add.l %d3,%d3 9934 add.l %d3,%d3 # Q := 2Q 9935 add.l %d2,%d2 9935 add.l %d2,%d2 # lo(R) = 2lo(R) 9936 roxl.l &1,%d1 9936 roxl.l &1,%d1 # hi(R) = 2hi(R) + carry 9937 scs %d6 9937 scs %d6 # set Carry if 2(R) overflows 9938 addq.l &1,%a1 9938 addq.l &1,%a1 # k := k+1 9939 subq.l &1,%d0 9939 subq.l &1,%d0 # j := j - 1 9940 #..At this point, R=(Carry,D1,D2) = 2^(k-L)X 9940 #..At this point, R=(Carry,D1,D2) = 2^(k-L)X - QY, j+k=L, j >= 0, R < 2Y. 9941 9941 9942 bra.b Mod_Loop 9942 bra.b Mod_Loop 9943 9943 9944 PostLoop: 9944 PostLoop: 9945 #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - 9945 #..k = L, j = 0, Carry = 0, R = (D1,D2) = X - QY, R < Y. 9946 9946 9947 #..normalize R. 9947 #..normalize R. 9948 mov.l L_SCR1(%a6),%d0 9948 mov.l L_SCR1(%a6),%d0 # new biased expo of R 9949 tst.l %d1 9949 tst.l %d1 9950 bne.b HiR_not0 9950 bne.b HiR_not0 9951 9951 9952 HiR_0: 9952 HiR_0: 9953 mov.l %d2,%d1 9953 mov.l %d2,%d1 9954 clr.l %d2 9954 clr.l %d2 9955 sub.l &32,%d0 9955 sub.l &32,%d0 9956 clr.l %d6 9956 clr.l %d6 9957 bfffo %d1{&0:&32},%d6 9957 bfffo %d1{&0:&32},%d6 9958 lsl.l %d6,%d1 9958 lsl.l %d6,%d1 9959 sub.l %d6,%d0 9959 sub.l %d6,%d0 # (D0,D1,D2) is normalized 9960 # ...wi 9960 # ...with bias $7FFD 9961 bra.b Get_Mod 9961 bra.b Get_Mod 9962 9962 9963 HiR_not0: 9963 HiR_not0: 9964 clr.l %d6 9964 clr.l %d6 9965 bfffo %d1{&0:&32},%d6 9965 bfffo %d1{&0:&32},%d6 9966 bmi.b Get_Mod 9966 bmi.b Get_Mod # already normalized 9967 sub.l %d6,%d0 9967 sub.l %d6,%d0 9968 lsl.l %d6,%d1 9968 lsl.l %d6,%d1 9969 mov.l %d2,%d7 9969 mov.l %d2,%d7 # a copy of D2 9970 lsl.l %d6,%d2 9970 lsl.l %d6,%d2 9971 neg.l %d6 9971 neg.l %d6 9972 add.l &32,%d6 9972 add.l &32,%d6 9973 lsr.l %d6,%d7 9973 lsr.l %d6,%d7 9974 or.l %d7,%d1 9974 or.l %d7,%d1 # (D0,D1,D2) normalized 9975 9975 9976 # 9976 # 9977 Get_Mod: 9977 Get_Mod: 9978 cmp.l %d0,&0x000041FE 9978 cmp.l %d0,&0x000041FE 9979 bge.b No_Scale 9979 bge.b No_Scale 9980 Do_Scale: 9980 Do_Scale: 9981 mov.w %d0,R(%a6) 9981 mov.w %d0,R(%a6) 9982 mov.l %d1,R_Hi(%a6) 9982 mov.l %d1,R_Hi(%a6) 9983 mov.l %d2,R_Lo(%a6) 9983 mov.l %d2,R_Lo(%a6) 9984 mov.l L_SCR1(%a6),%d6 9984 mov.l L_SCR1(%a6),%d6 9985 mov.w %d6,Y(%a6) 9985 mov.w %d6,Y(%a6) 9986 mov.l %d4,Y_Hi(%a6) 9986 mov.l %d4,Y_Hi(%a6) 9987 mov.l %d5,Y_Lo(%a6) 9987 mov.l %d5,Y_Lo(%a6) 9988 fmov.x R(%a6),%fp0 9988 fmov.x R(%a6),%fp0 # no exception 9989 mov.b &1,Sc_Flag(%a6) 9989 mov.b &1,Sc_Flag(%a6) 9990 bra.b ModOrRem 9990 bra.b ModOrRem 9991 No_Scale: 9991 No_Scale: 9992 mov.l %d1,R_Hi(%a6) 9992 mov.l %d1,R_Hi(%a6) 9993 mov.l %d2,R_Lo(%a6) 9993 mov.l %d2,R_Lo(%a6) 9994 sub.l &0x3FFE,%d0 9994 sub.l &0x3FFE,%d0 9995 mov.w %d0,R(%a6) 9995 mov.w %d0,R(%a6) 9996 mov.l L_SCR1(%a6),%d6 9996 mov.l L_SCR1(%a6),%d6 9997 sub.l &0x3FFE,%d6 9997 sub.l &0x3FFE,%d6 9998 mov.l %d6,L_SCR1(%a6) 9998 mov.l %d6,L_SCR1(%a6) 9999 fmov.x R(%a6),%fp0 9999 fmov.x R(%a6),%fp0 10000 mov.w %d6,Y(%a6) 10000 mov.w %d6,Y(%a6) 10001 mov.l %d4,Y_Hi(%a6) 10001 mov.l %d4,Y_Hi(%a6) 10002 mov.l %d5,Y_Lo(%a6) 10002 mov.l %d5,Y_Lo(%a6) 10003 clr.b Sc_Flag(%a6) 10003 clr.b Sc_Flag(%a6) 10004 10004 10005 # 10005 # 10006 ModOrRem: 10006 ModOrRem: 10007 tst.b Mod_Flag(%a6) 10007 tst.b Mod_Flag(%a6) 10008 beq.b Fix_Sign 10008 beq.b Fix_Sign 10009 10009 10010 mov.l L_SCR1(%a6),%d6 10010 mov.l L_SCR1(%a6),%d6 # new biased expo(Y) 10011 subq.l &1,%d6 10011 subq.l &1,%d6 # biased expo(Y/2) 10012 cmp.l %d0,%d6 10012 cmp.l %d0,%d6 10013 blt.b Fix_Sign 10013 blt.b Fix_Sign 10014 bgt.b Last_Sub 10014 bgt.b Last_Sub 10015 10015 10016 cmp.l %d1,%d4 10016 cmp.l %d1,%d4 10017 bne.b Not_EQ 10017 bne.b Not_EQ 10018 cmp.l %d2,%d5 10018 cmp.l %d2,%d5 10019 bne.b Not_EQ 10019 bne.b Not_EQ 10020 bra.w Tie_Case 10020 bra.w Tie_Case 10021 10021 10022 Not_EQ: 10022 Not_EQ: 10023 bcs.b Fix_Sign 10023 bcs.b Fix_Sign 10024 10024 10025 Last_Sub: 10025 Last_Sub: 10026 # 10026 # 10027 fsub.x Y(%a6),%fp0 10027 fsub.x Y(%a6),%fp0 # no exceptions 10028 addq.l &1,%d3 10028 addq.l &1,%d3 # Q := Q + 1 10029 10029 10030 # 10030 # 10031 Fix_Sign: 10031 Fix_Sign: 10032 #..Get sign of X 10032 #..Get sign of X 10033 mov.w SignX(%a6),%d6 10033 mov.w SignX(%a6),%d6 10034 bge.b Get_Q 10034 bge.b Get_Q 10035 fneg.x %fp0 10035 fneg.x %fp0 10036 10036 10037 #..Get Q 10037 #..Get Q 10038 # 10038 # 10039 Get_Q: 10039 Get_Q: 10040 clr.l %d6 10040 clr.l %d6 10041 mov.w SignQ(%a6),%d6 10041 mov.w SignQ(%a6),%d6 # D6 is sign(Q) 10042 mov.l &8,%d7 10042 mov.l &8,%d7 10043 lsr.l %d7,%d6 10043 lsr.l %d7,%d6 10044 and.l &0x0000007F,%d3 10044 and.l &0x0000007F,%d3 # 7 bits of Q 10045 or.l %d6,%d3 10045 or.l %d6,%d3 # sign and bits of Q 10046 # swap %d3 10046 # swap %d3 10047 # fmov.l %fpsr,%d6 10047 # fmov.l %fpsr,%d6 10048 # and.l &0xFF00FFFF,%d6 10048 # and.l &0xFF00FFFF,%d6 10049 # or.l %d3,%d6 10049 # or.l %d3,%d6 10050 # fmov.l %d6,%fpsr 10050 # fmov.l %d6,%fpsr # put Q in fpsr 10051 mov.b %d3,FPSR_QBYTE(%a6) 10051 mov.b %d3,FPSR_QBYTE(%a6) # put Q in fpsr 10052 10052 10053 # 10053 # 10054 Restore: 10054 Restore: 10055 movm.l (%sp)+,&0xfc 10055 movm.l (%sp)+,&0xfc # {%d2-%d7} 10056 mov.l (%sp)+,%d0 10056 mov.l (%sp)+,%d0 10057 fmov.l %d0,%fpcr 10057 fmov.l %d0,%fpcr 10058 tst.b Sc_Flag(%a6) 10058 tst.b Sc_Flag(%a6) 10059 beq.b Finish 10059 beq.b Finish 10060 mov.b &FMUL_OP,%d1 10060 mov.b &FMUL_OP,%d1 # last inst is MUL 10061 fmul.x Scale(%pc),%fp0 10061 fmul.x Scale(%pc),%fp0 # may cause underflow 10062 bra t_catch2 10062 bra t_catch2 10063 # the '040 package did this apparently to se 10063 # the '040 package did this apparently to see if the dst operand for the 10064 # preceding fmul was a denorm. but, it bette 10064 # preceding fmul was a denorm. but, it better not have been since the 10065 # algorithm just got done playing with fp0 a 10065 # algorithm just got done playing with fp0 and expected no exceptions 10066 # as a result. trust me... 10066 # as a result. trust me... 10067 # bra t_avoid_unsupp 10067 # bra t_avoid_unsupp # check for denorm as a 10068 # 10068 # ;result of the scaling 10069 10069 10070 Finish: 10070 Finish: 10071 mov.b &FMOV_OP,%d1 10071 mov.b &FMOV_OP,%d1 # last inst is MOVE 10072 fmov.x %fp0,%fp0 10072 fmov.x %fp0,%fp0 # capture exceptions & round 10073 bra t_catch2 10073 bra t_catch2 10074 10074 10075 Rem_is_0: 10075 Rem_is_0: 10076 #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quo 10076 #..R = 2^(-j)X - Q Y = Y, thus R = 0 and quotient = 2^j (Q+1) 10077 addq.l &1,%d3 10077 addq.l &1,%d3 10078 cmp.l %d0,&8 10078 cmp.l %d0,&8 # D0 is j 10079 bge.b Q_Big 10079 bge.b Q_Big 10080 10080 10081 lsl.l %d0,%d3 10081 lsl.l %d0,%d3 10082 bra.b Set_R_0 10082 bra.b Set_R_0 10083 10083 10084 Q_Big: 10084 Q_Big: 10085 clr.l %d3 10085 clr.l %d3 10086 10086 10087 Set_R_0: 10087 Set_R_0: 10088 fmov.s &0x00000000,%fp0 10088 fmov.s &0x00000000,%fp0 10089 clr.b Sc_Flag(%a6) 10089 clr.b Sc_Flag(%a6) 10090 bra.w Fix_Sign 10090 bra.w Fix_Sign 10091 10091 10092 Tie_Case: 10092 Tie_Case: 10093 #..Check parity of Q 10093 #..Check parity of Q 10094 mov.l %d3,%d6 10094 mov.l %d3,%d6 10095 and.l &0x00000001,%d6 10095 and.l &0x00000001,%d6 10096 tst.l %d6 10096 tst.l %d6 10097 beq.w Fix_Sign 10097 beq.w Fix_Sign # Q is even 10098 10098 10099 #..Q is odd, Q := Q + 1, signX := -signX 10099 #..Q is odd, Q := Q + 1, signX := -signX 10100 addq.l &1,%d3 10100 addq.l &1,%d3 10101 mov.w SignX(%a6),%d6 10101 mov.w SignX(%a6),%d6 10102 eor.l &0x00008000,%d6 10102 eor.l &0x00008000,%d6 10103 mov.w %d6,SignX(%a6) 10103 mov.w %d6,SignX(%a6) 10104 bra.w Fix_Sign 10104 bra.w Fix_Sign 10105 10105 10106 qnan: long 0x7fff0000, 0xffffff 10106 qnan: long 0x7fff0000, 0xffffffff, 0xffffffff 10107 10107 10108 ############################################ 10108 ######################################################################### 10109 # XDEF ************************************* 10109 # XDEF **************************************************************** # 10110 # t_dz(): Handle DZ exception during t 10110 # t_dz(): Handle DZ exception during transcendental emulation. # 10111 # Sets N bit according to sign 10111 # Sets N bit according to sign of source operand. # 10112 # t_dz2(): Handle DZ exception during 10112 # t_dz2(): Handle DZ exception during transcendental emulation. # 10113 # Sets N bit always. 10113 # Sets N bit always. # 10114 # 10114 # # 10115 # XREF ************************************* 10115 # XREF **************************************************************** # 10116 # None 10116 # None # 10117 # 10117 # # 10118 # INPUT ************************************ 10118 # INPUT *************************************************************** # 10119 # a0 = pointer to source operand 10119 # a0 = pointer to source operand # 10120 # 10120 # # 10121 # OUTPUT *********************************** 10121 # OUTPUT ************************************************************** # 10122 # fp0 = default result 10122 # fp0 = default result # 10123 # 10123 # # 10124 # ALGORITHM ******************************** 10124 # ALGORITHM *********************************************************** # 10125 # - Store properly signed INF into fp0 10125 # - Store properly signed INF into fp0. # 10126 # - Set FPSR exception status dz bit, 10126 # - Set FPSR exception status dz bit, ccode inf bit, and # 10127 # accrued dz bit. 10127 # accrued dz bit. # 10128 # 10128 # # 10129 ############################################ 10129 ######################################################################### 10130 10130 10131 global t_dz 10131 global t_dz 10132 t_dz: 10132 t_dz: 10133 tst.b SRC_EX(%a0) 10133 tst.b SRC_EX(%a0) # no; is src negative? 10134 bmi.b t_dz2 10134 bmi.b t_dz2 # yes 10135 10135 10136 dz_pinf: 10136 dz_pinf: 10137 fmov.s &0x7f800000,%fp0 10137 fmov.s &0x7f800000,%fp0 # return +INF in fp0 10138 ori.l &dzinf_mask,USER_FPS 10138 ori.l &dzinf_mask,USER_FPSR(%a6) # set I/DZ/ADZ 10139 rts 10139 rts 10140 10140 10141 global t_dz2 10141 global t_dz2 10142 t_dz2: 10142 t_dz2: 10143 fmov.s &0xff800000,%fp0 10143 fmov.s &0xff800000,%fp0 # return -INF in fp0 10144 ori.l &dzinf_mask+neg_mask 10144 ori.l &dzinf_mask+neg_mask,USER_FPSR(%a6) # set N/I/DZ/ADZ 10145 rts 10145 rts 10146 10146 10147 ############################################ 10147 ################################################################# 10148 # OPERR exception: 10148 # OPERR exception: # 10149 # - set FPSR exception status operr bi 10149 # - set FPSR exception status operr bit, condition code # 10150 # nan bit; Store default NAN into fp 10150 # nan bit; Store default NAN into fp0 # 10151 ############################################ 10151 ################################################################# 10152 global t_operr 10152 global t_operr 10153 t_operr: 10153 t_operr: 10154 ori.l &opnan_mask,USER_FPS 10154 ori.l &opnan_mask,USER_FPSR(%a6) # set NaN/OPERR/AIOP 10155 fmovm.x qnan(%pc),&0x80 10155 fmovm.x qnan(%pc),&0x80 # return default NAN in fp0 10156 rts 10156 rts 10157 10157 10158 ############################################ 10158 ################################################################# 10159 # Extended DENORM: 10159 # Extended DENORM: # 10160 # - For all functions that have a deno 10160 # - For all functions that have a denormalized input and # 10161 # that f(x)=x, this is the entry poi 10161 # that f(x)=x, this is the entry point. # 10162 # - we only return the EXOP here if ei 10162 # - we only return the EXOP here if either underflow or # 10163 # inexact is enabled. 10163 # inexact is enabled. # 10164 ############################################ 10164 ################################################################# 10165 10165 10166 # Entry point for scale w/ extended denorm. 10166 # Entry point for scale w/ extended denorm. The function does 10167 # NOT set INEX2/AUNFL/AINEX. 10167 # NOT set INEX2/AUNFL/AINEX. 10168 global t_resdnrm 10168 global t_resdnrm 10169 t_resdnrm: 10169 t_resdnrm: 10170 ori.l &unfl_mask,USER_FPSR 10170 ori.l &unfl_mask,USER_FPSR(%a6) # set UNFL 10171 bra.b xdnrm_con 10171 bra.b xdnrm_con 10172 10172 10173 global t_extdnrm 10173 global t_extdnrm 10174 t_extdnrm: 10174 t_extdnrm: 10175 ori.l &unfinx_mask,USER_FP 10175 ori.l &unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX 10176 10176 10177 xdnrm_con: 10177 xdnrm_con: 10178 mov.l %a0,%a1 10178 mov.l %a0,%a1 # make copy of src ptr 10179 mov.l %d0,%d1 10179 mov.l %d0,%d1 # make copy of rnd prec,mode 10180 andi.b &0xc0,%d1 10180 andi.b &0xc0,%d1 # extended precision? 10181 bne.b xdnrm_sd 10181 bne.b xdnrm_sd # no 10182 10182 10183 # result precision is extended. 10183 # result precision is extended. 10184 tst.b LOCAL_EX(%a0) 10184 tst.b LOCAL_EX(%a0) # is denorm negative? 10185 bpl.b xdnrm_exit 10185 bpl.b xdnrm_exit # no 10186 10186 10187 bset &neg_bit,FPSR_CC(%a6 10187 bset &neg_bit,FPSR_CC(%a6) # yes; set 'N' ccode bit 10188 bra.b xdnrm_exit 10188 bra.b xdnrm_exit 10189 10189 10190 # result precision is single or double 10190 # result precision is single or double 10191 xdnrm_sd: 10191 xdnrm_sd: 10192 mov.l %a1,-(%sp) 10192 mov.l %a1,-(%sp) 10193 tst.b LOCAL_EX(%a0) 10193 tst.b LOCAL_EX(%a0) # is denorm pos or neg? 10194 smi.b %d1 10194 smi.b %d1 # set d0 accordingly 10195 bsr.l unf_sub 10195 bsr.l unf_sub 10196 mov.l (%sp)+,%a1 10196 mov.l (%sp)+,%a1 10197 xdnrm_exit: 10197 xdnrm_exit: 10198 fmovm.x (%a0),&0x80 10198 fmovm.x (%a0),&0x80 # return default result in fp0 10199 10199 10200 mov.b FPCR_ENABLE(%a6),%d0 10200 mov.b FPCR_ENABLE(%a6),%d0 10201 andi.b &0x0a,%d0 10201 andi.b &0x0a,%d0 # is UNFL or INEX enabled? 10202 bne.b xdnrm_ena 10202 bne.b xdnrm_ena # yes 10203 rts 10203 rts 10204 10204 10205 ################ 10205 ################ 10206 # unfl enabled # 10206 # unfl enabled # 10207 ################ 10207 ################ 10208 # we have a DENORM that needs to be converte 10208 # we have a DENORM that needs to be converted into an EXOP. 10209 # so, normalize the mantissa, add 0x6000 to 10209 # so, normalize the mantissa, add 0x6000 to the new exponent, 10210 # and return the result in fp1. 10210 # and return the result in fp1. 10211 xdnrm_ena: 10211 xdnrm_ena: 10212 mov.w LOCAL_EX(%a1),FP_SCR 10212 mov.w LOCAL_EX(%a1),FP_SCR0_EX(%a6) 10213 mov.l LOCAL_HI(%a1),FP_SCR 10213 mov.l LOCAL_HI(%a1),FP_SCR0_HI(%a6) 10214 mov.l LOCAL_LO(%a1),FP_SCR 10214 mov.l LOCAL_LO(%a1),FP_SCR0_LO(%a6) 10215 10215 10216 lea FP_SCR0(%a6),%a0 10216 lea FP_SCR0(%a6),%a0 10217 bsr.l norm 10217 bsr.l norm # normalize mantissa 10218 addi.l &0x6000,%d0 10218 addi.l &0x6000,%d0 # add extra bias 10219 andi.w &0x8000,FP_SCR0_EX(% 10219 andi.w &0x8000,FP_SCR0_EX(%a6) # keep old sign 10220 or.w %d0,FP_SCR0_EX(%a6) 10220 or.w %d0,FP_SCR0_EX(%a6) # insert new exponent 10221 10221 10222 fmovm.x FP_SCR0(%a6),&0x40 10222 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 10223 rts 10223 rts 10224 10224 10225 ############################################ 10225 ################################################################# 10226 # UNFL exception: 10226 # UNFL exception: # 10227 # - This routine is for cases where ev 10227 # - This routine is for cases where even an EXOP isn't # 10228 # large enough to hold the range of 10228 # large enough to hold the range of this result. # 10229 # In such a case, the EXOP equals ze 10229 # In such a case, the EXOP equals zero. # 10230 # - Return the default result to the p 10230 # - Return the default result to the proper precision # 10231 # with the sign of this result being 10231 # with the sign of this result being the same as that # 10232 # of the src operand. 10232 # of the src operand. # 10233 # - t_unfl2() is provided to force the 10233 # - t_unfl2() is provided to force the result sign to # 10234 # positive which is the desired resu 10234 # positive which is the desired result for fetox(). # 10235 ############################################ 10235 ################################################################# 10236 global t_unfl 10236 global t_unfl 10237 t_unfl: 10237 t_unfl: 10238 ori.l &unfinx_mask,USER_FP 10238 ori.l &unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX 10239 10239 10240 tst.b (%a0) 10240 tst.b (%a0) # is result pos or neg? 10241 smi.b %d1 10241 smi.b %d1 # set d1 accordingly 10242 bsr.l unf_sub 10242 bsr.l unf_sub # calc default unfl result 10243 fmovm.x (%a0),&0x80 10243 fmovm.x (%a0),&0x80 # return default result in fp0 10244 10244 10245 fmov.s &0x00000000,%fp1 10245 fmov.s &0x00000000,%fp1 # return EXOP in fp1 10246 rts 10246 rts 10247 10247 10248 # t_unfl2 ALWAYS tells unf_sub to create a p 10248 # t_unfl2 ALWAYS tells unf_sub to create a positive result 10249 global t_unfl2 10249 global t_unfl2 10250 t_unfl2: 10250 t_unfl2: 10251 ori.l &unfinx_mask,USER_FP 10251 ori.l &unfinx_mask,USER_FPSR(%a6) # set UNFL/INEX2/AUNFL/AINEX 10252 10252 10253 sf.b %d1 10253 sf.b %d1 # set d0 to represent positive 10254 bsr.l unf_sub 10254 bsr.l unf_sub # calc default unfl result 10255 fmovm.x (%a0),&0x80 10255 fmovm.x (%a0),&0x80 # return default result in fp0 10256 10256 10257 fmov.s &0x0000000,%fp1 10257 fmov.s &0x0000000,%fp1 # return EXOP in fp1 10258 rts 10258 rts 10259 10259 10260 ############################################ 10260 ################################################################# 10261 # OVFL exception: 10261 # OVFL exception: # 10262 # - This routine is for cases where ev 10262 # - This routine is for cases where even an EXOP isn't # 10263 # large enough to hold the range of 10263 # large enough to hold the range of this result. # 10264 # - Return the default result to the p 10264 # - Return the default result to the proper precision # 10265 # with the sign of this result being 10265 # with the sign of this result being the same as that # 10266 # of the src operand. 10266 # of the src operand. # 10267 # - t_ovfl2() is provided to force the 10267 # - t_ovfl2() is provided to force the result sign to # 10268 # positive which is the desired resu 10268 # positive which is the desired result for fcosh(). # 10269 # - t_ovfl_sc() is provided for scale( 10269 # - t_ovfl_sc() is provided for scale() which only sets # 10270 # the inexact bits if the number is 10270 # the inexact bits if the number is inexact for the # 10271 # precision indicated. 10271 # precision indicated. # 10272 ############################################ 10272 ################################################################# 10273 10273 10274 global t_ovfl_sc 10274 global t_ovfl_sc 10275 t_ovfl_sc: 10275 t_ovfl_sc: 10276 ori.l &ovfl_inx_mask,USER_ 10276 ori.l &ovfl_inx_mask,USER_FPSR(%a6) # set OVFL/AOVFL/AINEX 10277 10277 10278 mov.b %d0,%d1 10278 mov.b %d0,%d1 # fetch rnd mode/prec 10279 andi.b &0xc0,%d1 10279 andi.b &0xc0,%d1 # extract rnd prec 10280 beq.b ovfl_work 10280 beq.b ovfl_work # prec is extended 10281 10281 10282 tst.b LOCAL_HI(%a0) 10282 tst.b LOCAL_HI(%a0) # is dst a DENORM? 10283 bmi.b ovfl_sc_norm 10283 bmi.b ovfl_sc_norm # no 10284 10284 10285 # dst op is a DENORM. we have to normalize t 10285 # dst op is a DENORM. we have to normalize the mantissa to see if the 10286 # result would be inexact for the given prec 10286 # result would be inexact for the given precision. make a copy of the 10287 # dst so we don't screw up the version passe 10287 # dst so we don't screw up the version passed to us. 10288 mov.w LOCAL_EX(%a0),FP_SCR 10288 mov.w LOCAL_EX(%a0),FP_SCR0_EX(%a6) 10289 mov.l LOCAL_HI(%a0),FP_SCR 10289 mov.l LOCAL_HI(%a0),FP_SCR0_HI(%a6) 10290 mov.l LOCAL_LO(%a0),FP_SCR 10290 mov.l LOCAL_LO(%a0),FP_SCR0_LO(%a6) 10291 lea FP_SCR0(%a6),%a0 10291 lea FP_SCR0(%a6),%a0 # pass ptr to FP_SCR0 10292 movm.l &0xc080,-(%sp) 10292 movm.l &0xc080,-(%sp) # save d0-d1/a0 10293 bsr.l norm 10293 bsr.l norm # normalize mantissa 10294 movm.l (%sp)+,&0x0103 10294 movm.l (%sp)+,&0x0103 # restore d0-d1/a0 10295 10295 10296 ovfl_sc_norm: 10296 ovfl_sc_norm: 10297 cmpi.b %d1,&0x40 10297 cmpi.b %d1,&0x40 # is prec dbl? 10298 bne.b ovfl_sc_dbl 10298 bne.b ovfl_sc_dbl # no; sgl 10299 ovfl_sc_sgl: 10299 ovfl_sc_sgl: 10300 tst.l LOCAL_LO(%a0) 10300 tst.l LOCAL_LO(%a0) # is lo lw of sgl set? 10301 bne.b ovfl_sc_inx 10301 bne.b ovfl_sc_inx # yes 10302 tst.b 3+LOCAL_HI(%a0) 10302 tst.b 3+LOCAL_HI(%a0) # is lo byte of hi lw set? 10303 bne.b ovfl_sc_inx 10303 bne.b ovfl_sc_inx # yes 10304 bra.b ovfl_work 10304 bra.b ovfl_work # don't set INEX2 10305 ovfl_sc_dbl: 10305 ovfl_sc_dbl: 10306 mov.l LOCAL_LO(%a0),%d1 10306 mov.l LOCAL_LO(%a0),%d1 # are any of lo 11 bits of 10307 andi.l &0x7ff,%d1 10307 andi.l &0x7ff,%d1 # dbl mantissa set? 10308 beq.b ovfl_work 10308 beq.b ovfl_work # no; don't set INEX2 10309 ovfl_sc_inx: 10309 ovfl_sc_inx: 10310 ori.l &inex2_mask,USER_FPS 10310 ori.l &inex2_mask,USER_FPSR(%a6) # set INEX2 10311 bra.b ovfl_work 10311 bra.b ovfl_work # continue 10312 10312 10313 global t_ovfl 10313 global t_ovfl 10314 t_ovfl: 10314 t_ovfl: 10315 ori.l &ovfinx_mask,USER_FP 10315 ori.l &ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX 10316 10316 10317 ovfl_work: 10317 ovfl_work: 10318 tst.b LOCAL_EX(%a0) 10318 tst.b LOCAL_EX(%a0) # what is the sign? 10319 smi.b %d1 10319 smi.b %d1 # set d1 accordingly 10320 bsr.l ovf_res 10320 bsr.l ovf_res # calc default ovfl result 10321 mov.b %d0,FPSR_CC(%a6) 10321 mov.b %d0,FPSR_CC(%a6) # insert new ccodes 10322 fmovm.x (%a0),&0x80 10322 fmovm.x (%a0),&0x80 # return default result in fp0 10323 10323 10324 fmov.s &0x00000000,%fp1 10324 fmov.s &0x00000000,%fp1 # return EXOP in fp1 10325 rts 10325 rts 10326 10326 10327 # t_ovfl2 ALWAYS tells ovf_res to create a p 10327 # t_ovfl2 ALWAYS tells ovf_res to create a positive result 10328 global t_ovfl2 10328 global t_ovfl2 10329 t_ovfl2: 10329 t_ovfl2: 10330 ori.l &ovfinx_mask,USER_FP 10330 ori.l &ovfinx_mask,USER_FPSR(%a6) # set OVFL/INEX2/AOVFL/AINEX 10331 10331 10332 sf.b %d1 10332 sf.b %d1 # clear sign flag for positive 10333 bsr.l ovf_res 10333 bsr.l ovf_res # calc default ovfl result 10334 mov.b %d0,FPSR_CC(%a6) 10334 mov.b %d0,FPSR_CC(%a6) # insert new ccodes 10335 fmovm.x (%a0),&0x80 10335 fmovm.x (%a0),&0x80 # return default result in fp0 10336 10336 10337 fmov.s &0x00000000,%fp1 10337 fmov.s &0x00000000,%fp1 # return EXOP in fp1 10338 rts 10338 rts 10339 10339 10340 ############################################ 10340 ################################################################# 10341 # t_catch(): 10341 # t_catch(): # 10342 # - the last operation of a transcende 10342 # - the last operation of a transcendental emulation # 10343 # routine may have caused an underfl 10343 # routine may have caused an underflow or overflow. # 10344 # we find out if this occurred by do 10344 # we find out if this occurred by doing an fsave and # 10345 # checking the exception bit. if one 10345 # checking the exception bit. if one did occur, then we # 10346 # jump to fgen_except() which create 10346 # jump to fgen_except() which creates the default # 10347 # result and EXOP for us. 10347 # result and EXOP for us. # 10348 ############################################ 10348 ################################################################# 10349 global t_catch 10349 global t_catch 10350 t_catch: 10350 t_catch: 10351 10351 10352 fsave -(%sp) 10352 fsave -(%sp) 10353 tst.b 0x2(%sp) 10353 tst.b 0x2(%sp) 10354 bmi.b catch 10354 bmi.b catch 10355 add.l &0xc,%sp 10355 add.l &0xc,%sp 10356 10356 10357 ############################################ 10357 ################################################################# 10358 # INEX2 exception: 10358 # INEX2 exception: # 10359 # - The inex2 and ainex bits are set. 10359 # - The inex2 and ainex bits are set. # 10360 ############################################ 10360 ################################################################# 10361 global t_inx2 10361 global t_inx2 10362 t_inx2: 10362 t_inx2: 10363 fblt.w t_minx2 10363 fblt.w t_minx2 10364 fbeq.w inx2_zero 10364 fbeq.w inx2_zero 10365 10365 10366 global t_pinx2 10366 global t_pinx2 10367 t_pinx2: 10367 t_pinx2: 10368 ori.w &inx2a_mask,2+USER_F 10368 ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX 10369 rts 10369 rts 10370 10370 10371 global t_minx2 10371 global t_minx2 10372 t_minx2: 10372 t_minx2: 10373 ori.l &inx2a_mask+neg_mask 10373 ori.l &inx2a_mask+neg_mask,USER_FPSR(%a6) # set N/INEX2/AINEX 10374 rts 10374 rts 10375 10375 10376 inx2_zero: 10376 inx2_zero: 10377 mov.b &z_bmask,FPSR_CC(%a6 10377 mov.b &z_bmask,FPSR_CC(%a6) 10378 ori.w &inx2a_mask,2+USER_F 10378 ori.w &inx2a_mask,2+USER_FPSR(%a6) # set INEX2/AINEX 10379 rts 10379 rts 10380 10380 10381 # an underflow or overflow exception occurre 10381 # an underflow or overflow exception occurred. 10382 # we must set INEX/AINEX since the fmul/fdiv 10382 # we must set INEX/AINEX since the fmul/fdiv/fmov emulation may not! 10383 catch: 10383 catch: 10384 ori.w &inx2a_mask,FPSR_EXC 10384 ori.w &inx2a_mask,FPSR_EXCEPT(%a6) 10385 catch2: 10385 catch2: 10386 bsr.l fgen_except 10386 bsr.l fgen_except 10387 add.l &0xc,%sp 10387 add.l &0xc,%sp 10388 rts 10388 rts 10389 10389 10390 global t_catch2 10390 global t_catch2 10391 t_catch2: 10391 t_catch2: 10392 10392 10393 fsave -(%sp) 10393 fsave -(%sp) 10394 10394 10395 tst.b 0x2(%sp) 10395 tst.b 0x2(%sp) 10396 bmi.b catch2 10396 bmi.b catch2 10397 add.l &0xc,%sp 10397 add.l &0xc,%sp 10398 10398 10399 fmov.l %fpsr,%d0 10399 fmov.l %fpsr,%d0 10400 or.l %d0,USER_FPSR(%a6) 10400 or.l %d0,USER_FPSR(%a6) 10401 10401 10402 rts 10402 rts 10403 10403 10404 ############################################ 10404 ######################################################################### 10405 10405 10406 ############################################ 10406 ######################################################################### 10407 # unf_res(): underflow default result calcul 10407 # unf_res(): underflow default result calculation for transcendentals # 10408 # 10408 # # 10409 # INPUT: 10409 # INPUT: # 10410 # d0 : rnd mode,precision 10410 # d0 : rnd mode,precision # 10411 # d1.b : sign bit of result ('11111111 10411 # d1.b : sign bit of result ('11111111 = (-) ; '00000000 = (+)) # 10412 # OUTPUT: 10412 # OUTPUT: # 10413 # a0 : points to result (in instruct 10413 # a0 : points to result (in instruction memory) # 10414 ############################################ 10414 ######################################################################### 10415 unf_sub: 10415 unf_sub: 10416 ori.l &unfinx_mask,USER_FP 10416 ori.l &unfinx_mask,USER_FPSR(%a6) 10417 10417 10418 andi.w &0x10,%d1 10418 andi.w &0x10,%d1 # keep sign bit in 4th spot 10419 10419 10420 lsr.b &0x4,%d0 10420 lsr.b &0x4,%d0 # shift rnd prec,mode to lo bits 10421 andi.b &0xf,%d0 10421 andi.b &0xf,%d0 # strip hi rnd mode bit 10422 or.b %d1,%d0 10422 or.b %d1,%d0 # concat {sgn,mode,prec} 10423 10423 10424 mov.l %d0,%d1 10424 mov.l %d0,%d1 # make a copy 10425 lsl.b &0x1,%d1 10425 lsl.b &0x1,%d1 # mult index 2 by 2 10426 10426 10427 mov.b (tbl_unf_cc.b,%pc,%d 10427 mov.b (tbl_unf_cc.b,%pc,%d0.w*1),FPSR_CC(%a6) # insert ccode bits 10428 lea (tbl_unf_result.b,%p 10428 lea (tbl_unf_result.b,%pc,%d1.w*8),%a0 # grab result ptr 10429 rts 10429 rts 10430 10430 10431 tbl_unf_cc: 10431 tbl_unf_cc: 10432 byte 0x4, 0x4, 0x4, 0x0 10432 byte 0x4, 0x4, 0x4, 0x0 10433 byte 0x4, 0x4, 0x4, 0x0 10433 byte 0x4, 0x4, 0x4, 0x0 10434 byte 0x4, 0x4, 0x4, 0x0 10434 byte 0x4, 0x4, 0x4, 0x0 10435 byte 0x0, 0x0, 0x0, 0x0 10435 byte 0x0, 0x0, 0x0, 0x0 10436 byte 0x8+0x4, 0x8+0x4, 0x 10436 byte 0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4 10437 byte 0x8+0x4, 0x8+0x4, 0x 10437 byte 0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4 10438 byte 0x8+0x4, 0x8+0x4, 0x 10438 byte 0x8+0x4, 0x8+0x4, 0x8, 0x8+0x4 10439 10439 10440 tbl_unf_result: 10440 tbl_unf_result: 10441 long 0x00000000, 0x000000 10441 long 0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext 10442 long 0x00000000, 0x000000 10442 long 0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext 10443 long 0x00000000, 0x000000 10443 long 0x00000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext 10444 long 0x00000000, 0x000000 10444 long 0x00000000, 0x00000000, 0x00000001, 0x0 # MIN; ext 10445 10445 10446 long 0x3f810000, 0x000000 10446 long 0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl 10447 long 0x3f810000, 0x000000 10447 long 0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl 10448 long 0x3f810000, 0x000000 10448 long 0x3f810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl 10449 long 0x3f810000, 0x000001 10449 long 0x3f810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl 10450 10450 10451 long 0x3c010000, 0x000000 10451 long 0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl 10452 long 0x3c010000, 0x000000 10452 long 0x3c010000, 0x00000000, 0x00000000, 0x0 # ZER0;dbl 10453 long 0x3c010000, 0x000000 10453 long 0x3c010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl 10454 long 0x3c010000, 0x000000 10454 long 0x3c010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl 10455 10455 10456 long 0x0,0x0,0x0,0x0 10456 long 0x0,0x0,0x0,0x0 10457 long 0x0,0x0,0x0,0x0 10457 long 0x0,0x0,0x0,0x0 10458 long 0x0,0x0,0x0,0x0 10458 long 0x0,0x0,0x0,0x0 10459 long 0x0,0x0,0x0,0x0 10459 long 0x0,0x0,0x0,0x0 10460 10460 10461 long 0x80000000, 0x000000 10461 long 0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext 10462 long 0x80000000, 0x000000 10462 long 0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext 10463 long 0x80000000, 0x000000 10463 long 0x80000000, 0x00000000, 0x00000001, 0x0 # MIN; ext 10464 long 0x80000000, 0x000000 10464 long 0x80000000, 0x00000000, 0x00000000, 0x0 # ZERO;ext 10465 10465 10466 long 0xbf810000, 0x000000 10466 long 0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl 10467 long 0xbf810000, 0x000000 10467 long 0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl 10468 long 0xbf810000, 0x000001 10468 long 0xbf810000, 0x00000100, 0x00000000, 0x0 # MIN; sgl 10469 long 0xbf810000, 0x000000 10469 long 0xbf810000, 0x00000000, 0x00000000, 0x0 # ZERO;sgl 10470 10470 10471 long 0xbc010000, 0x000000 10471 long 0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl 10472 long 0xbc010000, 0x000000 10472 long 0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl 10473 long 0xbc010000, 0x000000 10473 long 0xbc010000, 0x00000000, 0x00000800, 0x0 # MIN; dbl 10474 long 0xbc010000, 0x000000 10474 long 0xbc010000, 0x00000000, 0x00000000, 0x0 # ZERO;dbl 10475 10475 10476 ############################################ 10476 ############################################################ 10477 10477 10478 ############################################ 10478 ######################################################################### 10479 # src_zero(): Return signed zero according t 10479 # src_zero(): Return signed zero according to sign of src operand. # 10480 ############################################ 10480 ######################################################################### 10481 global src_zero 10481 global src_zero 10482 src_zero: 10482 src_zero: 10483 tst.b SRC_EX(%a0) 10483 tst.b SRC_EX(%a0) # get sign of src operand 10484 bmi.b ld_mzero 10484 bmi.b ld_mzero # if neg, load neg zero 10485 10485 10486 # 10486 # 10487 # ld_pzero(): return a positive zero. 10487 # ld_pzero(): return a positive zero. 10488 # 10488 # 10489 global ld_pzero 10489 global ld_pzero 10490 ld_pzero: 10490 ld_pzero: 10491 fmov.s &0x00000000,%fp0 10491 fmov.s &0x00000000,%fp0 # load +0 10492 mov.b &z_bmask,FPSR_CC(%a6 10492 mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 10493 rts 10493 rts 10494 10494 10495 # ld_mzero(): return a negative zero. 10495 # ld_mzero(): return a negative zero. 10496 global ld_mzero 10496 global ld_mzero 10497 ld_mzero: 10497 ld_mzero: 10498 fmov.s &0x80000000,%fp0 10498 fmov.s &0x80000000,%fp0 # load -0 10499 mov.b &neg_bmask+z_bmask,F 10499 mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set 'N','Z' ccode bits 10500 rts 10500 rts 10501 10501 10502 ############################################ 10502 ######################################################################### 10503 # dst_zero(): Return signed zero according t 10503 # dst_zero(): Return signed zero according to sign of dst operand. # 10504 ############################################ 10504 ######################################################################### 10505 global dst_zero 10505 global dst_zero 10506 dst_zero: 10506 dst_zero: 10507 tst.b DST_EX(%a1) 10507 tst.b DST_EX(%a1) # get sign of dst operand 10508 bmi.b ld_mzero 10508 bmi.b ld_mzero # if neg, load neg zero 10509 bra.b ld_pzero 10509 bra.b ld_pzero # load positive zero 10510 10510 10511 ############################################ 10511 ######################################################################### 10512 # src_inf(): Return signed inf according to 10512 # src_inf(): Return signed inf according to sign of src operand. # 10513 ############################################ 10513 ######################################################################### 10514 global src_inf 10514 global src_inf 10515 src_inf: 10515 src_inf: 10516 tst.b SRC_EX(%a0) 10516 tst.b SRC_EX(%a0) # get sign of src operand 10517 bmi.b ld_minf 10517 bmi.b ld_minf # if negative branch 10518 10518 10519 # 10519 # 10520 # ld_pinf(): return a positive infinity. 10520 # ld_pinf(): return a positive infinity. 10521 # 10521 # 10522 global ld_pinf 10522 global ld_pinf 10523 ld_pinf: 10523 ld_pinf: 10524 fmov.s &0x7f800000,%fp0 10524 fmov.s &0x7f800000,%fp0 # load +INF 10525 mov.b &inf_bmask,FPSR_CC(% 10525 mov.b &inf_bmask,FPSR_CC(%a6) # set 'INF' ccode bit 10526 rts 10526 rts 10527 10527 10528 # 10528 # 10529 # ld_minf():return a negative infinity. 10529 # ld_minf():return a negative infinity. 10530 # 10530 # 10531 global ld_minf 10531 global ld_minf 10532 ld_minf: 10532 ld_minf: 10533 fmov.s &0xff800000,%fp0 10533 fmov.s &0xff800000,%fp0 # load -INF 10534 mov.b &neg_bmask+inf_bmask 10534 mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits 10535 rts 10535 rts 10536 10536 10537 ############################################ 10537 ######################################################################### 10538 # dst_inf(): Return signed inf according to 10538 # dst_inf(): Return signed inf according to sign of dst operand. # 10539 ############################################ 10539 ######################################################################### 10540 global dst_inf 10540 global dst_inf 10541 dst_inf: 10541 dst_inf: 10542 tst.b DST_EX(%a1) 10542 tst.b DST_EX(%a1) # get sign of dst operand 10543 bmi.b ld_minf 10543 bmi.b ld_minf # if negative branch 10544 bra.b ld_pinf 10544 bra.b ld_pinf 10545 10545 10546 global szr_inf 10546 global szr_inf 10547 ############################################ 10547 ################################################################# 10548 # szr_inf(): Return +ZERO for a negative src 10548 # szr_inf(): Return +ZERO for a negative src operand or # 10549 # +INF for a positive src 10549 # +INF for a positive src operand. # 10550 # Routine used for fetox, ftwotox 10550 # Routine used for fetox, ftwotox, and ftentox. # 10551 ############################################ 10551 ################################################################# 10552 szr_inf: 10552 szr_inf: 10553 tst.b SRC_EX(%a0) 10553 tst.b SRC_EX(%a0) # check sign of source 10554 bmi.b ld_pzero 10554 bmi.b ld_pzero 10555 bra.b ld_pinf 10555 bra.b ld_pinf 10556 10556 10557 ############################################ 10557 ######################################################################### 10558 # sopr_inf(): Return +INF for a positive src 10558 # sopr_inf(): Return +INF for a positive src operand or # 10559 # jump to operand error routine 10559 # jump to operand error routine for a negative src operand. # 10560 # Routine used for flogn, flognp 10560 # Routine used for flogn, flognp1, flog10, and flog2. # 10561 ############################################ 10561 ######################################################################### 10562 global sopr_inf 10562 global sopr_inf 10563 sopr_inf: 10563 sopr_inf: 10564 tst.b SRC_EX(%a0) 10564 tst.b SRC_EX(%a0) # check sign of source 10565 bmi.w t_operr 10565 bmi.w t_operr 10566 bra.b ld_pinf 10566 bra.b ld_pinf 10567 10567 10568 ############################################ 10568 ################################################################# 10569 # setoxm1i(): Return minus one for a negativ 10569 # setoxm1i(): Return minus one for a negative src operand or # 10570 # positive infinity for a positi 10570 # positive infinity for a positive src operand. # 10571 # Routine used for fetoxm1. 10571 # Routine used for fetoxm1. # 10572 ############################################ 10572 ################################################################# 10573 global setoxm1i 10573 global setoxm1i 10574 setoxm1i: 10574 setoxm1i: 10575 tst.b SRC_EX(%a0) 10575 tst.b SRC_EX(%a0) # check sign of source 10576 bmi.b ld_mone 10576 bmi.b ld_mone 10577 bra.b ld_pinf 10577 bra.b ld_pinf 10578 10578 10579 ############################################ 10579 ######################################################################### 10580 # src_one(): Return signed one according to 10580 # src_one(): Return signed one according to sign of src operand. # 10581 ############################################ 10581 ######################################################################### 10582 global src_one 10582 global src_one 10583 src_one: 10583 src_one: 10584 tst.b SRC_EX(%a0) 10584 tst.b SRC_EX(%a0) # check sign of source 10585 bmi.b ld_mone 10585 bmi.b ld_mone 10586 10586 10587 # 10587 # 10588 # ld_pone(): return positive one. 10588 # ld_pone(): return positive one. 10589 # 10589 # 10590 global ld_pone 10590 global ld_pone 10591 ld_pone: 10591 ld_pone: 10592 fmov.s &0x3f800000,%fp0 10592 fmov.s &0x3f800000,%fp0 # load +1 10593 clr.b FPSR_CC(%a6) 10593 clr.b FPSR_CC(%a6) 10594 rts 10594 rts 10595 10595 10596 # 10596 # 10597 # ld_mone(): return negative one. 10597 # ld_mone(): return negative one. 10598 # 10598 # 10599 global ld_mone 10599 global ld_mone 10600 ld_mone: 10600 ld_mone: 10601 fmov.s &0xbf800000,%fp0 10601 fmov.s &0xbf800000,%fp0 # load -1 10602 mov.b &neg_bmask,FPSR_CC(% 10602 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 10603 rts 10603 rts 10604 10604 10605 ppiby2: long 0x3fff0000, 0xc90fda 10605 ppiby2: long 0x3fff0000, 0xc90fdaa2, 0x2168c235 10606 mpiby2: long 0xbfff0000, 0xc90fda 10606 mpiby2: long 0xbfff0000, 0xc90fdaa2, 0x2168c235 10607 10607 10608 ############################################ 10608 ################################################################# 10609 # spi_2(): Return signed PI/2 according to s 10609 # spi_2(): Return signed PI/2 according to sign of src operand. # 10610 ############################################ 10610 ################################################################# 10611 global spi_2 10611 global spi_2 10612 spi_2: 10612 spi_2: 10613 tst.b SRC_EX(%a0) 10613 tst.b SRC_EX(%a0) # check sign of source 10614 bmi.b ld_mpi2 10614 bmi.b ld_mpi2 10615 10615 10616 # 10616 # 10617 # ld_ppi2(): return positive PI/2. 10617 # ld_ppi2(): return positive PI/2. 10618 # 10618 # 10619 global ld_ppi2 10619 global ld_ppi2 10620 ld_ppi2: 10620 ld_ppi2: 10621 fmov.l %d0,%fpcr 10621 fmov.l %d0,%fpcr 10622 fmov.x ppiby2(%pc),%fp0 10622 fmov.x ppiby2(%pc),%fp0 # load +pi/2 10623 bra.w t_pinx2 10623 bra.w t_pinx2 # set INEX2 10624 10624 10625 # 10625 # 10626 # ld_mpi2(): return negative PI/2. 10626 # ld_mpi2(): return negative PI/2. 10627 # 10627 # 10628 global ld_mpi2 10628 global ld_mpi2 10629 ld_mpi2: 10629 ld_mpi2: 10630 fmov.l %d0,%fpcr 10630 fmov.l %d0,%fpcr 10631 fmov.x mpiby2(%pc),%fp0 10631 fmov.x mpiby2(%pc),%fp0 # load -pi/2 10632 bra.w t_minx2 10632 bra.w t_minx2 # set INEX2 10633 10633 10634 ############################################ 10634 #################################################### 10635 # The following routines give support for fs 10635 # The following routines give support for fsincos. # 10636 ############################################ 10636 #################################################### 10637 10637 10638 # 10638 # 10639 # ssincosz(): When the src operand is ZERO, 10639 # ssincosz(): When the src operand is ZERO, store a one in the 10640 # cosine register and return a Z 10640 # cosine register and return a ZERO in fp0 w/ the same sign 10641 # as the src operand. 10641 # as the src operand. 10642 # 10642 # 10643 global ssincosz 10643 global ssincosz 10644 ssincosz: 10644 ssincosz: 10645 fmov.s &0x3f800000,%fp1 10645 fmov.s &0x3f800000,%fp1 10646 tst.b SRC_EX(%a0) 10646 tst.b SRC_EX(%a0) # test sign 10647 bpl.b sincoszp 10647 bpl.b sincoszp 10648 fmov.s &0x80000000,%fp0 10648 fmov.s &0x80000000,%fp0 # return sin result in fp0 10649 mov.b &z_bmask+neg_bmask,F 10649 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) 10650 bra.b sto_cos 10650 bra.b sto_cos # store cosine result 10651 sincoszp: 10651 sincoszp: 10652 fmov.s &0x00000000,%fp0 10652 fmov.s &0x00000000,%fp0 # return sin result in fp0 10653 mov.b &z_bmask,FPSR_CC(%a6 10653 mov.b &z_bmask,FPSR_CC(%a6) 10654 bra.b sto_cos 10654 bra.b sto_cos # store cosine result 10655 10655 10656 # 10656 # 10657 # ssincosi(): When the src operand is INF, s 10657 # ssincosi(): When the src operand is INF, store a QNAN in the cosine 10658 # register and jump to the opera 10658 # register and jump to the operand error routine for negative 10659 # src operands. 10659 # src operands. 10660 # 10660 # 10661 global ssincosi 10661 global ssincosi 10662 ssincosi: 10662 ssincosi: 10663 fmov.x qnan(%pc),%fp1 10663 fmov.x qnan(%pc),%fp1 # load NAN 10664 bsr.l sto_cos 10664 bsr.l sto_cos # store cosine result 10665 bra.w t_operr 10665 bra.w t_operr 10666 10666 10667 # 10667 # 10668 # ssincosqnan(): When the src operand is a Q 10668 # ssincosqnan(): When the src operand is a QNAN, store the QNAN in the cosine 10669 # register and branch to the 10669 # register and branch to the src QNAN routine. 10670 # 10670 # 10671 global ssincosqnan 10671 global ssincosqnan 10672 ssincosqnan: 10672 ssincosqnan: 10673 fmov.x LOCAL_EX(%a0),%fp1 10673 fmov.x LOCAL_EX(%a0),%fp1 10674 bsr.l sto_cos 10674 bsr.l sto_cos 10675 bra.w src_qnan 10675 bra.w src_qnan 10676 10676 10677 # 10677 # 10678 # ssincossnan(): When the src operand is an 10678 # ssincossnan(): When the src operand is an SNAN, store the SNAN w/ the SNAN bit set 10679 # in the cosine register and 10679 # in the cosine register and branch to the src SNAN routine. 10680 # 10680 # 10681 global ssincossnan 10681 global ssincossnan 10682 ssincossnan: 10682 ssincossnan: 10683 fmov.x LOCAL_EX(%a0),%fp1 10683 fmov.x LOCAL_EX(%a0),%fp1 10684 bsr.l sto_cos 10684 bsr.l sto_cos 10685 bra.w src_snan 10685 bra.w src_snan 10686 10686 10687 ############################################ 10687 ######################################################################## 10688 10688 10689 ############################################ 10689 ######################################################################### 10690 # sto_cos(): store fp1 to the fpreg designat 10690 # sto_cos(): store fp1 to the fpreg designated by the CMDREG dst field. # 10691 # fp1 holds the result of the cos 10691 # fp1 holds the result of the cosine portion of ssincos(). # 10692 # the value in fp1 will not take 10692 # the value in fp1 will not take any exceptions when moved. # 10693 # INPUT: 10693 # INPUT: # 10694 # fp1 : fp value to store 10694 # fp1 : fp value to store # 10695 # MODIFIED: 10695 # MODIFIED: # 10696 # d0 10696 # d0 # 10697 ############################################ 10697 ######################################################################### 10698 global sto_cos 10698 global sto_cos 10699 sto_cos: 10699 sto_cos: 10700 mov.b 1+EXC_CMDREG(%a6),%d 10700 mov.b 1+EXC_CMDREG(%a6),%d0 10701 andi.w &0x7,%d0 10701 andi.w &0x7,%d0 10702 mov.w (tbl_sto_cos.b,%pc,% 10702 mov.w (tbl_sto_cos.b,%pc,%d0.w*2),%d0 10703 jmp (tbl_sto_cos.b,%pc,% 10703 jmp (tbl_sto_cos.b,%pc,%d0.w*1) 10704 10704 10705 tbl_sto_cos: 10705 tbl_sto_cos: 10706 short sto_cos_0 - tbl_sto_ 10706 short sto_cos_0 - tbl_sto_cos 10707 short sto_cos_1 - tbl_sto_ 10707 short sto_cos_1 - tbl_sto_cos 10708 short sto_cos_2 - tbl_sto_ 10708 short sto_cos_2 - tbl_sto_cos 10709 short sto_cos_3 - tbl_sto_ 10709 short sto_cos_3 - tbl_sto_cos 10710 short sto_cos_4 - tbl_sto_ 10710 short sto_cos_4 - tbl_sto_cos 10711 short sto_cos_5 - tbl_sto_ 10711 short sto_cos_5 - tbl_sto_cos 10712 short sto_cos_6 - tbl_sto_ 10712 short sto_cos_6 - tbl_sto_cos 10713 short sto_cos_7 - tbl_sto_ 10713 short sto_cos_7 - tbl_sto_cos 10714 10714 10715 sto_cos_0: 10715 sto_cos_0: 10716 fmovm.x &0x40,EXC_FP0(%a6) 10716 fmovm.x &0x40,EXC_FP0(%a6) 10717 rts 10717 rts 10718 sto_cos_1: 10718 sto_cos_1: 10719 fmovm.x &0x40,EXC_FP1(%a6) 10719 fmovm.x &0x40,EXC_FP1(%a6) 10720 rts 10720 rts 10721 sto_cos_2: 10721 sto_cos_2: 10722 fmov.x %fp1,%fp2 10722 fmov.x %fp1,%fp2 10723 rts 10723 rts 10724 sto_cos_3: 10724 sto_cos_3: 10725 fmov.x %fp1,%fp3 10725 fmov.x %fp1,%fp3 10726 rts 10726 rts 10727 sto_cos_4: 10727 sto_cos_4: 10728 fmov.x %fp1,%fp4 10728 fmov.x %fp1,%fp4 10729 rts 10729 rts 10730 sto_cos_5: 10730 sto_cos_5: 10731 fmov.x %fp1,%fp5 10731 fmov.x %fp1,%fp5 10732 rts 10732 rts 10733 sto_cos_6: 10733 sto_cos_6: 10734 fmov.x %fp1,%fp6 10734 fmov.x %fp1,%fp6 10735 rts 10735 rts 10736 sto_cos_7: 10736 sto_cos_7: 10737 fmov.x %fp1,%fp7 10737 fmov.x %fp1,%fp7 10738 rts 10738 rts 10739 10739 10740 ############################################ 10740 ################################################################## 10741 global smod_sdnrm 10741 global smod_sdnrm 10742 global smod_snorm 10742 global smod_snorm 10743 smod_sdnrm: 10743 smod_sdnrm: 10744 smod_snorm: 10744 smod_snorm: 10745 mov.b DTAG(%a6),%d1 10745 mov.b DTAG(%a6),%d1 10746 beq.l smod 10746 beq.l smod 10747 cmpi.b %d1,&ZERO 10747 cmpi.b %d1,&ZERO 10748 beq.w smod_zro 10748 beq.w smod_zro 10749 cmpi.b %d1,&INF 10749 cmpi.b %d1,&INF 10750 beq.l t_operr 10750 beq.l t_operr 10751 cmpi.b %d1,&DENORM 10751 cmpi.b %d1,&DENORM 10752 beq.l smod 10752 beq.l smod 10753 cmpi.b %d1,&SNAN 10753 cmpi.b %d1,&SNAN 10754 beq.l dst_snan 10754 beq.l dst_snan 10755 bra.l dst_qnan 10755 bra.l dst_qnan 10756 10756 10757 global smod_szero 10757 global smod_szero 10758 smod_szero: 10758 smod_szero: 10759 mov.b DTAG(%a6),%d1 10759 mov.b DTAG(%a6),%d1 10760 beq.l t_operr 10760 beq.l t_operr 10761 cmpi.b %d1,&ZERO 10761 cmpi.b %d1,&ZERO 10762 beq.l t_operr 10762 beq.l t_operr 10763 cmpi.b %d1,&INF 10763 cmpi.b %d1,&INF 10764 beq.l t_operr 10764 beq.l t_operr 10765 cmpi.b %d1,&DENORM 10765 cmpi.b %d1,&DENORM 10766 beq.l t_operr 10766 beq.l t_operr 10767 cmpi.b %d1,&QNAN 10767 cmpi.b %d1,&QNAN 10768 beq.l dst_qnan 10768 beq.l dst_qnan 10769 bra.l dst_snan 10769 bra.l dst_snan 10770 10770 10771 global smod_sinf 10771 global smod_sinf 10772 smod_sinf: 10772 smod_sinf: 10773 mov.b DTAG(%a6),%d1 10773 mov.b DTAG(%a6),%d1 10774 beq.l smod_fpn 10774 beq.l smod_fpn 10775 cmpi.b %d1,&ZERO 10775 cmpi.b %d1,&ZERO 10776 beq.l smod_zro 10776 beq.l smod_zro 10777 cmpi.b %d1,&INF 10777 cmpi.b %d1,&INF 10778 beq.l t_operr 10778 beq.l t_operr 10779 cmpi.b %d1,&DENORM 10779 cmpi.b %d1,&DENORM 10780 beq.l smod_fpn 10780 beq.l smod_fpn 10781 cmpi.b %d1,&QNAN 10781 cmpi.b %d1,&QNAN 10782 beq.l dst_qnan 10782 beq.l dst_qnan 10783 bra.l dst_snan 10783 bra.l dst_snan 10784 10784 10785 smod_zro: 10785 smod_zro: 10786 srem_zro: 10786 srem_zro: 10787 mov.b SRC_EX(%a0),%d1 10787 mov.b SRC_EX(%a0),%d1 # get src sign 10788 mov.b DST_EX(%a1),%d0 10788 mov.b DST_EX(%a1),%d0 # get dst sign 10789 eor.b %d0,%d1 10789 eor.b %d0,%d1 # get qbyte sign 10790 andi.b &0x80,%d1 10790 andi.b &0x80,%d1 10791 mov.b %d1,FPSR_QBYTE(%a6) 10791 mov.b %d1,FPSR_QBYTE(%a6) 10792 tst.b %d0 10792 tst.b %d0 10793 bpl.w ld_pzero 10793 bpl.w ld_pzero 10794 bra.w ld_mzero 10794 bra.w ld_mzero 10795 10795 10796 smod_fpn: 10796 smod_fpn: 10797 srem_fpn: 10797 srem_fpn: 10798 clr.b FPSR_QBYTE(%a6) 10798 clr.b FPSR_QBYTE(%a6) 10799 mov.l %d0,-(%sp) 10799 mov.l %d0,-(%sp) 10800 mov.b SRC_EX(%a0),%d1 10800 mov.b SRC_EX(%a0),%d1 # get src sign 10801 mov.b DST_EX(%a1),%d0 10801 mov.b DST_EX(%a1),%d0 # get dst sign 10802 eor.b %d0,%d1 10802 eor.b %d0,%d1 # get qbyte sign 10803 andi.b &0x80,%d1 10803 andi.b &0x80,%d1 10804 mov.b %d1,FPSR_QBYTE(%a6) 10804 mov.b %d1,FPSR_QBYTE(%a6) 10805 cmpi.b DTAG(%a6),&DENORM 10805 cmpi.b DTAG(%a6),&DENORM 10806 bne.b smod_nrm 10806 bne.b smod_nrm 10807 lea DST(%a1),%a0 10807 lea DST(%a1),%a0 10808 mov.l (%sp)+,%d0 10808 mov.l (%sp)+,%d0 10809 bra t_resdnrm 10809 bra t_resdnrm 10810 smod_nrm: 10810 smod_nrm: 10811 fmov.l (%sp)+,%fpcr 10811 fmov.l (%sp)+,%fpcr 10812 fmov.x DST(%a1),%fp0 10812 fmov.x DST(%a1),%fp0 10813 tst.b DST_EX(%a1) 10813 tst.b DST_EX(%a1) 10814 bmi.b smod_nrm_neg 10814 bmi.b smod_nrm_neg 10815 rts 10815 rts 10816 10816 10817 smod_nrm_neg: 10817 smod_nrm_neg: 10818 mov.b &neg_bmask,FPSR_CC(% 10818 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode 10819 rts 10819 rts 10820 10820 10821 ############################################ 10821 ######################################################################### 10822 global srem_snorm 10822 global srem_snorm 10823 global srem_sdnrm 10823 global srem_sdnrm 10824 srem_sdnrm: 10824 srem_sdnrm: 10825 srem_snorm: 10825 srem_snorm: 10826 mov.b DTAG(%a6),%d1 10826 mov.b DTAG(%a6),%d1 10827 beq.l srem 10827 beq.l srem 10828 cmpi.b %d1,&ZERO 10828 cmpi.b %d1,&ZERO 10829 beq.w srem_zro 10829 beq.w srem_zro 10830 cmpi.b %d1,&INF 10830 cmpi.b %d1,&INF 10831 beq.l t_operr 10831 beq.l t_operr 10832 cmpi.b %d1,&DENORM 10832 cmpi.b %d1,&DENORM 10833 beq.l srem 10833 beq.l srem 10834 cmpi.b %d1,&QNAN 10834 cmpi.b %d1,&QNAN 10835 beq.l dst_qnan 10835 beq.l dst_qnan 10836 bra.l dst_snan 10836 bra.l dst_snan 10837 10837 10838 global srem_szero 10838 global srem_szero 10839 srem_szero: 10839 srem_szero: 10840 mov.b DTAG(%a6),%d1 10840 mov.b DTAG(%a6),%d1 10841 beq.l t_operr 10841 beq.l t_operr 10842 cmpi.b %d1,&ZERO 10842 cmpi.b %d1,&ZERO 10843 beq.l t_operr 10843 beq.l t_operr 10844 cmpi.b %d1,&INF 10844 cmpi.b %d1,&INF 10845 beq.l t_operr 10845 beq.l t_operr 10846 cmpi.b %d1,&DENORM 10846 cmpi.b %d1,&DENORM 10847 beq.l t_operr 10847 beq.l t_operr 10848 cmpi.b %d1,&QNAN 10848 cmpi.b %d1,&QNAN 10849 beq.l dst_qnan 10849 beq.l dst_qnan 10850 bra.l dst_snan 10850 bra.l dst_snan 10851 10851 10852 global srem_sinf 10852 global srem_sinf 10853 srem_sinf: 10853 srem_sinf: 10854 mov.b DTAG(%a6),%d1 10854 mov.b DTAG(%a6),%d1 10855 beq.w srem_fpn 10855 beq.w srem_fpn 10856 cmpi.b %d1,&ZERO 10856 cmpi.b %d1,&ZERO 10857 beq.w srem_zro 10857 beq.w srem_zro 10858 cmpi.b %d1,&INF 10858 cmpi.b %d1,&INF 10859 beq.l t_operr 10859 beq.l t_operr 10860 cmpi.b %d1,&DENORM 10860 cmpi.b %d1,&DENORM 10861 beq.l srem_fpn 10861 beq.l srem_fpn 10862 cmpi.b %d1,&QNAN 10862 cmpi.b %d1,&QNAN 10863 beq.l dst_qnan 10863 beq.l dst_qnan 10864 bra.l dst_snan 10864 bra.l dst_snan 10865 10865 10866 ############################################ 10866 ######################################################################### 10867 global sscale_snorm 10867 global sscale_snorm 10868 global sscale_sdnrm 10868 global sscale_sdnrm 10869 sscale_snorm: 10869 sscale_snorm: 10870 sscale_sdnrm: 10870 sscale_sdnrm: 10871 mov.b DTAG(%a6),%d1 10871 mov.b DTAG(%a6),%d1 10872 beq.l sscale 10872 beq.l sscale 10873 cmpi.b %d1,&ZERO 10873 cmpi.b %d1,&ZERO 10874 beq.l dst_zero 10874 beq.l dst_zero 10875 cmpi.b %d1,&INF 10875 cmpi.b %d1,&INF 10876 beq.l dst_inf 10876 beq.l dst_inf 10877 cmpi.b %d1,&DENORM 10877 cmpi.b %d1,&DENORM 10878 beq.l sscale 10878 beq.l sscale 10879 cmpi.b %d1,&QNAN 10879 cmpi.b %d1,&QNAN 10880 beq.l dst_qnan 10880 beq.l dst_qnan 10881 bra.l dst_snan 10881 bra.l dst_snan 10882 10882 10883 global sscale_szero 10883 global sscale_szero 10884 sscale_szero: 10884 sscale_szero: 10885 mov.b DTAG(%a6),%d1 10885 mov.b DTAG(%a6),%d1 10886 beq.l sscale 10886 beq.l sscale 10887 cmpi.b %d1,&ZERO 10887 cmpi.b %d1,&ZERO 10888 beq.l dst_zero 10888 beq.l dst_zero 10889 cmpi.b %d1,&INF 10889 cmpi.b %d1,&INF 10890 beq.l dst_inf 10890 beq.l dst_inf 10891 cmpi.b %d1,&DENORM 10891 cmpi.b %d1,&DENORM 10892 beq.l sscale 10892 beq.l sscale 10893 cmpi.b %d1,&QNAN 10893 cmpi.b %d1,&QNAN 10894 beq.l dst_qnan 10894 beq.l dst_qnan 10895 bra.l dst_snan 10895 bra.l dst_snan 10896 10896 10897 global sscale_sinf 10897 global sscale_sinf 10898 sscale_sinf: 10898 sscale_sinf: 10899 mov.b DTAG(%a6),%d1 10899 mov.b DTAG(%a6),%d1 10900 beq.l t_operr 10900 beq.l t_operr 10901 cmpi.b %d1,&QNAN 10901 cmpi.b %d1,&QNAN 10902 beq.l dst_qnan 10902 beq.l dst_qnan 10903 cmpi.b %d1,&SNAN 10903 cmpi.b %d1,&SNAN 10904 beq.l dst_snan 10904 beq.l dst_snan 10905 bra.l t_operr 10905 bra.l t_operr 10906 10906 10907 ############################################ 10907 ######################################################################## 10908 10908 10909 # 10909 # 10910 # sop_sqnan(): The src op for frem/fmod/fsca 10910 # sop_sqnan(): The src op for frem/fmod/fscale was a QNAN. 10911 # 10911 # 10912 global sop_sqnan 10912 global sop_sqnan 10913 sop_sqnan: 10913 sop_sqnan: 10914 mov.b DTAG(%a6),%d1 10914 mov.b DTAG(%a6),%d1 10915 cmpi.b %d1,&QNAN 10915 cmpi.b %d1,&QNAN 10916 beq.b dst_qnan 10916 beq.b dst_qnan 10917 cmpi.b %d1,&SNAN 10917 cmpi.b %d1,&SNAN 10918 beq.b dst_snan 10918 beq.b dst_snan 10919 bra.b src_qnan 10919 bra.b src_qnan 10920 10920 10921 # 10921 # 10922 # sop_ssnan(): The src op for frem/fmod/fsca 10922 # sop_ssnan(): The src op for frem/fmod/fscale was an SNAN. 10923 # 10923 # 10924 global sop_ssnan 10924 global sop_ssnan 10925 sop_ssnan: 10925 sop_ssnan: 10926 mov.b DTAG(%a6),%d1 10926 mov.b DTAG(%a6),%d1 10927 cmpi.b %d1,&QNAN 10927 cmpi.b %d1,&QNAN 10928 beq.b dst_qnan_src_snan 10928 beq.b dst_qnan_src_snan 10929 cmpi.b %d1,&SNAN 10929 cmpi.b %d1,&SNAN 10930 beq.b dst_snan 10930 beq.b dst_snan 10931 bra.b src_snan 10931 bra.b src_snan 10932 10932 10933 dst_qnan_src_snan: 10933 dst_qnan_src_snan: 10934 ori.l &snaniop_mask,USER_F 10934 ori.l &snaniop_mask,USER_FPSR(%a6) # set NAN/SNAN/AIOP 10935 bra.b dst_qnan 10935 bra.b dst_qnan 10936 10936 10937 # 10937 # 10938 # dst_qnan(): Return the dst SNAN w/ the SNA 10938 # dst_qnan(): Return the dst SNAN w/ the SNAN bit set. 10939 # 10939 # 10940 global dst_snan 10940 global dst_snan 10941 dst_snan: 10941 dst_snan: 10942 fmov.x DST(%a1),%fp0 10942 fmov.x DST(%a1),%fp0 # the fmove sets the SNAN bit 10943 fmov.l %fpsr,%d0 10943 fmov.l %fpsr,%d0 # catch resulting status 10944 or.l %d0,USER_FPSR(%a6) 10944 or.l %d0,USER_FPSR(%a6) # store status 10945 rts 10945 rts 10946 10946 10947 # 10947 # 10948 # dst_qnan(): Return the dst QNAN. 10948 # dst_qnan(): Return the dst QNAN. 10949 # 10949 # 10950 global dst_qnan 10950 global dst_qnan 10951 dst_qnan: 10951 dst_qnan: 10952 fmov.x DST(%a1),%fp0 10952 fmov.x DST(%a1),%fp0 # return the non-signalling nan 10953 tst.b DST_EX(%a1) 10953 tst.b DST_EX(%a1) # set ccodes according to QNAN sign 10954 bmi.b dst_qnan_m 10954 bmi.b dst_qnan_m 10955 dst_qnan_p: 10955 dst_qnan_p: 10956 mov.b &nan_bmask,FPSR_CC(% 10956 mov.b &nan_bmask,FPSR_CC(%a6) 10957 rts 10957 rts 10958 dst_qnan_m: 10958 dst_qnan_m: 10959 mov.b &neg_bmask+nan_bmask 10959 mov.b &neg_bmask+nan_bmask,FPSR_CC(%a6) 10960 rts 10960 rts 10961 10961 10962 # 10962 # 10963 # src_snan(): Return the src SNAN w/ the SNA 10963 # src_snan(): Return the src SNAN w/ the SNAN bit set. 10964 # 10964 # 10965 global src_snan 10965 global src_snan 10966 src_snan: 10966 src_snan: 10967 fmov.x SRC(%a0),%fp0 10967 fmov.x SRC(%a0),%fp0 # the fmove sets the SNAN bit 10968 fmov.l %fpsr,%d0 10968 fmov.l %fpsr,%d0 # catch resulting status 10969 or.l %d0,USER_FPSR(%a6) 10969 or.l %d0,USER_FPSR(%a6) # store status 10970 rts 10970 rts 10971 10971 10972 # 10972 # 10973 # src_qnan(): Return the src QNAN. 10973 # src_qnan(): Return the src QNAN. 10974 # 10974 # 10975 global src_qnan 10975 global src_qnan 10976 src_qnan: 10976 src_qnan: 10977 fmov.x SRC(%a0),%fp0 10977 fmov.x SRC(%a0),%fp0 # return the non-signalling nan 10978 tst.b SRC_EX(%a0) 10978 tst.b SRC_EX(%a0) # set ccodes according to QNAN sign 10979 bmi.b dst_qnan_m 10979 bmi.b dst_qnan_m 10980 src_qnan_p: 10980 src_qnan_p: 10981 mov.b &nan_bmask,FPSR_CC(% 10981 mov.b &nan_bmask,FPSR_CC(%a6) 10982 rts 10982 rts 10983 src_qnan_m: 10983 src_qnan_m: 10984 mov.b &neg_bmask+nan_bmask 10984 mov.b &neg_bmask+nan_bmask,FPSR_CC(%a6) 10985 rts 10985 rts 10986 10986 10987 # 10987 # 10988 # fkern2.s: 10988 # fkern2.s: 10989 # These entry points are used by the e 10989 # These entry points are used by the exception handler 10990 # routines where an instruction is selected 10990 # routines where an instruction is selected by an index into 10991 # a large jump table corresponding to a give 10991 # a large jump table corresponding to a given instruction which 10992 # has been decoded. Flow continues here wher 10992 # has been decoded. Flow continues here where we now decode 10993 # further according to the source operand ty 10993 # further according to the source operand type. 10994 # 10994 # 10995 10995 10996 global fsinh 10996 global fsinh 10997 fsinh: 10997 fsinh: 10998 mov.b STAG(%a6),%d1 10998 mov.b STAG(%a6),%d1 10999 beq.l ssinh 10999 beq.l ssinh 11000 cmpi.b %d1,&ZERO 11000 cmpi.b %d1,&ZERO 11001 beq.l src_zero 11001 beq.l src_zero 11002 cmpi.b %d1,&INF 11002 cmpi.b %d1,&INF 11003 beq.l src_inf 11003 beq.l src_inf 11004 cmpi.b %d1,&DENORM 11004 cmpi.b %d1,&DENORM 11005 beq.l ssinhd 11005 beq.l ssinhd 11006 cmpi.b %d1,&QNAN 11006 cmpi.b %d1,&QNAN 11007 beq.l src_qnan 11007 beq.l src_qnan 11008 bra.l src_snan 11008 bra.l src_snan 11009 11009 11010 global flognp1 11010 global flognp1 11011 flognp1: 11011 flognp1: 11012 mov.b STAG(%a6),%d1 11012 mov.b STAG(%a6),%d1 11013 beq.l slognp1 11013 beq.l slognp1 11014 cmpi.b %d1,&ZERO 11014 cmpi.b %d1,&ZERO 11015 beq.l src_zero 11015 beq.l src_zero 11016 cmpi.b %d1,&INF 11016 cmpi.b %d1,&INF 11017 beq.l sopr_inf 11017 beq.l sopr_inf 11018 cmpi.b %d1,&DENORM 11018 cmpi.b %d1,&DENORM 11019 beq.l slognp1d 11019 beq.l slognp1d 11020 cmpi.b %d1,&QNAN 11020 cmpi.b %d1,&QNAN 11021 beq.l src_qnan 11021 beq.l src_qnan 11022 bra.l src_snan 11022 bra.l src_snan 11023 11023 11024 global fetoxm1 11024 global fetoxm1 11025 fetoxm1: 11025 fetoxm1: 11026 mov.b STAG(%a6),%d1 11026 mov.b STAG(%a6),%d1 11027 beq.l setoxm1 11027 beq.l setoxm1 11028 cmpi.b %d1,&ZERO 11028 cmpi.b %d1,&ZERO 11029 beq.l src_zero 11029 beq.l src_zero 11030 cmpi.b %d1,&INF 11030 cmpi.b %d1,&INF 11031 beq.l setoxm1i 11031 beq.l setoxm1i 11032 cmpi.b %d1,&DENORM 11032 cmpi.b %d1,&DENORM 11033 beq.l setoxm1d 11033 beq.l setoxm1d 11034 cmpi.b %d1,&QNAN 11034 cmpi.b %d1,&QNAN 11035 beq.l src_qnan 11035 beq.l src_qnan 11036 bra.l src_snan 11036 bra.l src_snan 11037 11037 11038 global ftanh 11038 global ftanh 11039 ftanh: 11039 ftanh: 11040 mov.b STAG(%a6),%d1 11040 mov.b STAG(%a6),%d1 11041 beq.l stanh 11041 beq.l stanh 11042 cmpi.b %d1,&ZERO 11042 cmpi.b %d1,&ZERO 11043 beq.l src_zero 11043 beq.l src_zero 11044 cmpi.b %d1,&INF 11044 cmpi.b %d1,&INF 11045 beq.l src_one 11045 beq.l src_one 11046 cmpi.b %d1,&DENORM 11046 cmpi.b %d1,&DENORM 11047 beq.l stanhd 11047 beq.l stanhd 11048 cmpi.b %d1,&QNAN 11048 cmpi.b %d1,&QNAN 11049 beq.l src_qnan 11049 beq.l src_qnan 11050 bra.l src_snan 11050 bra.l src_snan 11051 11051 11052 global fatan 11052 global fatan 11053 fatan: 11053 fatan: 11054 mov.b STAG(%a6),%d1 11054 mov.b STAG(%a6),%d1 11055 beq.l satan 11055 beq.l satan 11056 cmpi.b %d1,&ZERO 11056 cmpi.b %d1,&ZERO 11057 beq.l src_zero 11057 beq.l src_zero 11058 cmpi.b %d1,&INF 11058 cmpi.b %d1,&INF 11059 beq.l spi_2 11059 beq.l spi_2 11060 cmpi.b %d1,&DENORM 11060 cmpi.b %d1,&DENORM 11061 beq.l satand 11061 beq.l satand 11062 cmpi.b %d1,&QNAN 11062 cmpi.b %d1,&QNAN 11063 beq.l src_qnan 11063 beq.l src_qnan 11064 bra.l src_snan 11064 bra.l src_snan 11065 11065 11066 global fasin 11066 global fasin 11067 fasin: 11067 fasin: 11068 mov.b STAG(%a6),%d1 11068 mov.b STAG(%a6),%d1 11069 beq.l sasin 11069 beq.l sasin 11070 cmpi.b %d1,&ZERO 11070 cmpi.b %d1,&ZERO 11071 beq.l src_zero 11071 beq.l src_zero 11072 cmpi.b %d1,&INF 11072 cmpi.b %d1,&INF 11073 beq.l t_operr 11073 beq.l t_operr 11074 cmpi.b %d1,&DENORM 11074 cmpi.b %d1,&DENORM 11075 beq.l sasind 11075 beq.l sasind 11076 cmpi.b %d1,&QNAN 11076 cmpi.b %d1,&QNAN 11077 beq.l src_qnan 11077 beq.l src_qnan 11078 bra.l src_snan 11078 bra.l src_snan 11079 11079 11080 global fatanh 11080 global fatanh 11081 fatanh: 11081 fatanh: 11082 mov.b STAG(%a6),%d1 11082 mov.b STAG(%a6),%d1 11083 beq.l satanh 11083 beq.l satanh 11084 cmpi.b %d1,&ZERO 11084 cmpi.b %d1,&ZERO 11085 beq.l src_zero 11085 beq.l src_zero 11086 cmpi.b %d1,&INF 11086 cmpi.b %d1,&INF 11087 beq.l t_operr 11087 beq.l t_operr 11088 cmpi.b %d1,&DENORM 11088 cmpi.b %d1,&DENORM 11089 beq.l satanhd 11089 beq.l satanhd 11090 cmpi.b %d1,&QNAN 11090 cmpi.b %d1,&QNAN 11091 beq.l src_qnan 11091 beq.l src_qnan 11092 bra.l src_snan 11092 bra.l src_snan 11093 11093 11094 global fsine 11094 global fsine 11095 fsine: 11095 fsine: 11096 mov.b STAG(%a6),%d1 11096 mov.b STAG(%a6),%d1 11097 beq.l ssin 11097 beq.l ssin 11098 cmpi.b %d1,&ZERO 11098 cmpi.b %d1,&ZERO 11099 beq.l src_zero 11099 beq.l src_zero 11100 cmpi.b %d1,&INF 11100 cmpi.b %d1,&INF 11101 beq.l t_operr 11101 beq.l t_operr 11102 cmpi.b %d1,&DENORM 11102 cmpi.b %d1,&DENORM 11103 beq.l ssind 11103 beq.l ssind 11104 cmpi.b %d1,&QNAN 11104 cmpi.b %d1,&QNAN 11105 beq.l src_qnan 11105 beq.l src_qnan 11106 bra.l src_snan 11106 bra.l src_snan 11107 11107 11108 global ftan 11108 global ftan 11109 ftan: 11109 ftan: 11110 mov.b STAG(%a6),%d1 11110 mov.b STAG(%a6),%d1 11111 beq.l stan 11111 beq.l stan 11112 cmpi.b %d1,&ZERO 11112 cmpi.b %d1,&ZERO 11113 beq.l src_zero 11113 beq.l src_zero 11114 cmpi.b %d1,&INF 11114 cmpi.b %d1,&INF 11115 beq.l t_operr 11115 beq.l t_operr 11116 cmpi.b %d1,&DENORM 11116 cmpi.b %d1,&DENORM 11117 beq.l stand 11117 beq.l stand 11118 cmpi.b %d1,&QNAN 11118 cmpi.b %d1,&QNAN 11119 beq.l src_qnan 11119 beq.l src_qnan 11120 bra.l src_snan 11120 bra.l src_snan 11121 11121 11122 global fetox 11122 global fetox 11123 fetox: 11123 fetox: 11124 mov.b STAG(%a6),%d1 11124 mov.b STAG(%a6),%d1 11125 beq.l setox 11125 beq.l setox 11126 cmpi.b %d1,&ZERO 11126 cmpi.b %d1,&ZERO 11127 beq.l ld_pone 11127 beq.l ld_pone 11128 cmpi.b %d1,&INF 11128 cmpi.b %d1,&INF 11129 beq.l szr_inf 11129 beq.l szr_inf 11130 cmpi.b %d1,&DENORM 11130 cmpi.b %d1,&DENORM 11131 beq.l setoxd 11131 beq.l setoxd 11132 cmpi.b %d1,&QNAN 11132 cmpi.b %d1,&QNAN 11133 beq.l src_qnan 11133 beq.l src_qnan 11134 bra.l src_snan 11134 bra.l src_snan 11135 11135 11136 global ftwotox 11136 global ftwotox 11137 ftwotox: 11137 ftwotox: 11138 mov.b STAG(%a6),%d1 11138 mov.b STAG(%a6),%d1 11139 beq.l stwotox 11139 beq.l stwotox 11140 cmpi.b %d1,&ZERO 11140 cmpi.b %d1,&ZERO 11141 beq.l ld_pone 11141 beq.l ld_pone 11142 cmpi.b %d1,&INF 11142 cmpi.b %d1,&INF 11143 beq.l szr_inf 11143 beq.l szr_inf 11144 cmpi.b %d1,&DENORM 11144 cmpi.b %d1,&DENORM 11145 beq.l stwotoxd 11145 beq.l stwotoxd 11146 cmpi.b %d1,&QNAN 11146 cmpi.b %d1,&QNAN 11147 beq.l src_qnan 11147 beq.l src_qnan 11148 bra.l src_snan 11148 bra.l src_snan 11149 11149 11150 global ftentox 11150 global ftentox 11151 ftentox: 11151 ftentox: 11152 mov.b STAG(%a6),%d1 11152 mov.b STAG(%a6),%d1 11153 beq.l stentox 11153 beq.l stentox 11154 cmpi.b %d1,&ZERO 11154 cmpi.b %d1,&ZERO 11155 beq.l ld_pone 11155 beq.l ld_pone 11156 cmpi.b %d1,&INF 11156 cmpi.b %d1,&INF 11157 beq.l szr_inf 11157 beq.l szr_inf 11158 cmpi.b %d1,&DENORM 11158 cmpi.b %d1,&DENORM 11159 beq.l stentoxd 11159 beq.l stentoxd 11160 cmpi.b %d1,&QNAN 11160 cmpi.b %d1,&QNAN 11161 beq.l src_qnan 11161 beq.l src_qnan 11162 bra.l src_snan 11162 bra.l src_snan 11163 11163 11164 global flogn 11164 global flogn 11165 flogn: 11165 flogn: 11166 mov.b STAG(%a6),%d1 11166 mov.b STAG(%a6),%d1 11167 beq.l slogn 11167 beq.l slogn 11168 cmpi.b %d1,&ZERO 11168 cmpi.b %d1,&ZERO 11169 beq.l t_dz2 11169 beq.l t_dz2 11170 cmpi.b %d1,&INF 11170 cmpi.b %d1,&INF 11171 beq.l sopr_inf 11171 beq.l sopr_inf 11172 cmpi.b %d1,&DENORM 11172 cmpi.b %d1,&DENORM 11173 beq.l slognd 11173 beq.l slognd 11174 cmpi.b %d1,&QNAN 11174 cmpi.b %d1,&QNAN 11175 beq.l src_qnan 11175 beq.l src_qnan 11176 bra.l src_snan 11176 bra.l src_snan 11177 11177 11178 global flog10 11178 global flog10 11179 flog10: 11179 flog10: 11180 mov.b STAG(%a6),%d1 11180 mov.b STAG(%a6),%d1 11181 beq.l slog10 11181 beq.l slog10 11182 cmpi.b %d1,&ZERO 11182 cmpi.b %d1,&ZERO 11183 beq.l t_dz2 11183 beq.l t_dz2 11184 cmpi.b %d1,&INF 11184 cmpi.b %d1,&INF 11185 beq.l sopr_inf 11185 beq.l sopr_inf 11186 cmpi.b %d1,&DENORM 11186 cmpi.b %d1,&DENORM 11187 beq.l slog10d 11187 beq.l slog10d 11188 cmpi.b %d1,&QNAN 11188 cmpi.b %d1,&QNAN 11189 beq.l src_qnan 11189 beq.l src_qnan 11190 bra.l src_snan 11190 bra.l src_snan 11191 11191 11192 global flog2 11192 global flog2 11193 flog2: 11193 flog2: 11194 mov.b STAG(%a6),%d1 11194 mov.b STAG(%a6),%d1 11195 beq.l slog2 11195 beq.l slog2 11196 cmpi.b %d1,&ZERO 11196 cmpi.b %d1,&ZERO 11197 beq.l t_dz2 11197 beq.l t_dz2 11198 cmpi.b %d1,&INF 11198 cmpi.b %d1,&INF 11199 beq.l sopr_inf 11199 beq.l sopr_inf 11200 cmpi.b %d1,&DENORM 11200 cmpi.b %d1,&DENORM 11201 beq.l slog2d 11201 beq.l slog2d 11202 cmpi.b %d1,&QNAN 11202 cmpi.b %d1,&QNAN 11203 beq.l src_qnan 11203 beq.l src_qnan 11204 bra.l src_snan 11204 bra.l src_snan 11205 11205 11206 global fcosh 11206 global fcosh 11207 fcosh: 11207 fcosh: 11208 mov.b STAG(%a6),%d1 11208 mov.b STAG(%a6),%d1 11209 beq.l scosh 11209 beq.l scosh 11210 cmpi.b %d1,&ZERO 11210 cmpi.b %d1,&ZERO 11211 beq.l ld_pone 11211 beq.l ld_pone 11212 cmpi.b %d1,&INF 11212 cmpi.b %d1,&INF 11213 beq.l ld_pinf 11213 beq.l ld_pinf 11214 cmpi.b %d1,&DENORM 11214 cmpi.b %d1,&DENORM 11215 beq.l scoshd 11215 beq.l scoshd 11216 cmpi.b %d1,&QNAN 11216 cmpi.b %d1,&QNAN 11217 beq.l src_qnan 11217 beq.l src_qnan 11218 bra.l src_snan 11218 bra.l src_snan 11219 11219 11220 global facos 11220 global facos 11221 facos: 11221 facos: 11222 mov.b STAG(%a6),%d1 11222 mov.b STAG(%a6),%d1 11223 beq.l sacos 11223 beq.l sacos 11224 cmpi.b %d1,&ZERO 11224 cmpi.b %d1,&ZERO 11225 beq.l ld_ppi2 11225 beq.l ld_ppi2 11226 cmpi.b %d1,&INF 11226 cmpi.b %d1,&INF 11227 beq.l t_operr 11227 beq.l t_operr 11228 cmpi.b %d1,&DENORM 11228 cmpi.b %d1,&DENORM 11229 beq.l sacosd 11229 beq.l sacosd 11230 cmpi.b %d1,&QNAN 11230 cmpi.b %d1,&QNAN 11231 beq.l src_qnan 11231 beq.l src_qnan 11232 bra.l src_snan 11232 bra.l src_snan 11233 11233 11234 global fcos 11234 global fcos 11235 fcos: 11235 fcos: 11236 mov.b STAG(%a6),%d1 11236 mov.b STAG(%a6),%d1 11237 beq.l scos 11237 beq.l scos 11238 cmpi.b %d1,&ZERO 11238 cmpi.b %d1,&ZERO 11239 beq.l ld_pone 11239 beq.l ld_pone 11240 cmpi.b %d1,&INF 11240 cmpi.b %d1,&INF 11241 beq.l t_operr 11241 beq.l t_operr 11242 cmpi.b %d1,&DENORM 11242 cmpi.b %d1,&DENORM 11243 beq.l scosd 11243 beq.l scosd 11244 cmpi.b %d1,&QNAN 11244 cmpi.b %d1,&QNAN 11245 beq.l src_qnan 11245 beq.l src_qnan 11246 bra.l src_snan 11246 bra.l src_snan 11247 11247 11248 global fgetexp 11248 global fgetexp 11249 fgetexp: 11249 fgetexp: 11250 mov.b STAG(%a6),%d1 11250 mov.b STAG(%a6),%d1 11251 beq.l sgetexp 11251 beq.l sgetexp 11252 cmpi.b %d1,&ZERO 11252 cmpi.b %d1,&ZERO 11253 beq.l src_zero 11253 beq.l src_zero 11254 cmpi.b %d1,&INF 11254 cmpi.b %d1,&INF 11255 beq.l t_operr 11255 beq.l t_operr 11256 cmpi.b %d1,&DENORM 11256 cmpi.b %d1,&DENORM 11257 beq.l sgetexpd 11257 beq.l sgetexpd 11258 cmpi.b %d1,&QNAN 11258 cmpi.b %d1,&QNAN 11259 beq.l src_qnan 11259 beq.l src_qnan 11260 bra.l src_snan 11260 bra.l src_snan 11261 11261 11262 global fgetman 11262 global fgetman 11263 fgetman: 11263 fgetman: 11264 mov.b STAG(%a6),%d1 11264 mov.b STAG(%a6),%d1 11265 beq.l sgetman 11265 beq.l sgetman 11266 cmpi.b %d1,&ZERO 11266 cmpi.b %d1,&ZERO 11267 beq.l src_zero 11267 beq.l src_zero 11268 cmpi.b %d1,&INF 11268 cmpi.b %d1,&INF 11269 beq.l t_operr 11269 beq.l t_operr 11270 cmpi.b %d1,&DENORM 11270 cmpi.b %d1,&DENORM 11271 beq.l sgetmand 11271 beq.l sgetmand 11272 cmpi.b %d1,&QNAN 11272 cmpi.b %d1,&QNAN 11273 beq.l src_qnan 11273 beq.l src_qnan 11274 bra.l src_snan 11274 bra.l src_snan 11275 11275 11276 global fsincos 11276 global fsincos 11277 fsincos: 11277 fsincos: 11278 mov.b STAG(%a6),%d1 11278 mov.b STAG(%a6),%d1 11279 beq.l ssincos 11279 beq.l ssincos 11280 cmpi.b %d1,&ZERO 11280 cmpi.b %d1,&ZERO 11281 beq.l ssincosz 11281 beq.l ssincosz 11282 cmpi.b %d1,&INF 11282 cmpi.b %d1,&INF 11283 beq.l ssincosi 11283 beq.l ssincosi 11284 cmpi.b %d1,&DENORM 11284 cmpi.b %d1,&DENORM 11285 beq.l ssincosd 11285 beq.l ssincosd 11286 cmpi.b %d1,&QNAN 11286 cmpi.b %d1,&QNAN 11287 beq.l ssincosqnan 11287 beq.l ssincosqnan 11288 bra.l ssincossnan 11288 bra.l ssincossnan 11289 11289 11290 global fmod 11290 global fmod 11291 fmod: 11291 fmod: 11292 mov.b STAG(%a6),%d1 11292 mov.b STAG(%a6),%d1 11293 beq.l smod_snorm 11293 beq.l smod_snorm 11294 cmpi.b %d1,&ZERO 11294 cmpi.b %d1,&ZERO 11295 beq.l smod_szero 11295 beq.l smod_szero 11296 cmpi.b %d1,&INF 11296 cmpi.b %d1,&INF 11297 beq.l smod_sinf 11297 beq.l smod_sinf 11298 cmpi.b %d1,&DENORM 11298 cmpi.b %d1,&DENORM 11299 beq.l smod_sdnrm 11299 beq.l smod_sdnrm 11300 cmpi.b %d1,&QNAN 11300 cmpi.b %d1,&QNAN 11301 beq.l sop_sqnan 11301 beq.l sop_sqnan 11302 bra.l sop_ssnan 11302 bra.l sop_ssnan 11303 11303 11304 global frem 11304 global frem 11305 frem: 11305 frem: 11306 mov.b STAG(%a6),%d1 11306 mov.b STAG(%a6),%d1 11307 beq.l srem_snorm 11307 beq.l srem_snorm 11308 cmpi.b %d1,&ZERO 11308 cmpi.b %d1,&ZERO 11309 beq.l srem_szero 11309 beq.l srem_szero 11310 cmpi.b %d1,&INF 11310 cmpi.b %d1,&INF 11311 beq.l srem_sinf 11311 beq.l srem_sinf 11312 cmpi.b %d1,&DENORM 11312 cmpi.b %d1,&DENORM 11313 beq.l srem_sdnrm 11313 beq.l srem_sdnrm 11314 cmpi.b %d1,&QNAN 11314 cmpi.b %d1,&QNAN 11315 beq.l sop_sqnan 11315 beq.l sop_sqnan 11316 bra.l sop_ssnan 11316 bra.l sop_ssnan 11317 11317 11318 global fscale 11318 global fscale 11319 fscale: 11319 fscale: 11320 mov.b STAG(%a6),%d1 11320 mov.b STAG(%a6),%d1 11321 beq.l sscale_snorm 11321 beq.l sscale_snorm 11322 cmpi.b %d1,&ZERO 11322 cmpi.b %d1,&ZERO 11323 beq.l sscale_szero 11323 beq.l sscale_szero 11324 cmpi.b %d1,&INF 11324 cmpi.b %d1,&INF 11325 beq.l sscale_sinf 11325 beq.l sscale_sinf 11326 cmpi.b %d1,&DENORM 11326 cmpi.b %d1,&DENORM 11327 beq.l sscale_sdnrm 11327 beq.l sscale_sdnrm 11328 cmpi.b %d1,&QNAN 11328 cmpi.b %d1,&QNAN 11329 beq.l sop_sqnan 11329 beq.l sop_sqnan 11330 bra.l sop_ssnan 11330 bra.l sop_ssnan 11331 11331 11332 ############################################ 11332 ######################################################################### 11333 # XDEF ************************************* 11333 # XDEF **************************************************************** # 11334 # fgen_except(): catch an exception du 11334 # fgen_except(): catch an exception during transcendental # 11335 # emulation 11335 # emulation # 11336 # 11336 # # 11337 # XREF ************************************* 11337 # XREF **************************************************************** # 11338 # fmul() - emulate a multiply instruct 11338 # fmul() - emulate a multiply instruction # 11339 # fadd() - emulate an add instruction 11339 # fadd() - emulate an add instruction # 11340 # fin() - emulate an fmove instruction 11340 # fin() - emulate an fmove instruction # 11341 # 11341 # # 11342 # INPUT ************************************ 11342 # INPUT *************************************************************** # 11343 # fp0 = destination operand 11343 # fp0 = destination operand # 11344 # d0 = type of instruction that took 11344 # d0 = type of instruction that took exception # 11345 # fsave frame = source operand 11345 # fsave frame = source operand # 11346 # 11346 # # 11347 # OUTPUT *********************************** 11347 # OUTPUT ************************************************************** # 11348 # fp0 = result 11348 # fp0 = result # 11349 # fp1 = EXOP 11349 # fp1 = EXOP # 11350 # 11350 # # 11351 # ALGORITHM ******************************** 11351 # ALGORITHM *********************************************************** # 11352 # An exception occurred on the last in 11352 # An exception occurred on the last instruction of the # 11353 # transcendental emulation. hopefully, this 11353 # transcendental emulation. hopefully, this won't be happening much # 11354 # because it will be VERY slow. 11354 # because it will be VERY slow. # 11355 # The only exceptions capable of passi 11355 # The only exceptions capable of passing through here are # 11356 # Overflow, Underflow, and Unsupported Data 11356 # Overflow, Underflow, and Unsupported Data Type. # 11357 # 11357 # # 11358 ############################################ 11358 ######################################################################### 11359 11359 11360 global fgen_except 11360 global fgen_except 11361 fgen_except: 11361 fgen_except: 11362 cmpi.b 0x3(%sp),&0x7 11362 cmpi.b 0x3(%sp),&0x7 # is exception UNSUPP? 11363 beq.b fge_unsupp 11363 beq.b fge_unsupp # yes 11364 11364 11365 mov.b &NORM,STAG(%a6) 11365 mov.b &NORM,STAG(%a6) 11366 11366 11367 fge_cont: 11367 fge_cont: 11368 mov.b &NORM,DTAG(%a6) 11368 mov.b &NORM,DTAG(%a6) 11369 11369 11370 # ok, I have a problem with putting the dst 11370 # ok, I have a problem with putting the dst op at FP_DST. the emulation 11371 # routines aren't supposed to alter the oper 11371 # routines aren't supposed to alter the operands but we've just squashed 11372 # FP_DST here... 11372 # FP_DST here... 11373 11373 11374 # 8/17/93 - this turns out to be more of a " 11374 # 8/17/93 - this turns out to be more of a "cleanliness" standpoint 11375 # then a potential bug. to begin with, only 11375 # then a potential bug. to begin with, only the dyadic functions 11376 # frem,fmod, and fscale would get the dst tr 11376 # frem,fmod, and fscale would get the dst trashed here. But, for 11377 # the 060SP, the FP_DST is never used again 11377 # the 060SP, the FP_DST is never used again anyways. 11378 fmovm.x &0x80,FP_DST(%a6) 11378 fmovm.x &0x80,FP_DST(%a6) # dst op is in fp0 11379 11379 11380 lea 0x4(%sp),%a0 11380 lea 0x4(%sp),%a0 # pass: ptr to src op 11381 lea FP_DST(%a6),%a1 11381 lea FP_DST(%a6),%a1 # pass: ptr to dst op 11382 11382 11383 cmpi.b %d1,&FMOV_OP 11383 cmpi.b %d1,&FMOV_OP 11384 beq.b fge_fin 11384 beq.b fge_fin # it was an "fmov" 11385 cmpi.b %d1,&FADD_OP 11385 cmpi.b %d1,&FADD_OP 11386 beq.b fge_fadd 11386 beq.b fge_fadd # it was an "fadd" 11387 fge_fmul: 11387 fge_fmul: 11388 bsr.l fmul 11388 bsr.l fmul 11389 rts 11389 rts 11390 fge_fadd: 11390 fge_fadd: 11391 bsr.l fadd 11391 bsr.l fadd 11392 rts 11392 rts 11393 fge_fin: 11393 fge_fin: 11394 bsr.l fin 11394 bsr.l fin 11395 rts 11395 rts 11396 11396 11397 fge_unsupp: 11397 fge_unsupp: 11398 mov.b &DENORM,STAG(%a6) 11398 mov.b &DENORM,STAG(%a6) 11399 bra.b fge_cont 11399 bra.b fge_cont 11400 11400 11401 # 11401 # 11402 # This table holds the offsets of the emulat 11402 # This table holds the offsets of the emulation routines for each individual 11403 # math operation relative to the address of 11403 # math operation relative to the address of this table. Included are 11404 # routines like fadd/fmul/fabs as well as th 11404 # routines like fadd/fmul/fabs as well as the transcendentals. 11405 # The location within the table is determine 11405 # The location within the table is determined by the extension bits of the 11406 # operation longword. 11406 # operation longword. 11407 # 11407 # 11408 11408 11409 swbeg &109 11409 swbeg &109 11410 tbl_unsupp: 11410 tbl_unsupp: 11411 long fin - tb 11411 long fin - tbl_unsupp # 00: fmove 11412 long fint - tb 11412 long fint - tbl_unsupp # 01: fint 11413 long fsinh - tb 11413 long fsinh - tbl_unsupp # 02: fsinh 11414 long fintrz - tb 11414 long fintrz - tbl_unsupp # 03: fintrz 11415 long fsqrt - tb 11415 long fsqrt - tbl_unsupp # 04: fsqrt 11416 long tbl_unsupp - tb 11416 long tbl_unsupp - tbl_unsupp 11417 long flognp1 - tb 11417 long flognp1 - tbl_unsupp # 06: flognp1 11418 long tbl_unsupp - tb 11418 long tbl_unsupp - tbl_unsupp 11419 long fetoxm1 - tb 11419 long fetoxm1 - tbl_unsupp # 08: fetoxm1 11420 long ftanh - tb 11420 long ftanh - tbl_unsupp # 09: ftanh 11421 long fatan - tb 11421 long fatan - tbl_unsupp # 0a: fatan 11422 long tbl_unsupp - tb 11422 long tbl_unsupp - tbl_unsupp 11423 long fasin - tb 11423 long fasin - tbl_unsupp # 0c: fasin 11424 long fatanh - tb 11424 long fatanh - tbl_unsupp # 0d: fatanh 11425 long fsine - tb 11425 long fsine - tbl_unsupp # 0e: fsin 11426 long ftan - tb 11426 long ftan - tbl_unsupp # 0f: ftan 11427 long fetox - tb 11427 long fetox - tbl_unsupp # 10: fetox 11428 long ftwotox - tb 11428 long ftwotox - tbl_unsupp # 11: ftwotox 11429 long ftentox - tb 11429 long ftentox - tbl_unsupp # 12: ftentox 11430 long tbl_unsupp - tb 11430 long tbl_unsupp - tbl_unsupp 11431 long flogn - tb 11431 long flogn - tbl_unsupp # 14: flogn 11432 long flog10 - tb 11432 long flog10 - tbl_unsupp # 15: flog10 11433 long flog2 - tb 11433 long flog2 - tbl_unsupp # 16: flog2 11434 long tbl_unsupp - tb 11434 long tbl_unsupp - tbl_unsupp 11435 long fabs - tb 11435 long fabs - tbl_unsupp # 18: fabs 11436 long fcosh - tb 11436 long fcosh - tbl_unsupp # 19: fcosh 11437 long fneg - tb 11437 long fneg - tbl_unsupp # 1a: fneg 11438 long tbl_unsupp - tb 11438 long tbl_unsupp - tbl_unsupp 11439 long facos - tb 11439 long facos - tbl_unsupp # 1c: facos 11440 long fcos - tb 11440 long fcos - tbl_unsupp # 1d: fcos 11441 long fgetexp - tb 11441 long fgetexp - tbl_unsupp # 1e: fgetexp 11442 long fgetman - tb 11442 long fgetman - tbl_unsupp # 1f: fgetman 11443 long fdiv - tb 11443 long fdiv - tbl_unsupp # 20: fdiv 11444 long fmod - tb 11444 long fmod - tbl_unsupp # 21: fmod 11445 long fadd - tb 11445 long fadd - tbl_unsupp # 22: fadd 11446 long fmul - tb 11446 long fmul - tbl_unsupp # 23: fmul 11447 long fsgldiv - tb 11447 long fsgldiv - tbl_unsupp # 24: fsgldiv 11448 long frem - tb 11448 long frem - tbl_unsupp # 25: frem 11449 long fscale - tb 11449 long fscale - tbl_unsupp # 26: fscale 11450 long fsglmul - tb 11450 long fsglmul - tbl_unsupp # 27: fsglmul 11451 long fsub - tb 11451 long fsub - tbl_unsupp # 28: fsub 11452 long tbl_unsupp - tb 11452 long tbl_unsupp - tbl_unsupp 11453 long tbl_unsupp - tb 11453 long tbl_unsupp - tbl_unsupp 11454 long tbl_unsupp - tb 11454 long tbl_unsupp - tbl_unsupp 11455 long tbl_unsupp - tb 11455 long tbl_unsupp - tbl_unsupp 11456 long tbl_unsupp - tb 11456 long tbl_unsupp - tbl_unsupp 11457 long tbl_unsupp - tb 11457 long tbl_unsupp - tbl_unsupp 11458 long tbl_unsupp - tb 11458 long tbl_unsupp - tbl_unsupp 11459 long fsincos - tb 11459 long fsincos - tbl_unsupp # 30: fsincos 11460 long fsincos - tb 11460 long fsincos - tbl_unsupp # 31: fsincos 11461 long fsincos - tb 11461 long fsincos - tbl_unsupp # 32: fsincos 11462 long fsincos - tb 11462 long fsincos - tbl_unsupp # 33: fsincos 11463 long fsincos - tb 11463 long fsincos - tbl_unsupp # 34: fsincos 11464 long fsincos - tb 11464 long fsincos - tbl_unsupp # 35: fsincos 11465 long fsincos - tb 11465 long fsincos - tbl_unsupp # 36: fsincos 11466 long fsincos - tb 11466 long fsincos - tbl_unsupp # 37: fsincos 11467 long fcmp - tb 11467 long fcmp - tbl_unsupp # 38: fcmp 11468 long tbl_unsupp - tb 11468 long tbl_unsupp - tbl_unsupp 11469 long ftst - tb 11469 long ftst - tbl_unsupp # 3a: ftst 11470 long tbl_unsupp - tb 11470 long tbl_unsupp - tbl_unsupp 11471 long tbl_unsupp - tb 11471 long tbl_unsupp - tbl_unsupp 11472 long tbl_unsupp - tb 11472 long tbl_unsupp - tbl_unsupp 11473 long tbl_unsupp - tb 11473 long tbl_unsupp - tbl_unsupp 11474 long tbl_unsupp - tb 11474 long tbl_unsupp - tbl_unsupp 11475 long fsin - tb 11475 long fsin - tbl_unsupp # 40: fsmove 11476 long fssqrt - tb 11476 long fssqrt - tbl_unsupp # 41: fssqrt 11477 long tbl_unsupp - tb 11477 long tbl_unsupp - tbl_unsupp 11478 long tbl_unsupp - tb 11478 long tbl_unsupp - tbl_unsupp 11479 long fdin - tb 11479 long fdin - tbl_unsupp # 44: fdmove 11480 long fdsqrt - tb 11480 long fdsqrt - tbl_unsupp # 45: fdsqrt 11481 long tbl_unsupp - tb 11481 long tbl_unsupp - tbl_unsupp 11482 long tbl_unsupp - tb 11482 long tbl_unsupp - tbl_unsupp 11483 long tbl_unsupp - tb 11483 long tbl_unsupp - tbl_unsupp 11484 long tbl_unsupp - tb 11484 long tbl_unsupp - tbl_unsupp 11485 long tbl_unsupp - tb 11485 long tbl_unsupp - tbl_unsupp 11486 long tbl_unsupp - tb 11486 long tbl_unsupp - tbl_unsupp 11487 long tbl_unsupp - tb 11487 long tbl_unsupp - tbl_unsupp 11488 long tbl_unsupp - tb 11488 long tbl_unsupp - tbl_unsupp 11489 long tbl_unsupp - tb 11489 long tbl_unsupp - tbl_unsupp 11490 long tbl_unsupp - tb 11490 long tbl_unsupp - tbl_unsupp 11491 long tbl_unsupp - tb 11491 long tbl_unsupp - tbl_unsupp 11492 long tbl_unsupp - tb 11492 long tbl_unsupp - tbl_unsupp 11493 long tbl_unsupp - tb 11493 long tbl_unsupp - tbl_unsupp 11494 long tbl_unsupp - tb 11494 long tbl_unsupp - tbl_unsupp 11495 long tbl_unsupp - tb 11495 long tbl_unsupp - tbl_unsupp 11496 long tbl_unsupp - tb 11496 long tbl_unsupp - tbl_unsupp 11497 long tbl_unsupp - tb 11497 long tbl_unsupp - tbl_unsupp 11498 long tbl_unsupp - tb 11498 long tbl_unsupp - tbl_unsupp 11499 long fsabs - tb 11499 long fsabs - tbl_unsupp # 58: fsabs 11500 long tbl_unsupp - tb 11500 long tbl_unsupp - tbl_unsupp 11501 long fsneg - tb 11501 long fsneg - tbl_unsupp # 5a: fsneg 11502 long tbl_unsupp - tb 11502 long tbl_unsupp - tbl_unsupp 11503 long fdabs - tb 11503 long fdabs - tbl_unsupp # 5c: fdabs 11504 long tbl_unsupp - tb 11504 long tbl_unsupp - tbl_unsupp 11505 long fdneg - tb 11505 long fdneg - tbl_unsupp # 5e: fdneg 11506 long tbl_unsupp - tb 11506 long tbl_unsupp - tbl_unsupp 11507 long fsdiv - tb 11507 long fsdiv - tbl_unsupp # 60: fsdiv 11508 long tbl_unsupp - tb 11508 long tbl_unsupp - tbl_unsupp 11509 long fsadd - tb 11509 long fsadd - tbl_unsupp # 62: fsadd 11510 long fsmul - tb 11510 long fsmul - tbl_unsupp # 63: fsmul 11511 long fddiv - tb 11511 long fddiv - tbl_unsupp # 64: fddiv 11512 long tbl_unsupp - tb 11512 long tbl_unsupp - tbl_unsupp 11513 long fdadd - tb 11513 long fdadd - tbl_unsupp # 66: fdadd 11514 long fdmul - tb 11514 long fdmul - tbl_unsupp # 67: fdmul 11515 long fssub - tb 11515 long fssub - tbl_unsupp # 68: fssub 11516 long tbl_unsupp - tb 11516 long tbl_unsupp - tbl_unsupp 11517 long tbl_unsupp - tb 11517 long tbl_unsupp - tbl_unsupp 11518 long tbl_unsupp - tb 11518 long tbl_unsupp - tbl_unsupp 11519 long fdsub - tb 11519 long fdsub - tbl_unsupp # 6c: fdsub 11520 11520 11521 ############################################ 11521 ######################################################################### 11522 # XDEF ************************************* 11522 # XDEF **************************************************************** # 11523 # fmul(): emulates the fmul instructio 11523 # fmul(): emulates the fmul instruction # 11524 # fsmul(): emulates the fsmul instruct 11524 # fsmul(): emulates the fsmul instruction # 11525 # fdmul(): emulates the fdmul instruct 11525 # fdmul(): emulates the fdmul instruction # 11526 # 11526 # # 11527 # XREF ************************************* 11527 # XREF **************************************************************** # 11528 # scale_to_zero_src() - scale src expo 11528 # scale_to_zero_src() - scale src exponent to zero # 11529 # scale_to_zero_dst() - scale dst expo 11529 # scale_to_zero_dst() - scale dst exponent to zero # 11530 # unf_res() - return default underflow 11530 # unf_res() - return default underflow result # 11531 # ovf_res() - return default overflow 11531 # ovf_res() - return default overflow result # 11532 # res_qnan() - return QNAN result 11532 # res_qnan() - return QNAN result # 11533 # res_snan() - return SNAN result 11533 # res_snan() - return SNAN result # 11534 # 11534 # # 11535 # INPUT ************************************ 11535 # INPUT *************************************************************** # 11536 # a0 = pointer to extended precision s 11536 # a0 = pointer to extended precision source operand # 11537 # a1 = pointer to extended precision d 11537 # a1 = pointer to extended precision destination operand # 11538 # d0 rnd prec,mode 11538 # d0 rnd prec,mode # 11539 # 11539 # # 11540 # OUTPUT *********************************** 11540 # OUTPUT ************************************************************** # 11541 # fp0 = result 11541 # fp0 = result # 11542 # fp1 = EXOP (if exception occurred) 11542 # fp1 = EXOP (if exception occurred) # 11543 # 11543 # # 11544 # ALGORITHM ******************************** 11544 # ALGORITHM *********************************************************** # 11545 # Handle NANs, infinities, and zeroes 11545 # Handle NANs, infinities, and zeroes as special cases. Divide # 11546 # norms/denorms into ext/sgl/dbl precision. 11546 # norms/denorms into ext/sgl/dbl precision. # 11547 # For norms/denorms, scale the exponen 11547 # For norms/denorms, scale the exponents such that a multiply # 11548 # instruction won't cause an exception. Use 11548 # instruction won't cause an exception. Use the regular fmul to # 11549 # compute a result. Check if the regular ope 11549 # compute a result. Check if the regular operands would have taken # 11550 # an exception. If so, return the default ov 11550 # an exception. If so, return the default overflow/underflow result # 11551 # and return the EXOP if exceptions are enab 11551 # and return the EXOP if exceptions are enabled. Else, scale the # 11552 # result operand to the proper exponent. 11552 # result operand to the proper exponent. # 11553 # 11553 # # 11554 ############################################ 11554 ######################################################################### 11555 11555 11556 align 0x10 11556 align 0x10 11557 tbl_fmul_ovfl: 11557 tbl_fmul_ovfl: 11558 long 0x3fff - 0x7ffe 11558 long 0x3fff - 0x7ffe # ext_max 11559 long 0x3fff - 0x407e 11559 long 0x3fff - 0x407e # sgl_max 11560 long 0x3fff - 0x43fe 11560 long 0x3fff - 0x43fe # dbl_max 11561 tbl_fmul_unfl: 11561 tbl_fmul_unfl: 11562 long 0x3fff + 0x0001 11562 long 0x3fff + 0x0001 # ext_unfl 11563 long 0x3fff - 0x3f80 11563 long 0x3fff - 0x3f80 # sgl_unfl 11564 long 0x3fff - 0x3c00 11564 long 0x3fff - 0x3c00 # dbl_unfl 11565 11565 11566 global fsmul 11566 global fsmul 11567 fsmul: 11567 fsmul: 11568 andi.b &0x30,%d0 11568 andi.b &0x30,%d0 # clear rnd prec 11569 ori.b &s_mode*0x10,%d0 11569 ori.b &s_mode*0x10,%d0 # insert sgl prec 11570 bra.b fmul 11570 bra.b fmul 11571 11571 11572 global fdmul 11572 global fdmul 11573 fdmul: 11573 fdmul: 11574 andi.b &0x30,%d0 11574 andi.b &0x30,%d0 11575 ori.b &d_mode*0x10,%d0 11575 ori.b &d_mode*0x10,%d0 # insert dbl prec 11576 11576 11577 global fmul 11577 global fmul 11578 fmul: 11578 fmul: 11579 mov.l %d0,L_SCR3(%a6) 11579 mov.l %d0,L_SCR3(%a6) # store rnd info 11580 11580 11581 clr.w %d1 11581 clr.w %d1 11582 mov.b DTAG(%a6),%d1 11582 mov.b DTAG(%a6),%d1 11583 lsl.b &0x3,%d1 11583 lsl.b &0x3,%d1 11584 or.b STAG(%a6),%d1 11584 or.b STAG(%a6),%d1 # combine src tags 11585 bne.w fmul_not_norm 11585 bne.w fmul_not_norm # optimize on non-norm input 11586 11586 11587 fmul_norm: 11587 fmul_norm: 11588 mov.w DST_EX(%a1),FP_SCR1_ 11588 mov.w DST_EX(%a1),FP_SCR1_EX(%a6) 11589 mov.l DST_HI(%a1),FP_SCR1_ 11589 mov.l DST_HI(%a1),FP_SCR1_HI(%a6) 11590 mov.l DST_LO(%a1),FP_SCR1_ 11590 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 11591 11591 11592 mov.w SRC_EX(%a0),FP_SCR0_ 11592 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 11593 mov.l SRC_HI(%a0),FP_SCR0_ 11593 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 11594 mov.l SRC_LO(%a0),FP_SCR0_ 11594 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 11595 11595 11596 bsr.l scale_to_zero_src 11596 bsr.l scale_to_zero_src # scale src exponent 11597 mov.l %d0,-(%sp) 11597 mov.l %d0,-(%sp) # save scale factor 1 11598 11598 11599 bsr.l scale_to_zero_dst 11599 bsr.l scale_to_zero_dst # scale dst exponent 11600 11600 11601 add.l %d0,(%sp) 11601 add.l %d0,(%sp) # SCALE_FACTOR = scale1 + scale2 11602 11602 11603 mov.w 2+L_SCR3(%a6),%d1 11603 mov.w 2+L_SCR3(%a6),%d1 # fetch precision 11604 lsr.b &0x6,%d1 11604 lsr.b &0x6,%d1 # shift to lo bits 11605 mov.l (%sp)+,%d0 11605 mov.l (%sp)+,%d0 # load S.F. 11606 cmp.l %d0,(tbl_fmul_ovfl.w 11606 cmp.l %d0,(tbl_fmul_ovfl.w,%pc,%d1.w*4) # would result ovfl? 11607 beq.w fmul_may_ovfl 11607 beq.w fmul_may_ovfl # result may rnd to overflow 11608 blt.w fmul_ovfl 11608 blt.w fmul_ovfl # result will overflow 11609 11609 11610 cmp.l %d0,(tbl_fmul_unfl.w 11610 cmp.l %d0,(tbl_fmul_unfl.w,%pc,%d1.w*4) # would result unfl? 11611 beq.w fmul_may_unfl 11611 beq.w fmul_may_unfl # result may rnd to no unfl 11612 bgt.w fmul_unfl 11612 bgt.w fmul_unfl # result will underflow 11613 11613 11614 # 11614 # 11615 # NORMAL: 11615 # NORMAL: 11616 # - the result of the multiply operation wil 11616 # - the result of the multiply operation will neither overflow nor underflow. 11617 # - do the multiply to the proper precision 11617 # - do the multiply to the proper precision and rounding mode. 11618 # - scale the result exponent using the scal 11618 # - scale the result exponent using the scale factor. if both operands were 11619 # normalized then we really don't need to go 11619 # normalized then we really don't need to go through this scaling. but for now, 11620 # this will do. 11620 # this will do. 11621 # 11621 # 11622 fmul_normal: 11622 fmul_normal: 11623 fmovm.x FP_SCR1(%a6),&0x80 11623 fmovm.x FP_SCR1(%a6),&0x80 # load dst operand 11624 11624 11625 fmov.l L_SCR3(%a6),%fpcr 11625 fmov.l L_SCR3(%a6),%fpcr # set FPCR 11626 fmov.l &0x0,%fpsr 11626 fmov.l &0x0,%fpsr # clear FPSR 11627 11627 11628 fmul.x FP_SCR0(%a6),%fp0 11628 fmul.x FP_SCR0(%a6),%fp0 # execute multiply 11629 11629 11630 fmov.l %fpsr,%d1 11630 fmov.l %fpsr,%d1 # save status 11631 fmov.l &0x0,%fpcr 11631 fmov.l &0x0,%fpcr # clear FPCR 11632 11632 11633 or.l %d1,USER_FPSR(%a6) 11633 or.l %d1,USER_FPSR(%a6) # save INEX2,N 11634 11634 11635 fmul_normal_exit: 11635 fmul_normal_exit: 11636 fmovm.x &0x80,FP_SCR0(%a6) 11636 fmovm.x &0x80,FP_SCR0(%a6) # store out result 11637 mov.l %d2,-(%sp) 11637 mov.l %d2,-(%sp) # save d2 11638 mov.w FP_SCR0_EX(%a6),%d1 11638 mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp} 11639 mov.l %d1,%d2 11639 mov.l %d1,%d2 # make a copy 11640 andi.l &0x7fff,%d1 11640 andi.l &0x7fff,%d1 # strip sign 11641 andi.w &0x8000,%d2 11641 andi.w &0x8000,%d2 # keep old sign 11642 sub.l %d0,%d1 11642 sub.l %d0,%d1 # add scale factor 11643 or.w %d2,%d1 11643 or.w %d2,%d1 # concat old sign,new exp 11644 mov.w %d1,FP_SCR0_EX(%a6) 11644 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 11645 mov.l (%sp)+,%d2 11645 mov.l (%sp)+,%d2 # restore d2 11646 fmovm.x FP_SCR0(%a6),&0x80 11646 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 11647 rts 11647 rts 11648 11648 11649 # 11649 # 11650 # OVERFLOW: 11650 # OVERFLOW: 11651 # - the result of the multiply operation is 11651 # - the result of the multiply operation is an overflow. 11652 # - do the multiply to the proper precision 11652 # - do the multiply to the proper precision and rounding mode in order to 11653 # set the inexact bits. 11653 # set the inexact bits. 11654 # - calculate the default result and return 11654 # - calculate the default result and return it in fp0. 11655 # - if overflow or inexact is enabled, we ne 11655 # - if overflow or inexact is enabled, we need a multiply result rounded to 11656 # extended precision. if the original operat 11656 # extended precision. if the original operation was extended, then we have this 11657 # result. if the original operation was sing 11657 # result. if the original operation was single or double, we have to do another 11658 # multiply using extended precision and the 11658 # multiply using extended precision and the correct rounding mode. the result 11659 # of this operation then has its exponent sc 11659 # of this operation then has its exponent scaled by -0x6000 to create the 11660 # exceptional operand. 11660 # exceptional operand. 11661 # 11661 # 11662 fmul_ovfl: 11662 fmul_ovfl: 11663 fmovm.x FP_SCR1(%a6),&0x80 11663 fmovm.x FP_SCR1(%a6),&0x80 # load dst operand 11664 11664 11665 fmov.l L_SCR3(%a6),%fpcr 11665 fmov.l L_SCR3(%a6),%fpcr # set FPCR 11666 fmov.l &0x0,%fpsr 11666 fmov.l &0x0,%fpsr # clear FPSR 11667 11667 11668 fmul.x FP_SCR0(%a6),%fp0 11668 fmul.x FP_SCR0(%a6),%fp0 # execute multiply 11669 11669 11670 fmov.l %fpsr,%d1 11670 fmov.l %fpsr,%d1 # save status 11671 fmov.l &0x0,%fpcr 11671 fmov.l &0x0,%fpcr # clear FPCR 11672 11672 11673 or.l %d1,USER_FPSR(%a6) 11673 or.l %d1,USER_FPSR(%a6) # save INEX2,N 11674 11674 11675 # save setting this until now because this i 11675 # save setting this until now because this is where fmul_may_ovfl may jump in 11676 fmul_ovfl_tst: 11676 fmul_ovfl_tst: 11677 or.l &ovfl_inx_mask,USER_ 11677 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 11678 11678 11679 mov.b FPCR_ENABLE(%a6),%d1 11679 mov.b FPCR_ENABLE(%a6),%d1 11680 andi.b &0x13,%d1 11680 andi.b &0x13,%d1 # is OVFL or INEX enabled? 11681 bne.b fmul_ovfl_ena 11681 bne.b fmul_ovfl_ena # yes 11682 11682 11683 # calculate the default result 11683 # calculate the default result 11684 fmul_ovfl_dis: 11684 fmul_ovfl_dis: 11685 btst &neg_bit,FPSR_CC(%a6 11685 btst &neg_bit,FPSR_CC(%a6) # is result negative? 11686 sne %d1 11686 sne %d1 # set sign param accordingly 11687 mov.l L_SCR3(%a6),%d0 11687 mov.l L_SCR3(%a6),%d0 # pass rnd prec,mode 11688 bsr.l ovf_res 11688 bsr.l ovf_res # calculate default result 11689 or.b %d0,FPSR_CC(%a6) 11689 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 11690 fmovm.x (%a0),&0x80 11690 fmovm.x (%a0),&0x80 # return default result in fp0 11691 rts 11691 rts 11692 11692 11693 # 11693 # 11694 # OVFL is enabled; Create EXOP: 11694 # OVFL is enabled; Create EXOP: 11695 # - if precision is extended, then we have t 11695 # - if precision is extended, then we have the EXOP. simply bias the exponent 11696 # with an extra -0x6000. if the precision is 11696 # with an extra -0x6000. if the precision is single or double, we need to 11697 # calculate a result rounded to extended pre 11697 # calculate a result rounded to extended precision. 11698 # 11698 # 11699 fmul_ovfl_ena: 11699 fmul_ovfl_ena: 11700 mov.l L_SCR3(%a6),%d1 11700 mov.l L_SCR3(%a6),%d1 11701 andi.b &0xc0,%d1 11701 andi.b &0xc0,%d1 # test the rnd prec 11702 bne.b fmul_ovfl_ena_sd 11702 bne.b fmul_ovfl_ena_sd # it's sgl or dbl 11703 11703 11704 fmul_ovfl_ena_cont: 11704 fmul_ovfl_ena_cont: 11705 fmovm.x &0x80,FP_SCR0(%a6) 11705 fmovm.x &0x80,FP_SCR0(%a6) # move result to stack 11706 11706 11707 mov.l %d2,-(%sp) 11707 mov.l %d2,-(%sp) # save d2 11708 mov.w FP_SCR0_EX(%a6),%d1 11708 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 11709 mov.w %d1,%d2 11709 mov.w %d1,%d2 # make a copy 11710 andi.l &0x7fff,%d1 11710 andi.l &0x7fff,%d1 # strip sign 11711 sub.l %d0,%d1 11711 sub.l %d0,%d1 # add scale factor 11712 subi.l &0x6000,%d1 11712 subi.l &0x6000,%d1 # subtract bias 11713 andi.w &0x7fff,%d1 11713 andi.w &0x7fff,%d1 # clear sign bit 11714 andi.w &0x8000,%d2 11714 andi.w &0x8000,%d2 # keep old sign 11715 or.w %d2,%d1 11715 or.w %d2,%d1 # concat old sign,new exp 11716 mov.w %d1,FP_SCR0_EX(%a6) 11716 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 11717 mov.l (%sp)+,%d2 11717 mov.l (%sp)+,%d2 # restore d2 11718 fmovm.x FP_SCR0(%a6),&0x40 11718 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 11719 bra.b fmul_ovfl_dis 11719 bra.b fmul_ovfl_dis 11720 11720 11721 fmul_ovfl_ena_sd: 11721 fmul_ovfl_ena_sd: 11722 fmovm.x FP_SCR1(%a6),&0x80 11722 fmovm.x FP_SCR1(%a6),&0x80 # load dst operand 11723 11723 11724 mov.l L_SCR3(%a6),%d1 11724 mov.l L_SCR3(%a6),%d1 11725 andi.b &0x30,%d1 11725 andi.b &0x30,%d1 # keep rnd mode only 11726 fmov.l %d1,%fpcr 11726 fmov.l %d1,%fpcr # set FPCR 11727 11727 11728 fmul.x FP_SCR0(%a6),%fp0 11728 fmul.x FP_SCR0(%a6),%fp0 # execute multiply 11729 11729 11730 fmov.l &0x0,%fpcr 11730 fmov.l &0x0,%fpcr # clear FPCR 11731 bra.b fmul_ovfl_ena_cont 11731 bra.b fmul_ovfl_ena_cont 11732 11732 11733 # 11733 # 11734 # may OVERFLOW: 11734 # may OVERFLOW: 11735 # - the result of the multiply operation MAY 11735 # - the result of the multiply operation MAY overflow. 11736 # - do the multiply to the proper precision 11736 # - do the multiply to the proper precision and rounding mode in order to 11737 # set the inexact bits. 11737 # set the inexact bits. 11738 # - calculate the default result and return 11738 # - calculate the default result and return it in fp0. 11739 # 11739 # 11740 fmul_may_ovfl: 11740 fmul_may_ovfl: 11741 fmovm.x FP_SCR1(%a6),&0x80 11741 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 11742 11742 11743 fmov.l L_SCR3(%a6),%fpcr 11743 fmov.l L_SCR3(%a6),%fpcr # set FPCR 11744 fmov.l &0x0,%fpsr 11744 fmov.l &0x0,%fpsr # clear FPSR 11745 11745 11746 fmul.x FP_SCR0(%a6),%fp0 11746 fmul.x FP_SCR0(%a6),%fp0 # execute multiply 11747 11747 11748 fmov.l %fpsr,%d1 11748 fmov.l %fpsr,%d1 # save status 11749 fmov.l &0x0,%fpcr 11749 fmov.l &0x0,%fpcr # clear FPCR 11750 11750 11751 or.l %d1,USER_FPSR(%a6) 11751 or.l %d1,USER_FPSR(%a6) # save INEX2,N 11752 11752 11753 fabs.x %fp0,%fp1 11753 fabs.x %fp0,%fp1 # make a copy of result 11754 fcmp.b %fp1,&0x2 11754 fcmp.b %fp1,&0x2 # is |result| >= 2.b? 11755 fbge.w fmul_ovfl_tst 11755 fbge.w fmul_ovfl_tst # yes; overflow has occurred 11756 11756 11757 # no, it didn't overflow; we have correct re 11757 # no, it didn't overflow; we have correct result 11758 bra.w fmul_normal_exit 11758 bra.w fmul_normal_exit 11759 11759 11760 # 11760 # 11761 # UNDERFLOW: 11761 # UNDERFLOW: 11762 # - the result of the multiply operation is 11762 # - the result of the multiply operation is an underflow. 11763 # - do the multiply to the proper precision 11763 # - do the multiply to the proper precision and rounding mode in order to 11764 # set the inexact bits. 11764 # set the inexact bits. 11765 # - calculate the default result and return 11765 # - calculate the default result and return it in fp0. 11766 # - if overflow or inexact is enabled, we ne 11766 # - if overflow or inexact is enabled, we need a multiply result rounded to 11767 # extended precision. if the original operat 11767 # extended precision. if the original operation was extended, then we have this 11768 # result. if the original operation was sing 11768 # result. if the original operation was single or double, we have to do another 11769 # multiply using extended precision and the 11769 # multiply using extended precision and the correct rounding mode. the result 11770 # of this operation then has its exponent sc 11770 # of this operation then has its exponent scaled by -0x6000 to create the 11771 # exceptional operand. 11771 # exceptional operand. 11772 # 11772 # 11773 fmul_unfl: 11773 fmul_unfl: 11774 bset &unfl_bit,FPSR_EXCEP 11774 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 11775 11775 11776 # for fun, let's use only extended precision 11776 # for fun, let's use only extended precision, round to zero. then, let 11777 # the unf_res() routine figure out all the r 11777 # the unf_res() routine figure out all the rest. 11778 # will we get the correct answer. 11778 # will we get the correct answer. 11779 fmovm.x FP_SCR1(%a6),&0x80 11779 fmovm.x FP_SCR1(%a6),&0x80 # load dst operand 11780 11780 11781 fmov.l &rz_mode*0x10,%fpcr 11781 fmov.l &rz_mode*0x10,%fpcr # set FPCR 11782 fmov.l &0x0,%fpsr 11782 fmov.l &0x0,%fpsr # clear FPSR 11783 11783 11784 fmul.x FP_SCR0(%a6),%fp0 11784 fmul.x FP_SCR0(%a6),%fp0 # execute multiply 11785 11785 11786 fmov.l %fpsr,%d1 11786 fmov.l %fpsr,%d1 # save status 11787 fmov.l &0x0,%fpcr 11787 fmov.l &0x0,%fpcr # clear FPCR 11788 11788 11789 or.l %d1,USER_FPSR(%a6) 11789 or.l %d1,USER_FPSR(%a6) # save INEX2,N 11790 11790 11791 mov.b FPCR_ENABLE(%a6),%d1 11791 mov.b FPCR_ENABLE(%a6),%d1 11792 andi.b &0x0b,%d1 11792 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 11793 bne.b fmul_unfl_ena 11793 bne.b fmul_unfl_ena # yes 11794 11794 11795 fmul_unfl_dis: 11795 fmul_unfl_dis: 11796 fmovm.x &0x80,FP_SCR0(%a6) 11796 fmovm.x &0x80,FP_SCR0(%a6) # store out result 11797 11797 11798 lea FP_SCR0(%a6),%a0 11798 lea FP_SCR0(%a6),%a0 # pass: result addr 11799 mov.l L_SCR3(%a6),%d1 11799 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 11800 bsr.l unf_res 11800 bsr.l unf_res # calculate default result 11801 or.b %d0,FPSR_CC(%a6) 11801 or.b %d0,FPSR_CC(%a6) # unf_res2 may have set 'Z' 11802 fmovm.x FP_SCR0(%a6),&0x80 11802 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 11803 rts 11803 rts 11804 11804 11805 # 11805 # 11806 # UNFL is enabled. 11806 # UNFL is enabled. 11807 # 11807 # 11808 fmul_unfl_ena: 11808 fmul_unfl_ena: 11809 fmovm.x FP_SCR1(%a6),&0x40 11809 fmovm.x FP_SCR1(%a6),&0x40 # load dst op 11810 11810 11811 mov.l L_SCR3(%a6),%d1 11811 mov.l L_SCR3(%a6),%d1 11812 andi.b &0xc0,%d1 11812 andi.b &0xc0,%d1 # is precision extended? 11813 bne.b fmul_unfl_ena_sd 11813 bne.b fmul_unfl_ena_sd # no, sgl or dbl 11814 11814 11815 # if the rnd mode is anything but RZ, then w 11815 # if the rnd mode is anything but RZ, then we have to re-do the above 11816 # multiplication because we used RZ for all. 11816 # multiplication because we used RZ for all. 11817 fmov.l L_SCR3(%a6),%fpcr 11817 fmov.l L_SCR3(%a6),%fpcr # set FPCR 11818 11818 11819 fmul_unfl_ena_cont: 11819 fmul_unfl_ena_cont: 11820 fmov.l &0x0,%fpsr 11820 fmov.l &0x0,%fpsr # clear FPSR 11821 11821 11822 fmul.x FP_SCR0(%a6),%fp1 11822 fmul.x FP_SCR0(%a6),%fp1 # execute multiply 11823 11823 11824 fmov.l &0x0,%fpcr 11824 fmov.l &0x0,%fpcr # clear FPCR 11825 11825 11826 fmovm.x &0x40,FP_SCR0(%a6) 11826 fmovm.x &0x40,FP_SCR0(%a6) # save result to stack 11827 mov.l %d2,-(%sp) 11827 mov.l %d2,-(%sp) # save d2 11828 mov.w FP_SCR0_EX(%a6),%d1 11828 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 11829 mov.l %d1,%d2 11829 mov.l %d1,%d2 # make a copy 11830 andi.l &0x7fff,%d1 11830 andi.l &0x7fff,%d1 # strip sign 11831 andi.w &0x8000,%d2 11831 andi.w &0x8000,%d2 # keep old sign 11832 sub.l %d0,%d1 11832 sub.l %d0,%d1 # add scale factor 11833 addi.l &0x6000,%d1 11833 addi.l &0x6000,%d1 # add bias 11834 andi.w &0x7fff,%d1 11834 andi.w &0x7fff,%d1 11835 or.w %d2,%d1 11835 or.w %d2,%d1 # concat old sign,new exp 11836 mov.w %d1,FP_SCR0_EX(%a6) 11836 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 11837 mov.l (%sp)+,%d2 11837 mov.l (%sp)+,%d2 # restore d2 11838 fmovm.x FP_SCR0(%a6),&0x40 11838 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 11839 bra.w fmul_unfl_dis 11839 bra.w fmul_unfl_dis 11840 11840 11841 fmul_unfl_ena_sd: 11841 fmul_unfl_ena_sd: 11842 mov.l L_SCR3(%a6),%d1 11842 mov.l L_SCR3(%a6),%d1 11843 andi.b &0x30,%d1 11843 andi.b &0x30,%d1 # use only rnd mode 11844 fmov.l %d1,%fpcr 11844 fmov.l %d1,%fpcr # set FPCR 11845 11845 11846 bra.b fmul_unfl_ena_cont 11846 bra.b fmul_unfl_ena_cont 11847 11847 11848 # MAY UNDERFLOW: 11848 # MAY UNDERFLOW: 11849 # -use the correct rounding mode and precisi 11849 # -use the correct rounding mode and precision. this code favors operations 11850 # that do not underflow. 11850 # that do not underflow. 11851 fmul_may_unfl: 11851 fmul_may_unfl: 11852 fmovm.x FP_SCR1(%a6),&0x80 11852 fmovm.x FP_SCR1(%a6),&0x80 # load dst operand 11853 11853 11854 fmov.l L_SCR3(%a6),%fpcr 11854 fmov.l L_SCR3(%a6),%fpcr # set FPCR 11855 fmov.l &0x0,%fpsr 11855 fmov.l &0x0,%fpsr # clear FPSR 11856 11856 11857 fmul.x FP_SCR0(%a6),%fp0 11857 fmul.x FP_SCR0(%a6),%fp0 # execute multiply 11858 11858 11859 fmov.l %fpsr,%d1 11859 fmov.l %fpsr,%d1 # save status 11860 fmov.l &0x0,%fpcr 11860 fmov.l &0x0,%fpcr # clear FPCR 11861 11861 11862 or.l %d1,USER_FPSR(%a6) 11862 or.l %d1,USER_FPSR(%a6) # save INEX2,N 11863 11863 11864 fabs.x %fp0,%fp1 11864 fabs.x %fp0,%fp1 # make a copy of result 11865 fcmp.b %fp1,&0x2 11865 fcmp.b %fp1,&0x2 # is |result| > 2.b? 11866 fbgt.w fmul_normal_exit 11866 fbgt.w fmul_normal_exit # no; no underflow occurred 11867 fblt.w fmul_unfl 11867 fblt.w fmul_unfl # yes; underflow occurred 11868 11868 11869 # 11869 # 11870 # we still don't know if underflow occurred. 11870 # we still don't know if underflow occurred. result is ~ equal to 2. but, 11871 # we don't know if the result was an underfl 11871 # we don't know if the result was an underflow that rounded up to a 2 or 11872 # a normalized number that rounded down to a 11872 # a normalized number that rounded down to a 2. so, redo the entire operation 11873 # using RZ as the rounding mode to see what 11873 # using RZ as the rounding mode to see what the pre-rounded result is. 11874 # this case should be relatively rare. 11874 # this case should be relatively rare. 11875 # 11875 # 11876 fmovm.x FP_SCR1(%a6),&0x40 11876 fmovm.x FP_SCR1(%a6),&0x40 # load dst operand 11877 11877 11878 mov.l L_SCR3(%a6),%d1 11878 mov.l L_SCR3(%a6),%d1 11879 andi.b &0xc0,%d1 11879 andi.b &0xc0,%d1 # keep rnd prec 11880 ori.b &rz_mode*0x10,%d1 11880 ori.b &rz_mode*0x10,%d1 # insert RZ 11881 11881 11882 fmov.l %d1,%fpcr 11882 fmov.l %d1,%fpcr # set FPCR 11883 fmov.l &0x0,%fpsr 11883 fmov.l &0x0,%fpsr # clear FPSR 11884 11884 11885 fmul.x FP_SCR0(%a6),%fp1 11885 fmul.x FP_SCR0(%a6),%fp1 # execute multiply 11886 11886 11887 fmov.l &0x0,%fpcr 11887 fmov.l &0x0,%fpcr # clear FPCR 11888 fabs.x %fp1 11888 fabs.x %fp1 # make absolute value 11889 fcmp.b %fp1,&0x2 11889 fcmp.b %fp1,&0x2 # is |result| < 2.b? 11890 fbge.w fmul_normal_exit 11890 fbge.w fmul_normal_exit # no; no underflow occurred 11891 bra.w fmul_unfl 11891 bra.w fmul_unfl # yes, underflow occurred 11892 11892 11893 ############################################ 11893 ################################################################################ 11894 11894 11895 # 11895 # 11896 # Multiply: inputs are not both normalized; 11896 # Multiply: inputs are not both normalized; what are they? 11897 # 11897 # 11898 fmul_not_norm: 11898 fmul_not_norm: 11899 mov.w (tbl_fmul_op.b,%pc,% 11899 mov.w (tbl_fmul_op.b,%pc,%d1.w*2),%d1 11900 jmp (tbl_fmul_op.b,%pc,% 11900 jmp (tbl_fmul_op.b,%pc,%d1.w) 11901 11901 11902 swbeg &48 11902 swbeg &48 11903 tbl_fmul_op: 11903 tbl_fmul_op: 11904 short fmul_norm - tb 11904 short fmul_norm - tbl_fmul_op # NORM x NORM 11905 short fmul_zero - tb 11905 short fmul_zero - tbl_fmul_op # NORM x ZERO 11906 short fmul_inf_src - tb 11906 short fmul_inf_src - tbl_fmul_op # NORM x INF 11907 short fmul_res_qnan - tb 11907 short fmul_res_qnan - tbl_fmul_op # NORM x QNAN 11908 short fmul_norm - tb 11908 short fmul_norm - tbl_fmul_op # NORM x DENORM 11909 short fmul_res_snan - tb 11909 short fmul_res_snan - tbl_fmul_op # NORM x SNAN 11910 short tbl_fmul_op - tb 11910 short tbl_fmul_op - tbl_fmul_op # 11911 short tbl_fmul_op - tb 11911 short tbl_fmul_op - tbl_fmul_op # 11912 11912 11913 short fmul_zero - tb 11913 short fmul_zero - tbl_fmul_op # ZERO x NORM 11914 short fmul_zero - tb 11914 short fmul_zero - tbl_fmul_op # ZERO x ZERO 11915 short fmul_res_operr - tb 11915 short fmul_res_operr - tbl_fmul_op # ZERO x INF 11916 short fmul_res_qnan - tb 11916 short fmul_res_qnan - tbl_fmul_op # ZERO x QNAN 11917 short fmul_zero - tb 11917 short fmul_zero - tbl_fmul_op # ZERO x DENORM 11918 short fmul_res_snan - tb 11918 short fmul_res_snan - tbl_fmul_op # ZERO x SNAN 11919 short tbl_fmul_op - tb 11919 short tbl_fmul_op - tbl_fmul_op # 11920 short tbl_fmul_op - tb 11920 short tbl_fmul_op - tbl_fmul_op # 11921 11921 11922 short fmul_inf_dst - tb 11922 short fmul_inf_dst - tbl_fmul_op # INF x NORM 11923 short fmul_res_operr - tb 11923 short fmul_res_operr - tbl_fmul_op # INF x ZERO 11924 short fmul_inf_dst - tb 11924 short fmul_inf_dst - tbl_fmul_op # INF x INF 11925 short fmul_res_qnan - tb 11925 short fmul_res_qnan - tbl_fmul_op # INF x QNAN 11926 short fmul_inf_dst - tb 11926 short fmul_inf_dst - tbl_fmul_op # INF x DENORM 11927 short fmul_res_snan - tb 11927 short fmul_res_snan - tbl_fmul_op # INF x SNAN 11928 short tbl_fmul_op - tb 11928 short tbl_fmul_op - tbl_fmul_op # 11929 short tbl_fmul_op - tb 11929 short tbl_fmul_op - tbl_fmul_op # 11930 11930 11931 short fmul_res_qnan - tb 11931 short fmul_res_qnan - tbl_fmul_op # QNAN x NORM 11932 short fmul_res_qnan - tb 11932 short fmul_res_qnan - tbl_fmul_op # QNAN x ZERO 11933 short fmul_res_qnan - tb 11933 short fmul_res_qnan - tbl_fmul_op # QNAN x INF 11934 short fmul_res_qnan - tb 11934 short fmul_res_qnan - tbl_fmul_op # QNAN x QNAN 11935 short fmul_res_qnan - tb 11935 short fmul_res_qnan - tbl_fmul_op # QNAN x DENORM 11936 short fmul_res_snan - tb 11936 short fmul_res_snan - tbl_fmul_op # QNAN x SNAN 11937 short tbl_fmul_op - tb 11937 short tbl_fmul_op - tbl_fmul_op # 11938 short tbl_fmul_op - tb 11938 short tbl_fmul_op - tbl_fmul_op # 11939 11939 11940 short fmul_norm - tb 11940 short fmul_norm - tbl_fmul_op # NORM x NORM 11941 short fmul_zero - tb 11941 short fmul_zero - tbl_fmul_op # NORM x ZERO 11942 short fmul_inf_src - tb 11942 short fmul_inf_src - tbl_fmul_op # NORM x INF 11943 short fmul_res_qnan - tb 11943 short fmul_res_qnan - tbl_fmul_op # NORM x QNAN 11944 short fmul_norm - tb 11944 short fmul_norm - tbl_fmul_op # NORM x DENORM 11945 short fmul_res_snan - tb 11945 short fmul_res_snan - tbl_fmul_op # NORM x SNAN 11946 short tbl_fmul_op - tb 11946 short tbl_fmul_op - tbl_fmul_op # 11947 short tbl_fmul_op - tb 11947 short tbl_fmul_op - tbl_fmul_op # 11948 11948 11949 short fmul_res_snan - tb 11949 short fmul_res_snan - tbl_fmul_op # SNAN x NORM 11950 short fmul_res_snan - tb 11950 short fmul_res_snan - tbl_fmul_op # SNAN x ZERO 11951 short fmul_res_snan - tb 11951 short fmul_res_snan - tbl_fmul_op # SNAN x INF 11952 short fmul_res_snan - tb 11952 short fmul_res_snan - tbl_fmul_op # SNAN x QNAN 11953 short fmul_res_snan - tb 11953 short fmul_res_snan - tbl_fmul_op # SNAN x DENORM 11954 short fmul_res_snan - tb 11954 short fmul_res_snan - tbl_fmul_op # SNAN x SNAN 11955 short tbl_fmul_op - tb 11955 short tbl_fmul_op - tbl_fmul_op # 11956 short tbl_fmul_op - tb 11956 short tbl_fmul_op - tbl_fmul_op # 11957 11957 11958 fmul_res_operr: 11958 fmul_res_operr: 11959 bra.l res_operr 11959 bra.l res_operr 11960 fmul_res_snan: 11960 fmul_res_snan: 11961 bra.l res_snan 11961 bra.l res_snan 11962 fmul_res_qnan: 11962 fmul_res_qnan: 11963 bra.l res_qnan 11963 bra.l res_qnan 11964 11964 11965 # 11965 # 11966 # Multiply: (Zero x Zero) || (Zero x norm) | 11966 # Multiply: (Zero x Zero) || (Zero x norm) || (Zero x denorm) 11967 # 11967 # 11968 global fmul_zero 11968 global fmul_zero # global for fsglmul 11969 fmul_zero: 11969 fmul_zero: 11970 mov.b SRC_EX(%a0),%d0 11970 mov.b SRC_EX(%a0),%d0 # exclusive or the signs 11971 mov.b DST_EX(%a1),%d1 11971 mov.b DST_EX(%a1),%d1 11972 eor.b %d0,%d1 11972 eor.b %d0,%d1 11973 bpl.b fmul_zero_p 11973 bpl.b fmul_zero_p # result ZERO is pos. 11974 fmul_zero_n: 11974 fmul_zero_n: 11975 fmov.s &0x80000000,%fp0 11975 fmov.s &0x80000000,%fp0 # load -ZERO 11976 mov.b &z_bmask+neg_bmask,F 11976 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/N 11977 rts 11977 rts 11978 fmul_zero_p: 11978 fmul_zero_p: 11979 fmov.s &0x00000000,%fp0 11979 fmov.s &0x00000000,%fp0 # load +ZERO 11980 mov.b &z_bmask,FPSR_CC(%a6 11980 mov.b &z_bmask,FPSR_CC(%a6) # set Z 11981 rts 11981 rts 11982 11982 11983 # 11983 # 11984 # Multiply: (inf x inf) || (inf x norm) || ( 11984 # Multiply: (inf x inf) || (inf x norm) || (inf x denorm) 11985 # 11985 # 11986 # Note: The j-bit for an infinity is a don't 11986 # Note: The j-bit for an infinity is a don't-care. However, to be 11987 # strictly compatible w/ the 68881/882, we m 11987 # strictly compatible w/ the 68881/882, we make sure to return an 11988 # INF w/ the j-bit set if the input INF j-bi 11988 # INF w/ the j-bit set if the input INF j-bit was set. Destination 11989 # INFs take priority. 11989 # INFs take priority. 11990 # 11990 # 11991 global fmul_inf_dst 11991 global fmul_inf_dst # global for fsglmul 11992 fmul_inf_dst: 11992 fmul_inf_dst: 11993 fmovm.x DST(%a1),&0x80 11993 fmovm.x DST(%a1),&0x80 # return INF result in fp0 11994 mov.b SRC_EX(%a0),%d0 11994 mov.b SRC_EX(%a0),%d0 # exclusive or the signs 11995 mov.b DST_EX(%a1),%d1 11995 mov.b DST_EX(%a1),%d1 11996 eor.b %d0,%d1 11996 eor.b %d0,%d1 11997 bpl.b fmul_inf_dst_p 11997 bpl.b fmul_inf_dst_p # result INF is pos. 11998 fmul_inf_dst_n: 11998 fmul_inf_dst_n: 11999 fabs.x %fp0 11999 fabs.x %fp0 # clear result sign 12000 fneg.x %fp0 12000 fneg.x %fp0 # set result sign 12001 mov.b &inf_bmask+neg_bmask 12001 mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N 12002 rts 12002 rts 12003 fmul_inf_dst_p: 12003 fmul_inf_dst_p: 12004 fabs.x %fp0 12004 fabs.x %fp0 # clear result sign 12005 mov.b &inf_bmask,FPSR_CC(% 12005 mov.b &inf_bmask,FPSR_CC(%a6) # set INF 12006 rts 12006 rts 12007 12007 12008 global fmul_inf_src 12008 global fmul_inf_src # global for fsglmul 12009 fmul_inf_src: 12009 fmul_inf_src: 12010 fmovm.x SRC(%a0),&0x80 12010 fmovm.x SRC(%a0),&0x80 # return INF result in fp0 12011 mov.b SRC_EX(%a0),%d0 12011 mov.b SRC_EX(%a0),%d0 # exclusive or the signs 12012 mov.b DST_EX(%a1),%d1 12012 mov.b DST_EX(%a1),%d1 12013 eor.b %d0,%d1 12013 eor.b %d0,%d1 12014 bpl.b fmul_inf_dst_p 12014 bpl.b fmul_inf_dst_p # result INF is pos. 12015 bra.b fmul_inf_dst_n 12015 bra.b fmul_inf_dst_n 12016 12016 12017 ############################################ 12017 ######################################################################### 12018 # XDEF ************************************* 12018 # XDEF **************************************************************** # 12019 # fin(): emulates the fmove instructio 12019 # fin(): emulates the fmove instruction # 12020 # fsin(): emulates the fsmove instruct 12020 # fsin(): emulates the fsmove instruction # 12021 # fdin(): emulates the fdmove instruct 12021 # fdin(): emulates the fdmove instruction # 12022 # 12022 # # 12023 # XREF ************************************* 12023 # XREF **************************************************************** # 12024 # norm() - normalize mantissa for EXOP 12024 # norm() - normalize mantissa for EXOP on denorm # 12025 # scale_to_zero_src() - scale src expo 12025 # scale_to_zero_src() - scale src exponent to zero # 12026 # ovf_res() - return default overflow 12026 # ovf_res() - return default overflow result # 12027 # unf_res() - return default underflow 12027 # unf_res() - return default underflow result # 12028 # res_qnan_1op() - return QNAN result 12028 # res_qnan_1op() - return QNAN result # 12029 # res_snan_1op() - return SNAN result 12029 # res_snan_1op() - return SNAN result # 12030 # 12030 # # 12031 # INPUT ************************************ 12031 # INPUT *************************************************************** # 12032 # a0 = pointer to extended precision s 12032 # a0 = pointer to extended precision source operand # 12033 # d0 = round prec/mode 12033 # d0 = round prec/mode # 12034 # 12034 # # 12035 # OUTPUT *********************************** 12035 # OUTPUT ************************************************************** # 12036 # fp0 = result 12036 # fp0 = result # 12037 # fp1 = EXOP (if exception occurred) 12037 # fp1 = EXOP (if exception occurred) # 12038 # 12038 # # 12039 # ALGORITHM ******************************** 12039 # ALGORITHM *********************************************************** # 12040 # Handle NANs, infinities, and zeroes 12040 # Handle NANs, infinities, and zeroes as special cases. Divide # 12041 # norms into extended, single, and double pr 12041 # norms into extended, single, and double precision. # 12042 # Norms can be emulated w/ a regular f 12042 # Norms can be emulated w/ a regular fmove instruction. For # 12043 # sgl/dbl, must scale exponent and perform a 12043 # sgl/dbl, must scale exponent and perform an "fmove". Check to see # 12044 # if the result would have overflowed/underf 12044 # if the result would have overflowed/underflowed. If so, use unf_res() # 12045 # or ovf_res() to return the default result. 12045 # or ovf_res() to return the default result. Also return EXOP if # 12046 # exception is enabled. If no exception, ret 12046 # exception is enabled. If no exception, return the default result. # 12047 # Unnorms don't pass through here. 12047 # Unnorms don't pass through here. # 12048 # 12048 # # 12049 ############################################ 12049 ######################################################################### 12050 12050 12051 global fsin 12051 global fsin 12052 fsin: 12052 fsin: 12053 andi.b &0x30,%d0 12053 andi.b &0x30,%d0 # clear rnd prec 12054 ori.b &s_mode*0x10,%d0 12054 ori.b &s_mode*0x10,%d0 # insert sgl precision 12055 bra.b fin 12055 bra.b fin 12056 12056 12057 global fdin 12057 global fdin 12058 fdin: 12058 fdin: 12059 andi.b &0x30,%d0 12059 andi.b &0x30,%d0 # clear rnd prec 12060 ori.b &d_mode*0x10,%d0 12060 ori.b &d_mode*0x10,%d0 # insert dbl precision 12061 12061 12062 global fin 12062 global fin 12063 fin: 12063 fin: 12064 mov.l %d0,L_SCR3(%a6) 12064 mov.l %d0,L_SCR3(%a6) # store rnd info 12065 12065 12066 mov.b STAG(%a6),%d1 12066 mov.b STAG(%a6),%d1 # fetch src optype tag 12067 bne.w fin_not_norm 12067 bne.w fin_not_norm # optimize on non-norm input 12068 12068 12069 # 12069 # 12070 # FP MOVE IN: NORMs and DENORMs ONLY! 12070 # FP MOVE IN: NORMs and DENORMs ONLY! 12071 # 12071 # 12072 fin_norm: 12072 fin_norm: 12073 andi.b &0xc0,%d0 12073 andi.b &0xc0,%d0 # is precision extended? 12074 bne.w fin_not_ext 12074 bne.w fin_not_ext # no, so go handle dbl or sgl 12075 12075 12076 # 12076 # 12077 # precision selected is extended. so...we ca 12077 # precision selected is extended. so...we cannot get an underflow 12078 # or overflow because of rounding to the cor 12078 # or overflow because of rounding to the correct precision. so... 12079 # skip the scaling and unscaling... 12079 # skip the scaling and unscaling... 12080 # 12080 # 12081 tst.b SRC_EX(%a0) 12081 tst.b SRC_EX(%a0) # is the operand negative? 12082 bpl.b fin_norm_done 12082 bpl.b fin_norm_done # no 12083 bset &neg_bit,FPSR_CC(%a6 12083 bset &neg_bit,FPSR_CC(%a6) # yes, so set 'N' ccode bit 12084 fin_norm_done: 12084 fin_norm_done: 12085 fmovm.x SRC(%a0),&0x80 12085 fmovm.x SRC(%a0),&0x80 # return result in fp0 12086 rts 12086 rts 12087 12087 12088 # 12088 # 12089 # for an extended precision DENORM, the UNFL 12089 # for an extended precision DENORM, the UNFL exception bit is set 12090 # the accrued bit is NOT set in this instanc 12090 # the accrued bit is NOT set in this instance(no inexactness!) 12091 # 12091 # 12092 fin_denorm: 12092 fin_denorm: 12093 andi.b &0xc0,%d0 12093 andi.b &0xc0,%d0 # is precision extended? 12094 bne.w fin_not_ext 12094 bne.w fin_not_ext # no, so go handle dbl or sgl 12095 12095 12096 bset &unfl_bit,FPSR_EXCEP 12096 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 12097 tst.b SRC_EX(%a0) 12097 tst.b SRC_EX(%a0) # is the operand negative? 12098 bpl.b fin_denorm_done 12098 bpl.b fin_denorm_done # no 12099 bset &neg_bit,FPSR_CC(%a6 12099 bset &neg_bit,FPSR_CC(%a6) # yes, so set 'N' ccode bit 12100 fin_denorm_done: 12100 fin_denorm_done: 12101 fmovm.x SRC(%a0),&0x80 12101 fmovm.x SRC(%a0),&0x80 # return result in fp0 12102 btst &unfl_bit,FPCR_ENABL 12102 btst &unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled? 12103 bne.b fin_denorm_unfl_ena 12103 bne.b fin_denorm_unfl_ena # yes 12104 rts 12104 rts 12105 12105 12106 # 12106 # 12107 # the input is an extended DENORM and underf 12107 # the input is an extended DENORM and underflow is enabled in the FPCR. 12108 # normalize the mantissa and add the bias of 12108 # normalize the mantissa and add the bias of 0x6000 to the resulting negative 12109 # exponent and insert back into the operand. 12109 # exponent and insert back into the operand. 12110 # 12110 # 12111 fin_denorm_unfl_ena: 12111 fin_denorm_unfl_ena: 12112 mov.w SRC_EX(%a0),FP_SCR0_ 12112 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 12113 mov.l SRC_HI(%a0),FP_SCR0_ 12113 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12114 mov.l SRC_LO(%a0),FP_SCR0_ 12114 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12115 lea FP_SCR0(%a6),%a0 12115 lea FP_SCR0(%a6),%a0 # pass: ptr to operand 12116 bsr.l norm 12116 bsr.l norm # normalize result 12117 neg.w %d0 12117 neg.w %d0 # new exponent = -(shft val) 12118 addi.w &0x6000,%d0 12118 addi.w &0x6000,%d0 # add new bias to exponent 12119 mov.w FP_SCR0_EX(%a6),%d1 12119 mov.w FP_SCR0_EX(%a6),%d1 # fetch old sign,exp 12120 andi.w &0x8000,%d1 12120 andi.w &0x8000,%d1 # keep old sign 12121 andi.w &0x7fff,%d0 12121 andi.w &0x7fff,%d0 # clear sign position 12122 or.w %d1,%d0 12122 or.w %d1,%d0 # concat new exo,old sign 12123 mov.w %d0,FP_SCR0_EX(%a6) 12123 mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent 12124 fmovm.x FP_SCR0(%a6),&0x40 12124 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 12125 rts 12125 rts 12126 12126 12127 # 12127 # 12128 # operand is to be rounded to single or doub 12128 # operand is to be rounded to single or double precision 12129 # 12129 # 12130 fin_not_ext: 12130 fin_not_ext: 12131 cmpi.b %d0,&s_mode*0x10 12131 cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec 12132 bne.b fin_dbl 12132 bne.b fin_dbl 12133 12133 12134 # 12134 # 12135 # operand is to be rounded to single precisi 12135 # operand is to be rounded to single precision 12136 # 12136 # 12137 fin_sgl: 12137 fin_sgl: 12138 mov.w SRC_EX(%a0),FP_SCR0_ 12138 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 12139 mov.l SRC_HI(%a0),FP_SCR0_ 12139 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12140 mov.l SRC_LO(%a0),FP_SCR0_ 12140 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12141 bsr.l scale_to_zero_src 12141 bsr.l scale_to_zero_src # calculate scale factor 12142 12142 12143 cmpi.l %d0,&0x3fff-0x3f80 12143 cmpi.l %d0,&0x3fff-0x3f80 # will move in underflow? 12144 bge.w fin_sd_unfl 12144 bge.w fin_sd_unfl # yes; go handle underflow 12145 cmpi.l %d0,&0x3fff-0x407e 12145 cmpi.l %d0,&0x3fff-0x407e # will move in overflow? 12146 beq.w fin_sd_may_ovfl 12146 beq.w fin_sd_may_ovfl # maybe; go check 12147 blt.w fin_sd_ovfl 12147 blt.w fin_sd_ovfl # yes; go handle overflow 12148 12148 12149 # 12149 # 12150 # operand will NOT overflow or underflow whe 12150 # operand will NOT overflow or underflow when moved into the fp reg file 12151 # 12151 # 12152 fin_sd_normal: 12152 fin_sd_normal: 12153 fmov.l &0x0,%fpsr 12153 fmov.l &0x0,%fpsr # clear FPSR 12154 fmov.l L_SCR3(%a6),%fpcr 12154 fmov.l L_SCR3(%a6),%fpcr # set FPCR 12155 12155 12156 fmov.x FP_SCR0(%a6),%fp0 12156 fmov.x FP_SCR0(%a6),%fp0 # perform move 12157 12157 12158 fmov.l %fpsr,%d1 12158 fmov.l %fpsr,%d1 # save FPSR 12159 fmov.l &0x0,%fpcr 12159 fmov.l &0x0,%fpcr # clear FPCR 12160 12160 12161 or.l %d1,USER_FPSR(%a6) 12161 or.l %d1,USER_FPSR(%a6) # save INEX2,N 12162 12162 12163 fin_sd_normal_exit: 12163 fin_sd_normal_exit: 12164 mov.l %d2,-(%sp) 12164 mov.l %d2,-(%sp) # save d2 12165 fmovm.x &0x80,FP_SCR0(%a6) 12165 fmovm.x &0x80,FP_SCR0(%a6) # store out result 12166 mov.w FP_SCR0_EX(%a6),%d1 12166 mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp} 12167 mov.w %d1,%d2 12167 mov.w %d1,%d2 # make a copy 12168 andi.l &0x7fff,%d1 12168 andi.l &0x7fff,%d1 # strip sign 12169 sub.l %d0,%d1 12169 sub.l %d0,%d1 # add scale factor 12170 andi.w &0x8000,%d2 12170 andi.w &0x8000,%d2 # keep old sign 12171 or.w %d1,%d2 12171 or.w %d1,%d2 # concat old sign,new exponent 12172 mov.w %d2,FP_SCR0_EX(%a6) 12172 mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent 12173 mov.l (%sp)+,%d2 12173 mov.l (%sp)+,%d2 # restore d2 12174 fmovm.x FP_SCR0(%a6),&0x80 12174 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 12175 rts 12175 rts 12176 12176 12177 # 12177 # 12178 # operand is to be rounded to double precisi 12178 # operand is to be rounded to double precision 12179 # 12179 # 12180 fin_dbl: 12180 fin_dbl: 12181 mov.w SRC_EX(%a0),FP_SCR0_ 12181 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 12182 mov.l SRC_HI(%a0),FP_SCR0_ 12182 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12183 mov.l SRC_LO(%a0),FP_SCR0_ 12183 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12184 bsr.l scale_to_zero_src 12184 bsr.l scale_to_zero_src # calculate scale factor 12185 12185 12186 cmpi.l %d0,&0x3fff-0x3c00 12186 cmpi.l %d0,&0x3fff-0x3c00 # will move in underflow? 12187 bge.w fin_sd_unfl 12187 bge.w fin_sd_unfl # yes; go handle underflow 12188 cmpi.l %d0,&0x3fff-0x43fe 12188 cmpi.l %d0,&0x3fff-0x43fe # will move in overflow? 12189 beq.w fin_sd_may_ovfl 12189 beq.w fin_sd_may_ovfl # maybe; go check 12190 blt.w fin_sd_ovfl 12190 blt.w fin_sd_ovfl # yes; go handle overflow 12191 bra.w fin_sd_normal 12191 bra.w fin_sd_normal # no; ho handle normalized op 12192 12192 12193 # 12193 # 12194 # operand WILL underflow when moved in to th 12194 # operand WILL underflow when moved in to the fp register file 12195 # 12195 # 12196 fin_sd_unfl: 12196 fin_sd_unfl: 12197 bset &unfl_bit,FPSR_EXCEP 12197 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 12198 12198 12199 tst.b FP_SCR0_EX(%a6) 12199 tst.b FP_SCR0_EX(%a6) # is operand negative? 12200 bpl.b fin_sd_unfl_tst 12200 bpl.b fin_sd_unfl_tst 12201 bset &neg_bit,FPSR_CC(%a6 12201 bset &neg_bit,FPSR_CC(%a6) # set 'N' ccode bit 12202 12202 12203 # if underflow or inexact is enabled, then g 12203 # if underflow or inexact is enabled, then go calculate the EXOP first. 12204 fin_sd_unfl_tst: 12204 fin_sd_unfl_tst: 12205 mov.b FPCR_ENABLE(%a6),%d1 12205 mov.b FPCR_ENABLE(%a6),%d1 12206 andi.b &0x0b,%d1 12206 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 12207 bne.b fin_sd_unfl_ena 12207 bne.b fin_sd_unfl_ena # yes 12208 12208 12209 fin_sd_unfl_dis: 12209 fin_sd_unfl_dis: 12210 lea FP_SCR0(%a6),%a0 12210 lea FP_SCR0(%a6),%a0 # pass: result addr 12211 mov.l L_SCR3(%a6),%d1 12211 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 12212 bsr.l unf_res 12212 bsr.l unf_res # calculate default result 12213 or.b %d0,FPSR_CC(%a6) 12213 or.b %d0,FPSR_CC(%a6) # unf_res may have set 'Z' 12214 fmovm.x FP_SCR0(%a6),&0x80 12214 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 12215 rts 12215 rts 12216 12216 12217 # 12217 # 12218 # operand will underflow AND underflow or in 12218 # operand will underflow AND underflow or inexact is enabled. 12219 # Therefore, we must return the result round 12219 # Therefore, we must return the result rounded to extended precision. 12220 # 12220 # 12221 fin_sd_unfl_ena: 12221 fin_sd_unfl_ena: 12222 mov.l FP_SCR0_HI(%a6),FP_S 12222 mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) 12223 mov.l FP_SCR0_LO(%a6),FP_S 12223 mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6) 12224 mov.w FP_SCR0_EX(%a6),%d1 12224 mov.w FP_SCR0_EX(%a6),%d1 # load current exponent 12225 12225 12226 mov.l %d2,-(%sp) 12226 mov.l %d2,-(%sp) # save d2 12227 mov.w %d1,%d2 12227 mov.w %d1,%d2 # make a copy 12228 andi.l &0x7fff,%d1 12228 andi.l &0x7fff,%d1 # strip sign 12229 sub.l %d0,%d1 12229 sub.l %d0,%d1 # subtract scale factor 12230 andi.w &0x8000,%d2 12230 andi.w &0x8000,%d2 # extract old sign 12231 addi.l &0x6000,%d1 12231 addi.l &0x6000,%d1 # add new bias 12232 andi.w &0x7fff,%d1 12232 andi.w &0x7fff,%d1 12233 or.w %d1,%d2 12233 or.w %d1,%d2 # concat old sign,new exp 12234 mov.w %d2,FP_SCR1_EX(%a6) 12234 mov.w %d2,FP_SCR1_EX(%a6) # insert new exponent 12235 fmovm.x FP_SCR1(%a6),&0x40 12235 fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1 12236 mov.l (%sp)+,%d2 12236 mov.l (%sp)+,%d2 # restore d2 12237 bra.b fin_sd_unfl_dis 12237 bra.b fin_sd_unfl_dis 12238 12238 12239 # 12239 # 12240 # operand WILL overflow. 12240 # operand WILL overflow. 12241 # 12241 # 12242 fin_sd_ovfl: 12242 fin_sd_ovfl: 12243 fmov.l &0x0,%fpsr 12243 fmov.l &0x0,%fpsr # clear FPSR 12244 fmov.l L_SCR3(%a6),%fpcr 12244 fmov.l L_SCR3(%a6),%fpcr # set FPCR 12245 12245 12246 fmov.x FP_SCR0(%a6),%fp0 12246 fmov.x FP_SCR0(%a6),%fp0 # perform move 12247 12247 12248 fmov.l &0x0,%fpcr 12248 fmov.l &0x0,%fpcr # clear FPCR 12249 fmov.l %fpsr,%d1 12249 fmov.l %fpsr,%d1 # save FPSR 12250 12250 12251 or.l %d1,USER_FPSR(%a6) 12251 or.l %d1,USER_FPSR(%a6) # save INEX2,N 12252 12252 12253 fin_sd_ovfl_tst: 12253 fin_sd_ovfl_tst: 12254 or.l &ovfl_inx_mask,USER_ 12254 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 12255 12255 12256 mov.b FPCR_ENABLE(%a6),%d1 12256 mov.b FPCR_ENABLE(%a6),%d1 12257 andi.b &0x13,%d1 12257 andi.b &0x13,%d1 # is OVFL or INEX enabled? 12258 bne.b fin_sd_ovfl_ena 12258 bne.b fin_sd_ovfl_ena # yes 12259 12259 12260 # 12260 # 12261 # OVFL is not enabled; therefore, we must cr 12261 # OVFL is not enabled; therefore, we must create the default result by 12262 # calling ovf_res(). 12262 # calling ovf_res(). 12263 # 12263 # 12264 fin_sd_ovfl_dis: 12264 fin_sd_ovfl_dis: 12265 btst &neg_bit,FPSR_CC(%a6 12265 btst &neg_bit,FPSR_CC(%a6) # is result negative? 12266 sne %d1 12266 sne %d1 # set sign param accordingly 12267 mov.l L_SCR3(%a6),%d0 12267 mov.l L_SCR3(%a6),%d0 # pass: prec,mode 12268 bsr.l ovf_res 12268 bsr.l ovf_res # calculate default result 12269 or.b %d0,FPSR_CC(%a6) 12269 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 12270 fmovm.x (%a0),&0x80 12270 fmovm.x (%a0),&0x80 # return default result in fp0 12271 rts 12271 rts 12272 12272 12273 # 12273 # 12274 # OVFL is enabled. 12274 # OVFL is enabled. 12275 # the INEX2 bit has already been updated by 12275 # the INEX2 bit has already been updated by the round to the correct precision. 12276 # now, round to extended(and don't alter the 12276 # now, round to extended(and don't alter the FPSR). 12277 # 12277 # 12278 fin_sd_ovfl_ena: 12278 fin_sd_ovfl_ena: 12279 mov.l %d2,-(%sp) 12279 mov.l %d2,-(%sp) # save d2 12280 mov.w FP_SCR0_EX(%a6),%d1 12280 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 12281 mov.l %d1,%d2 12281 mov.l %d1,%d2 # make a copy 12282 andi.l &0x7fff,%d1 12282 andi.l &0x7fff,%d1 # strip sign 12283 andi.w &0x8000,%d2 12283 andi.w &0x8000,%d2 # keep old sign 12284 sub.l %d0,%d1 12284 sub.l %d0,%d1 # add scale factor 12285 sub.l &0x6000,%d1 12285 sub.l &0x6000,%d1 # subtract bias 12286 andi.w &0x7fff,%d1 12286 andi.w &0x7fff,%d1 12287 or.w %d2,%d1 12287 or.w %d2,%d1 12288 mov.w %d1,FP_SCR0_EX(%a6) 12288 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 12289 mov.l (%sp)+,%d2 12289 mov.l (%sp)+,%d2 # restore d2 12290 fmovm.x FP_SCR0(%a6),&0x40 12290 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 12291 bra.b fin_sd_ovfl_dis 12291 bra.b fin_sd_ovfl_dis 12292 12292 12293 # 12293 # 12294 # the move in MAY overflow. so... 12294 # the move in MAY overflow. so... 12295 # 12295 # 12296 fin_sd_may_ovfl: 12296 fin_sd_may_ovfl: 12297 fmov.l &0x0,%fpsr 12297 fmov.l &0x0,%fpsr # clear FPSR 12298 fmov.l L_SCR3(%a6),%fpcr 12298 fmov.l L_SCR3(%a6),%fpcr # set FPCR 12299 12299 12300 fmov.x FP_SCR0(%a6),%fp0 12300 fmov.x FP_SCR0(%a6),%fp0 # perform the move 12301 12301 12302 fmov.l %fpsr,%d1 12302 fmov.l %fpsr,%d1 # save status 12303 fmov.l &0x0,%fpcr 12303 fmov.l &0x0,%fpcr # clear FPCR 12304 12304 12305 or.l %d1,USER_FPSR(%a6) 12305 or.l %d1,USER_FPSR(%a6) # save INEX2,N 12306 12306 12307 fabs.x %fp0,%fp1 12307 fabs.x %fp0,%fp1 # make a copy of result 12308 fcmp.b %fp1,&0x2 12308 fcmp.b %fp1,&0x2 # is |result| >= 2.b? 12309 fbge.w fin_sd_ovfl_tst 12309 fbge.w fin_sd_ovfl_tst # yes; overflow has occurred 12310 12310 12311 # no, it didn't overflow; we have correct re 12311 # no, it didn't overflow; we have correct result 12312 bra.w fin_sd_normal_exit 12312 bra.w fin_sd_normal_exit 12313 12313 12314 ############################################ 12314 ########################################################################## 12315 12315 12316 # 12316 # 12317 # operand is not a NORM: check its optype an 12317 # operand is not a NORM: check its optype and branch accordingly 12318 # 12318 # 12319 fin_not_norm: 12319 fin_not_norm: 12320 cmpi.b %d1,&DENORM 12320 cmpi.b %d1,&DENORM # weed out DENORM 12321 beq.w fin_denorm 12321 beq.w fin_denorm 12322 cmpi.b %d1,&SNAN 12322 cmpi.b %d1,&SNAN # weed out SNANs 12323 beq.l res_snan_1op 12323 beq.l res_snan_1op 12324 cmpi.b %d1,&QNAN 12324 cmpi.b %d1,&QNAN # weed out QNANs 12325 beq.l res_qnan_1op 12325 beq.l res_qnan_1op 12326 12326 12327 # 12327 # 12328 # do the fmove in; at this point, only possi 12328 # do the fmove in; at this point, only possible ops are ZERO and INF. 12329 # use fmov to determine ccodes. 12329 # use fmov to determine ccodes. 12330 # prec:mode should be zero at this point but 12330 # prec:mode should be zero at this point but it won't affect answer anyways. 12331 # 12331 # 12332 fmov.x SRC(%a0),%fp0 12332 fmov.x SRC(%a0),%fp0 # do fmove in 12333 fmov.l %fpsr,%d0 12333 fmov.l %fpsr,%d0 # no exceptions possible 12334 rol.l &0x8,%d0 12334 rol.l &0x8,%d0 # put ccodes in lo byte 12335 mov.b %d0,FPSR_CC(%a6) 12335 mov.b %d0,FPSR_CC(%a6) # insert correct ccodes 12336 rts 12336 rts 12337 12337 12338 ############################################ 12338 ######################################################################### 12339 # XDEF ************************************* 12339 # XDEF **************************************************************** # 12340 # fdiv(): emulates the fdiv instructio 12340 # fdiv(): emulates the fdiv instruction # 12341 # fsdiv(): emulates the fsdiv instruct 12341 # fsdiv(): emulates the fsdiv instruction # 12342 # fddiv(): emulates the fddiv instruct 12342 # fddiv(): emulates the fddiv instruction # 12343 # 12343 # # 12344 # XREF ************************************* 12344 # XREF **************************************************************** # 12345 # scale_to_zero_src() - scale src expo 12345 # scale_to_zero_src() - scale src exponent to zero # 12346 # scale_to_zero_dst() - scale dst expo 12346 # scale_to_zero_dst() - scale dst exponent to zero # 12347 # unf_res() - return default underflow 12347 # unf_res() - return default underflow result # 12348 # ovf_res() - return default overflow 12348 # ovf_res() - return default overflow result # 12349 # res_qnan() - return QNAN result 12349 # res_qnan() - return QNAN result # 12350 # res_snan() - return SNAN result 12350 # res_snan() - return SNAN result # 12351 # 12351 # # 12352 # INPUT ************************************ 12352 # INPUT *************************************************************** # 12353 # a0 = pointer to extended precision s 12353 # a0 = pointer to extended precision source operand # 12354 # a1 = pointer to extended precision d 12354 # a1 = pointer to extended precision destination operand # 12355 # d0 rnd prec,mode 12355 # d0 rnd prec,mode # 12356 # 12356 # # 12357 # OUTPUT *********************************** 12357 # OUTPUT ************************************************************** # 12358 # fp0 = result 12358 # fp0 = result # 12359 # fp1 = EXOP (if exception occurred) 12359 # fp1 = EXOP (if exception occurred) # 12360 # 12360 # # 12361 # ALGORITHM ******************************** 12361 # ALGORITHM *********************************************************** # 12362 # Handle NANs, infinities, and zeroes 12362 # Handle NANs, infinities, and zeroes as special cases. Divide # 12363 # norms/denorms into ext/sgl/dbl precision. 12363 # norms/denorms into ext/sgl/dbl precision. # 12364 # For norms/denorms, scale the exponen 12364 # For norms/denorms, scale the exponents such that a divide # 12365 # instruction won't cause an exception. Use 12365 # instruction won't cause an exception. Use the regular fdiv to # 12366 # compute a result. Check if the regular ope 12366 # compute a result. Check if the regular operands would have taken # 12367 # an exception. If so, return the default ov 12367 # an exception. If so, return the default overflow/underflow result # 12368 # and return the EXOP if exceptions are enab 12368 # and return the EXOP if exceptions are enabled. Else, scale the # 12369 # result operand to the proper exponent. 12369 # result operand to the proper exponent. # 12370 # 12370 # # 12371 ############################################ 12371 ######################################################################### 12372 12372 12373 align 0x10 12373 align 0x10 12374 tbl_fdiv_unfl: 12374 tbl_fdiv_unfl: 12375 long 0x3fff - 0x0000 12375 long 0x3fff - 0x0000 # ext_unfl 12376 long 0x3fff - 0x3f81 12376 long 0x3fff - 0x3f81 # sgl_unfl 12377 long 0x3fff - 0x3c01 12377 long 0x3fff - 0x3c01 # dbl_unfl 12378 12378 12379 tbl_fdiv_ovfl: 12379 tbl_fdiv_ovfl: 12380 long 0x3fff - 0x7ffe 12380 long 0x3fff - 0x7ffe # ext overflow exponent 12381 long 0x3fff - 0x407e 12381 long 0x3fff - 0x407e # sgl overflow exponent 12382 long 0x3fff - 0x43fe 12382 long 0x3fff - 0x43fe # dbl overflow exponent 12383 12383 12384 global fsdiv 12384 global fsdiv 12385 fsdiv: 12385 fsdiv: 12386 andi.b &0x30,%d0 12386 andi.b &0x30,%d0 # clear rnd prec 12387 ori.b &s_mode*0x10,%d0 12387 ori.b &s_mode*0x10,%d0 # insert sgl prec 12388 bra.b fdiv 12388 bra.b fdiv 12389 12389 12390 global fddiv 12390 global fddiv 12391 fddiv: 12391 fddiv: 12392 andi.b &0x30,%d0 12392 andi.b &0x30,%d0 # clear rnd prec 12393 ori.b &d_mode*0x10,%d0 12393 ori.b &d_mode*0x10,%d0 # insert dbl prec 12394 12394 12395 global fdiv 12395 global fdiv 12396 fdiv: 12396 fdiv: 12397 mov.l %d0,L_SCR3(%a6) 12397 mov.l %d0,L_SCR3(%a6) # store rnd info 12398 12398 12399 clr.w %d1 12399 clr.w %d1 12400 mov.b DTAG(%a6),%d1 12400 mov.b DTAG(%a6),%d1 12401 lsl.b &0x3,%d1 12401 lsl.b &0x3,%d1 12402 or.b STAG(%a6),%d1 12402 or.b STAG(%a6),%d1 # combine src tags 12403 12403 12404 bne.w fdiv_not_norm 12404 bne.w fdiv_not_norm # optimize on non-norm input 12405 12405 12406 # 12406 # 12407 # DIVIDE: NORMs and DENORMs ONLY! 12407 # DIVIDE: NORMs and DENORMs ONLY! 12408 # 12408 # 12409 fdiv_norm: 12409 fdiv_norm: 12410 mov.w DST_EX(%a1),FP_SCR1_ 12410 mov.w DST_EX(%a1),FP_SCR1_EX(%a6) 12411 mov.l DST_HI(%a1),FP_SCR1_ 12411 mov.l DST_HI(%a1),FP_SCR1_HI(%a6) 12412 mov.l DST_LO(%a1),FP_SCR1_ 12412 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 12413 12413 12414 mov.w SRC_EX(%a0),FP_SCR0_ 12414 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 12415 mov.l SRC_HI(%a0),FP_SCR0_ 12415 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12416 mov.l SRC_LO(%a0),FP_SCR0_ 12416 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12417 12417 12418 bsr.l scale_to_zero_src 12418 bsr.l scale_to_zero_src # scale src exponent 12419 mov.l %d0,-(%sp) 12419 mov.l %d0,-(%sp) # save scale factor 1 12420 12420 12421 bsr.l scale_to_zero_dst 12421 bsr.l scale_to_zero_dst # scale dst exponent 12422 12422 12423 neg.l (%sp) 12423 neg.l (%sp) # SCALE FACTOR = scale1 - scale2 12424 add.l %d0,(%sp) 12424 add.l %d0,(%sp) 12425 12425 12426 mov.w 2+L_SCR3(%a6),%d1 12426 mov.w 2+L_SCR3(%a6),%d1 # fetch precision 12427 lsr.b &0x6,%d1 12427 lsr.b &0x6,%d1 # shift to lo bits 12428 mov.l (%sp)+,%d0 12428 mov.l (%sp)+,%d0 # load S.F. 12429 cmp.l %d0,(tbl_fdiv_ovfl.b 12429 cmp.l %d0,(tbl_fdiv_ovfl.b,%pc,%d1.w*4) # will result overflow? 12430 ble.w fdiv_may_ovfl 12430 ble.w fdiv_may_ovfl # result will overflow 12431 12431 12432 cmp.l %d0,(tbl_fdiv_unfl.w 12432 cmp.l %d0,(tbl_fdiv_unfl.w,%pc,%d1.w*4) # will result underflow? 12433 beq.w fdiv_may_unfl 12433 beq.w fdiv_may_unfl # maybe 12434 bgt.w fdiv_unfl 12434 bgt.w fdiv_unfl # yes; go handle underflow 12435 12435 12436 fdiv_normal: 12436 fdiv_normal: 12437 fmovm.x FP_SCR1(%a6),&0x80 12437 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 12438 12438 12439 fmov.l L_SCR3(%a6),%fpcr 12439 fmov.l L_SCR3(%a6),%fpcr # save FPCR 12440 fmov.l &0x0,%fpsr 12440 fmov.l &0x0,%fpsr # clear FPSR 12441 12441 12442 fdiv.x FP_SCR0(%a6),%fp0 12442 fdiv.x FP_SCR0(%a6),%fp0 # perform divide 12443 12443 12444 fmov.l %fpsr,%d1 12444 fmov.l %fpsr,%d1 # save FPSR 12445 fmov.l &0x0,%fpcr 12445 fmov.l &0x0,%fpcr # clear FPCR 12446 12446 12447 or.l %d1,USER_FPSR(%a6) 12447 or.l %d1,USER_FPSR(%a6) # save INEX2,N 12448 12448 12449 fdiv_normal_exit: 12449 fdiv_normal_exit: 12450 fmovm.x &0x80,FP_SCR0(%a6) 12450 fmovm.x &0x80,FP_SCR0(%a6) # store result on stack 12451 mov.l %d2,-(%sp) 12451 mov.l %d2,-(%sp) # store d2 12452 mov.w FP_SCR0_EX(%a6),%d1 12452 mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp} 12453 mov.l %d1,%d2 12453 mov.l %d1,%d2 # make a copy 12454 andi.l &0x7fff,%d1 12454 andi.l &0x7fff,%d1 # strip sign 12455 andi.w &0x8000,%d2 12455 andi.w &0x8000,%d2 # keep old sign 12456 sub.l %d0,%d1 12456 sub.l %d0,%d1 # add scale factor 12457 or.w %d2,%d1 12457 or.w %d2,%d1 # concat old sign,new exp 12458 mov.w %d1,FP_SCR0_EX(%a6) 12458 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 12459 mov.l (%sp)+,%d2 12459 mov.l (%sp)+,%d2 # restore d2 12460 fmovm.x FP_SCR0(%a6),&0x80 12460 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 12461 rts 12461 rts 12462 12462 12463 tbl_fdiv_ovfl2: 12463 tbl_fdiv_ovfl2: 12464 long 0x7fff 12464 long 0x7fff 12465 long 0x407f 12465 long 0x407f 12466 long 0x43ff 12466 long 0x43ff 12467 12467 12468 fdiv_no_ovfl: 12468 fdiv_no_ovfl: 12469 mov.l (%sp)+,%d0 12469 mov.l (%sp)+,%d0 # restore scale factor 12470 bra.b fdiv_normal_exit 12470 bra.b fdiv_normal_exit 12471 12471 12472 fdiv_may_ovfl: 12472 fdiv_may_ovfl: 12473 mov.l %d0,-(%sp) 12473 mov.l %d0,-(%sp) # save scale factor 12474 12474 12475 fmovm.x FP_SCR1(%a6),&0x80 12475 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 12476 12476 12477 fmov.l L_SCR3(%a6),%fpcr 12477 fmov.l L_SCR3(%a6),%fpcr # set FPCR 12478 fmov.l &0x0,%fpsr 12478 fmov.l &0x0,%fpsr # set FPSR 12479 12479 12480 fdiv.x FP_SCR0(%a6),%fp0 12480 fdiv.x FP_SCR0(%a6),%fp0 # execute divide 12481 12481 12482 fmov.l %fpsr,%d0 12482 fmov.l %fpsr,%d0 12483 fmov.l &0x0,%fpcr 12483 fmov.l &0x0,%fpcr 12484 12484 12485 or.l %d0,USER_FPSR(%a6) 12485 or.l %d0,USER_FPSR(%a6) # save INEX,N 12486 12486 12487 fmovm.x &0x01,-(%sp) 12487 fmovm.x &0x01,-(%sp) # save result to stack 12488 mov.w (%sp),%d0 12488 mov.w (%sp),%d0 # fetch new exponent 12489 add.l &0xc,%sp 12489 add.l &0xc,%sp # clear result from stack 12490 andi.l &0x7fff,%d0 12490 andi.l &0x7fff,%d0 # strip sign 12491 sub.l (%sp),%d0 12491 sub.l (%sp),%d0 # add scale factor 12492 cmp.l %d0,(tbl_fdiv_ovfl2. 12492 cmp.l %d0,(tbl_fdiv_ovfl2.b,%pc,%d1.w*4) 12493 blt.b fdiv_no_ovfl 12493 blt.b fdiv_no_ovfl 12494 mov.l (%sp)+,%d0 12494 mov.l (%sp)+,%d0 12495 12495 12496 fdiv_ovfl_tst: 12496 fdiv_ovfl_tst: 12497 or.l &ovfl_inx_mask,USER_ 12497 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 12498 12498 12499 mov.b FPCR_ENABLE(%a6),%d1 12499 mov.b FPCR_ENABLE(%a6),%d1 12500 andi.b &0x13,%d1 12500 andi.b &0x13,%d1 # is OVFL or INEX enabled? 12501 bne.b fdiv_ovfl_ena 12501 bne.b fdiv_ovfl_ena # yes 12502 12502 12503 fdiv_ovfl_dis: 12503 fdiv_ovfl_dis: 12504 btst &neg_bit,FPSR_CC(%a6 12504 btst &neg_bit,FPSR_CC(%a6) # is result negative? 12505 sne %d1 12505 sne %d1 # set sign param accordingly 12506 mov.l L_SCR3(%a6),%d0 12506 mov.l L_SCR3(%a6),%d0 # pass prec:rnd 12507 bsr.l ovf_res 12507 bsr.l ovf_res # calculate default result 12508 or.b %d0,FPSR_CC(%a6) 12508 or.b %d0,FPSR_CC(%a6) # set INF if applicable 12509 fmovm.x (%a0),&0x80 12509 fmovm.x (%a0),&0x80 # return default result in fp0 12510 rts 12510 rts 12511 12511 12512 fdiv_ovfl_ena: 12512 fdiv_ovfl_ena: 12513 mov.l L_SCR3(%a6),%d1 12513 mov.l L_SCR3(%a6),%d1 12514 andi.b &0xc0,%d1 12514 andi.b &0xc0,%d1 # is precision extended? 12515 bne.b fdiv_ovfl_ena_sd 12515 bne.b fdiv_ovfl_ena_sd # no, do sgl or dbl 12516 12516 12517 fdiv_ovfl_ena_cont: 12517 fdiv_ovfl_ena_cont: 12518 fmovm.x &0x80,FP_SCR0(%a6) 12518 fmovm.x &0x80,FP_SCR0(%a6) # move result to stack 12519 12519 12520 mov.l %d2,-(%sp) 12520 mov.l %d2,-(%sp) # save d2 12521 mov.w FP_SCR0_EX(%a6),%d1 12521 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 12522 mov.w %d1,%d2 12522 mov.w %d1,%d2 # make a copy 12523 andi.l &0x7fff,%d1 12523 andi.l &0x7fff,%d1 # strip sign 12524 sub.l %d0,%d1 12524 sub.l %d0,%d1 # add scale factor 12525 subi.l &0x6000,%d1 12525 subi.l &0x6000,%d1 # subtract bias 12526 andi.w &0x7fff,%d1 12526 andi.w &0x7fff,%d1 # clear sign bit 12527 andi.w &0x8000,%d2 12527 andi.w &0x8000,%d2 # keep old sign 12528 or.w %d2,%d1 12528 or.w %d2,%d1 # concat old sign,new exp 12529 mov.w %d1,FP_SCR0_EX(%a6) 12529 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 12530 mov.l (%sp)+,%d2 12530 mov.l (%sp)+,%d2 # restore d2 12531 fmovm.x FP_SCR0(%a6),&0x40 12531 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 12532 bra.b fdiv_ovfl_dis 12532 bra.b fdiv_ovfl_dis 12533 12533 12534 fdiv_ovfl_ena_sd: 12534 fdiv_ovfl_ena_sd: 12535 fmovm.x FP_SCR1(%a6),&0x80 12535 fmovm.x FP_SCR1(%a6),&0x80 # load dst operand 12536 12536 12537 mov.l L_SCR3(%a6),%d1 12537 mov.l L_SCR3(%a6),%d1 12538 andi.b &0x30,%d1 12538 andi.b &0x30,%d1 # keep rnd mode 12539 fmov.l %d1,%fpcr 12539 fmov.l %d1,%fpcr # set FPCR 12540 12540 12541 fdiv.x FP_SCR0(%a6),%fp0 12541 fdiv.x FP_SCR0(%a6),%fp0 # execute divide 12542 12542 12543 fmov.l &0x0,%fpcr 12543 fmov.l &0x0,%fpcr # clear FPCR 12544 bra.b fdiv_ovfl_ena_cont 12544 bra.b fdiv_ovfl_ena_cont 12545 12545 12546 fdiv_unfl: 12546 fdiv_unfl: 12547 bset &unfl_bit,FPSR_EXCEP 12547 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 12548 12548 12549 fmovm.x FP_SCR1(%a6),&0x80 12549 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 12550 12550 12551 fmov.l &rz_mode*0x10,%fpcr 12551 fmov.l &rz_mode*0x10,%fpcr # set FPCR 12552 fmov.l &0x0,%fpsr 12552 fmov.l &0x0,%fpsr # clear FPSR 12553 12553 12554 fdiv.x FP_SCR0(%a6),%fp0 12554 fdiv.x FP_SCR0(%a6),%fp0 # execute divide 12555 12555 12556 fmov.l %fpsr,%d1 12556 fmov.l %fpsr,%d1 # save status 12557 fmov.l &0x0,%fpcr 12557 fmov.l &0x0,%fpcr # clear FPCR 12558 12558 12559 or.l %d1,USER_FPSR(%a6) 12559 or.l %d1,USER_FPSR(%a6) # save INEX2,N 12560 12560 12561 mov.b FPCR_ENABLE(%a6),%d1 12561 mov.b FPCR_ENABLE(%a6),%d1 12562 andi.b &0x0b,%d1 12562 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 12563 bne.b fdiv_unfl_ena 12563 bne.b fdiv_unfl_ena # yes 12564 12564 12565 fdiv_unfl_dis: 12565 fdiv_unfl_dis: 12566 fmovm.x &0x80,FP_SCR0(%a6) 12566 fmovm.x &0x80,FP_SCR0(%a6) # store out result 12567 12567 12568 lea FP_SCR0(%a6),%a0 12568 lea FP_SCR0(%a6),%a0 # pass: result addr 12569 mov.l L_SCR3(%a6),%d1 12569 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 12570 bsr.l unf_res 12570 bsr.l unf_res # calculate default result 12571 or.b %d0,FPSR_CC(%a6) 12571 or.b %d0,FPSR_CC(%a6) # 'Z' may have been set 12572 fmovm.x FP_SCR0(%a6),&0x80 12572 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 12573 rts 12573 rts 12574 12574 12575 # 12575 # 12576 # UNFL is enabled. 12576 # UNFL is enabled. 12577 # 12577 # 12578 fdiv_unfl_ena: 12578 fdiv_unfl_ena: 12579 fmovm.x FP_SCR1(%a6),&0x40 12579 fmovm.x FP_SCR1(%a6),&0x40 # load dst op 12580 12580 12581 mov.l L_SCR3(%a6),%d1 12581 mov.l L_SCR3(%a6),%d1 12582 andi.b &0xc0,%d1 12582 andi.b &0xc0,%d1 # is precision extended? 12583 bne.b fdiv_unfl_ena_sd 12583 bne.b fdiv_unfl_ena_sd # no, sgl or dbl 12584 12584 12585 fmov.l L_SCR3(%a6),%fpcr 12585 fmov.l L_SCR3(%a6),%fpcr # set FPCR 12586 12586 12587 fdiv_unfl_ena_cont: 12587 fdiv_unfl_ena_cont: 12588 fmov.l &0x0,%fpsr 12588 fmov.l &0x0,%fpsr # clear FPSR 12589 12589 12590 fdiv.x FP_SCR0(%a6),%fp1 12590 fdiv.x FP_SCR0(%a6),%fp1 # execute divide 12591 12591 12592 fmov.l &0x0,%fpcr 12592 fmov.l &0x0,%fpcr # clear FPCR 12593 12593 12594 fmovm.x &0x40,FP_SCR0(%a6) 12594 fmovm.x &0x40,FP_SCR0(%a6) # save result to stack 12595 mov.l %d2,-(%sp) 12595 mov.l %d2,-(%sp) # save d2 12596 mov.w FP_SCR0_EX(%a6),%d1 12596 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 12597 mov.l %d1,%d2 12597 mov.l %d1,%d2 # make a copy 12598 andi.l &0x7fff,%d1 12598 andi.l &0x7fff,%d1 # strip sign 12599 andi.w &0x8000,%d2 12599 andi.w &0x8000,%d2 # keep old sign 12600 sub.l %d0,%d1 12600 sub.l %d0,%d1 # add scale factoer 12601 addi.l &0x6000,%d1 12601 addi.l &0x6000,%d1 # add bias 12602 andi.w &0x7fff,%d1 12602 andi.w &0x7fff,%d1 12603 or.w %d2,%d1 12603 or.w %d2,%d1 # concat old sign,new exp 12604 mov.w %d1,FP_SCR0_EX(%a6) 12604 mov.w %d1,FP_SCR0_EX(%a6) # insert new exp 12605 mov.l (%sp)+,%d2 12605 mov.l (%sp)+,%d2 # restore d2 12606 fmovm.x FP_SCR0(%a6),&0x40 12606 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 12607 bra.w fdiv_unfl_dis 12607 bra.w fdiv_unfl_dis 12608 12608 12609 fdiv_unfl_ena_sd: 12609 fdiv_unfl_ena_sd: 12610 mov.l L_SCR3(%a6),%d1 12610 mov.l L_SCR3(%a6),%d1 12611 andi.b &0x30,%d1 12611 andi.b &0x30,%d1 # use only rnd mode 12612 fmov.l %d1,%fpcr 12612 fmov.l %d1,%fpcr # set FPCR 12613 12613 12614 bra.b fdiv_unfl_ena_cont 12614 bra.b fdiv_unfl_ena_cont 12615 12615 12616 # 12616 # 12617 # the divide operation MAY underflow: 12617 # the divide operation MAY underflow: 12618 # 12618 # 12619 fdiv_may_unfl: 12619 fdiv_may_unfl: 12620 fmovm.x FP_SCR1(%a6),&0x80 12620 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 12621 12621 12622 fmov.l L_SCR3(%a6),%fpcr 12622 fmov.l L_SCR3(%a6),%fpcr # set FPCR 12623 fmov.l &0x0,%fpsr 12623 fmov.l &0x0,%fpsr # clear FPSR 12624 12624 12625 fdiv.x FP_SCR0(%a6),%fp0 12625 fdiv.x FP_SCR0(%a6),%fp0 # execute divide 12626 12626 12627 fmov.l %fpsr,%d1 12627 fmov.l %fpsr,%d1 # save status 12628 fmov.l &0x0,%fpcr 12628 fmov.l &0x0,%fpcr # clear FPCR 12629 12629 12630 or.l %d1,USER_FPSR(%a6) 12630 or.l %d1,USER_FPSR(%a6) # save INEX2,N 12631 12631 12632 fabs.x %fp0,%fp1 12632 fabs.x %fp0,%fp1 # make a copy of result 12633 fcmp.b %fp1,&0x1 12633 fcmp.b %fp1,&0x1 # is |result| > 1.b? 12634 fbgt.w fdiv_normal_exit 12634 fbgt.w fdiv_normal_exit # no; no underflow occurred 12635 fblt.w fdiv_unfl 12635 fblt.w fdiv_unfl # yes; underflow occurred 12636 12636 12637 # 12637 # 12638 # we still don't know if underflow occurred. 12638 # we still don't know if underflow occurred. result is ~ equal to 1. but, 12639 # we don't know if the result was an underfl 12639 # we don't know if the result was an underflow that rounded up to a 1 12640 # or a normalized number that rounded down t 12640 # or a normalized number that rounded down to a 1. so, redo the entire 12641 # operation using RZ as the rounding mode to 12641 # operation using RZ as the rounding mode to see what the pre-rounded 12642 # result is. this case should be relatively 12642 # result is. this case should be relatively rare. 12643 # 12643 # 12644 fmovm.x FP_SCR1(%a6),&0x40 12644 fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1 12645 12645 12646 mov.l L_SCR3(%a6),%d1 12646 mov.l L_SCR3(%a6),%d1 12647 andi.b &0xc0,%d1 12647 andi.b &0xc0,%d1 # keep rnd prec 12648 ori.b &rz_mode*0x10,%d1 12648 ori.b &rz_mode*0x10,%d1 # insert RZ 12649 12649 12650 fmov.l %d1,%fpcr 12650 fmov.l %d1,%fpcr # set FPCR 12651 fmov.l &0x0,%fpsr 12651 fmov.l &0x0,%fpsr # clear FPSR 12652 12652 12653 fdiv.x FP_SCR0(%a6),%fp1 12653 fdiv.x FP_SCR0(%a6),%fp1 # execute divide 12654 12654 12655 fmov.l &0x0,%fpcr 12655 fmov.l &0x0,%fpcr # clear FPCR 12656 fabs.x %fp1 12656 fabs.x %fp1 # make absolute value 12657 fcmp.b %fp1,&0x1 12657 fcmp.b %fp1,&0x1 # is |result| < 1.b? 12658 fbge.w fdiv_normal_exit 12658 fbge.w fdiv_normal_exit # no; no underflow occurred 12659 bra.w fdiv_unfl 12659 bra.w fdiv_unfl # yes; underflow occurred 12660 12660 12661 ############################################ 12661 ############################################################################ 12662 12662 12663 # 12663 # 12664 # Divide: inputs are not both normalized; wh 12664 # Divide: inputs are not both normalized; what are they? 12665 # 12665 # 12666 fdiv_not_norm: 12666 fdiv_not_norm: 12667 mov.w (tbl_fdiv_op.b,%pc,% 12667 mov.w (tbl_fdiv_op.b,%pc,%d1.w*2),%d1 12668 jmp (tbl_fdiv_op.b,%pc,% 12668 jmp (tbl_fdiv_op.b,%pc,%d1.w*1) 12669 12669 12670 swbeg &48 12670 swbeg &48 12671 tbl_fdiv_op: 12671 tbl_fdiv_op: 12672 short fdiv_norm - tb 12672 short fdiv_norm - tbl_fdiv_op # NORM / NORM 12673 short fdiv_inf_load - tb 12673 short fdiv_inf_load - tbl_fdiv_op # NORM / ZERO 12674 short fdiv_zero_load - tb 12674 short fdiv_zero_load - tbl_fdiv_op # NORM / INF 12675 short fdiv_res_qnan - tb 12675 short fdiv_res_qnan - tbl_fdiv_op # NORM / QNAN 12676 short fdiv_norm - tb 12676 short fdiv_norm - tbl_fdiv_op # NORM / DENORM 12677 short fdiv_res_snan - tb 12677 short fdiv_res_snan - tbl_fdiv_op # NORM / SNAN 12678 short tbl_fdiv_op - tb 12678 short tbl_fdiv_op - tbl_fdiv_op # 12679 short tbl_fdiv_op - tb 12679 short tbl_fdiv_op - tbl_fdiv_op # 12680 12680 12681 short fdiv_zero_load - tb 12681 short fdiv_zero_load - tbl_fdiv_op # ZERO / NORM 12682 short fdiv_res_operr - tb 12682 short fdiv_res_operr - tbl_fdiv_op # ZERO / ZERO 12683 short fdiv_zero_load - tb 12683 short fdiv_zero_load - tbl_fdiv_op # ZERO / INF 12684 short fdiv_res_qnan - tb 12684 short fdiv_res_qnan - tbl_fdiv_op # ZERO / QNAN 12685 short fdiv_zero_load - tb 12685 short fdiv_zero_load - tbl_fdiv_op # ZERO / DENORM 12686 short fdiv_res_snan - tb 12686 short fdiv_res_snan - tbl_fdiv_op # ZERO / SNAN 12687 short tbl_fdiv_op - tb 12687 short tbl_fdiv_op - tbl_fdiv_op # 12688 short tbl_fdiv_op - tb 12688 short tbl_fdiv_op - tbl_fdiv_op # 12689 12689 12690 short fdiv_inf_dst - tb 12690 short fdiv_inf_dst - tbl_fdiv_op # INF / NORM 12691 short fdiv_inf_dst - tb 12691 short fdiv_inf_dst - tbl_fdiv_op # INF / ZERO 12692 short fdiv_res_operr - tb 12692 short fdiv_res_operr - tbl_fdiv_op # INF / INF 12693 short fdiv_res_qnan - tb 12693 short fdiv_res_qnan - tbl_fdiv_op # INF / QNAN 12694 short fdiv_inf_dst - tb 12694 short fdiv_inf_dst - tbl_fdiv_op # INF / DENORM 12695 short fdiv_res_snan - tb 12695 short fdiv_res_snan - tbl_fdiv_op # INF / SNAN 12696 short tbl_fdiv_op - tb 12696 short tbl_fdiv_op - tbl_fdiv_op # 12697 short tbl_fdiv_op - tb 12697 short tbl_fdiv_op - tbl_fdiv_op # 12698 12698 12699 short fdiv_res_qnan - tb 12699 short fdiv_res_qnan - tbl_fdiv_op # QNAN / NORM 12700 short fdiv_res_qnan - tb 12700 short fdiv_res_qnan - tbl_fdiv_op # QNAN / ZERO 12701 short fdiv_res_qnan - tb 12701 short fdiv_res_qnan - tbl_fdiv_op # QNAN / INF 12702 short fdiv_res_qnan - tb 12702 short fdiv_res_qnan - tbl_fdiv_op # QNAN / QNAN 12703 short fdiv_res_qnan - tb 12703 short fdiv_res_qnan - tbl_fdiv_op # QNAN / DENORM 12704 short fdiv_res_snan - tb 12704 short fdiv_res_snan - tbl_fdiv_op # QNAN / SNAN 12705 short tbl_fdiv_op - tb 12705 short tbl_fdiv_op - tbl_fdiv_op # 12706 short tbl_fdiv_op - tb 12706 short tbl_fdiv_op - tbl_fdiv_op # 12707 12707 12708 short fdiv_norm - tb 12708 short fdiv_norm - tbl_fdiv_op # DENORM / NORM 12709 short fdiv_inf_load - tb 12709 short fdiv_inf_load - tbl_fdiv_op # DENORM / ZERO 12710 short fdiv_zero_load - tb 12710 short fdiv_zero_load - tbl_fdiv_op # DENORM / INF 12711 short fdiv_res_qnan - tb 12711 short fdiv_res_qnan - tbl_fdiv_op # DENORM / QNAN 12712 short fdiv_norm - tb 12712 short fdiv_norm - tbl_fdiv_op # DENORM / DENORM 12713 short fdiv_res_snan - tb 12713 short fdiv_res_snan - tbl_fdiv_op # DENORM / SNAN 12714 short tbl_fdiv_op - tb 12714 short tbl_fdiv_op - tbl_fdiv_op # 12715 short tbl_fdiv_op - tb 12715 short tbl_fdiv_op - tbl_fdiv_op # 12716 12716 12717 short fdiv_res_snan - tb 12717 short fdiv_res_snan - tbl_fdiv_op # SNAN / NORM 12718 short fdiv_res_snan - tb 12718 short fdiv_res_snan - tbl_fdiv_op # SNAN / ZERO 12719 short fdiv_res_snan - tb 12719 short fdiv_res_snan - tbl_fdiv_op # SNAN / INF 12720 short fdiv_res_snan - tb 12720 short fdiv_res_snan - tbl_fdiv_op # SNAN / QNAN 12721 short fdiv_res_snan - tb 12721 short fdiv_res_snan - tbl_fdiv_op # SNAN / DENORM 12722 short fdiv_res_snan - tb 12722 short fdiv_res_snan - tbl_fdiv_op # SNAN / SNAN 12723 short tbl_fdiv_op - tb 12723 short tbl_fdiv_op - tbl_fdiv_op # 12724 short tbl_fdiv_op - tb 12724 short tbl_fdiv_op - tbl_fdiv_op # 12725 12725 12726 fdiv_res_qnan: 12726 fdiv_res_qnan: 12727 bra.l res_qnan 12727 bra.l res_qnan 12728 fdiv_res_snan: 12728 fdiv_res_snan: 12729 bra.l res_snan 12729 bra.l res_snan 12730 fdiv_res_operr: 12730 fdiv_res_operr: 12731 bra.l res_operr 12731 bra.l res_operr 12732 12732 12733 global fdiv_zero_load 12733 global fdiv_zero_load # global for fsgldiv 12734 fdiv_zero_load: 12734 fdiv_zero_load: 12735 mov.b SRC_EX(%a0),%d0 12735 mov.b SRC_EX(%a0),%d0 # result sign is exclusive 12736 mov.b DST_EX(%a1),%d1 12736 mov.b DST_EX(%a1),%d1 # or of input signs. 12737 eor.b %d0,%d1 12737 eor.b %d0,%d1 12738 bpl.b fdiv_zero_load_p 12738 bpl.b fdiv_zero_load_p # result is positive 12739 fmov.s &0x80000000,%fp0 12739 fmov.s &0x80000000,%fp0 # load a -ZERO 12740 mov.b &z_bmask+neg_bmask,F 12740 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/N 12741 rts 12741 rts 12742 fdiv_zero_load_p: 12742 fdiv_zero_load_p: 12743 fmov.s &0x00000000,%fp0 12743 fmov.s &0x00000000,%fp0 # load a +ZERO 12744 mov.b &z_bmask,FPSR_CC(%a6 12744 mov.b &z_bmask,FPSR_CC(%a6) # set Z 12745 rts 12745 rts 12746 12746 12747 # 12747 # 12748 # The destination was In Range and the sourc 12748 # The destination was In Range and the source was a ZERO. The result, 12749 # Therefore, is an INF w/ the proper sign. 12749 # Therefore, is an INF w/ the proper sign. 12750 # So, determine the sign and return a new IN 12750 # So, determine the sign and return a new INF (w/ the j-bit cleared). 12751 # 12751 # 12752 global fdiv_inf_load 12752 global fdiv_inf_load # global for fsgldiv 12753 fdiv_inf_load: 12753 fdiv_inf_load: 12754 ori.w &dz_mask+adz_mask,2+ 12754 ori.w &dz_mask+adz_mask,2+USER_FPSR(%a6) # no; set DZ/ADZ 12755 mov.b SRC_EX(%a0),%d0 12755 mov.b SRC_EX(%a0),%d0 # load both signs 12756 mov.b DST_EX(%a1),%d1 12756 mov.b DST_EX(%a1),%d1 12757 eor.b %d0,%d1 12757 eor.b %d0,%d1 12758 bpl.b fdiv_inf_load_p 12758 bpl.b fdiv_inf_load_p # result is positive 12759 fmov.s &0xff800000,%fp0 12759 fmov.s &0xff800000,%fp0 # make result -INF 12760 mov.b &inf_bmask+neg_bmask 12760 mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/N 12761 rts 12761 rts 12762 fdiv_inf_load_p: 12762 fdiv_inf_load_p: 12763 fmov.s &0x7f800000,%fp0 12763 fmov.s &0x7f800000,%fp0 # make result +INF 12764 mov.b &inf_bmask,FPSR_CC(% 12764 mov.b &inf_bmask,FPSR_CC(%a6) # set INF 12765 rts 12765 rts 12766 12766 12767 # 12767 # 12768 # The destination was an INF w/ an In Range 12768 # The destination was an INF w/ an In Range or ZERO source, the result is 12769 # an INF w/ the proper sign. 12769 # an INF w/ the proper sign. 12770 # The 68881/882 returns the destination INF 12770 # The 68881/882 returns the destination INF w/ the new sign(if the j-bit of the 12771 # dst INF is set, then then j-bit of the res 12771 # dst INF is set, then then j-bit of the result INF is also set). 12772 # 12772 # 12773 global fdiv_inf_dst 12773 global fdiv_inf_dst # global for fsgldiv 12774 fdiv_inf_dst: 12774 fdiv_inf_dst: 12775 mov.b DST_EX(%a1),%d0 12775 mov.b DST_EX(%a1),%d0 # load both signs 12776 mov.b SRC_EX(%a0),%d1 12776 mov.b SRC_EX(%a0),%d1 12777 eor.b %d0,%d1 12777 eor.b %d0,%d1 12778 bpl.b fdiv_inf_dst_p 12778 bpl.b fdiv_inf_dst_p # result is positive 12779 12779 12780 fmovm.x DST(%a1),&0x80 12780 fmovm.x DST(%a1),&0x80 # return result in fp0 12781 fabs.x %fp0 12781 fabs.x %fp0 # clear sign bit 12782 fneg.x %fp0 12782 fneg.x %fp0 # set sign bit 12783 mov.b &inf_bmask+neg_bmask 12783 mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set INF/NEG 12784 rts 12784 rts 12785 12785 12786 fdiv_inf_dst_p: 12786 fdiv_inf_dst_p: 12787 fmovm.x DST(%a1),&0x80 12787 fmovm.x DST(%a1),&0x80 # return result in fp0 12788 fabs.x %fp0 12788 fabs.x %fp0 # return positive INF 12789 mov.b &inf_bmask,FPSR_CC(% 12789 mov.b &inf_bmask,FPSR_CC(%a6) # set INF 12790 rts 12790 rts 12791 12791 12792 ############################################ 12792 ######################################################################### 12793 # XDEF ************************************* 12793 # XDEF **************************************************************** # 12794 # fneg(): emulates the fneg instructio 12794 # fneg(): emulates the fneg instruction # 12795 # fsneg(): emulates the fsneg instruct 12795 # fsneg(): emulates the fsneg instruction # 12796 # fdneg(): emulates the fdneg instruct 12796 # fdneg(): emulates the fdneg instruction # 12797 # 12797 # # 12798 # XREF ************************************* 12798 # XREF **************************************************************** # 12799 # norm() - normalize a denorm to provi 12799 # norm() - normalize a denorm to provide EXOP # 12800 # scale_to_zero_src() - scale sgl/dbl 12800 # scale_to_zero_src() - scale sgl/dbl source exponent # 12801 # ovf_res() - return default overflow 12801 # ovf_res() - return default overflow result # 12802 # unf_res() - return default underflow 12802 # unf_res() - return default underflow result # 12803 # res_qnan_1op() - return QNAN result 12803 # res_qnan_1op() - return QNAN result # 12804 # res_snan_1op() - return SNAN result 12804 # res_snan_1op() - return SNAN result # 12805 # 12805 # # 12806 # INPUT ************************************ 12806 # INPUT *************************************************************** # 12807 # a0 = pointer to extended precision s 12807 # a0 = pointer to extended precision source operand # 12808 # d0 = rnd prec,mode 12808 # d0 = rnd prec,mode # 12809 # 12809 # # 12810 # OUTPUT *********************************** 12810 # OUTPUT ************************************************************** # 12811 # fp0 = result 12811 # fp0 = result # 12812 # fp1 = EXOP (if exception occurred) 12812 # fp1 = EXOP (if exception occurred) # 12813 # 12813 # # 12814 # ALGORITHM ******************************** 12814 # ALGORITHM *********************************************************** # 12815 # Handle NANs, zeroes, and infinities 12815 # Handle NANs, zeroes, and infinities as special cases. Separate # 12816 # norms/denorms into ext/sgl/dbl precisions. 12816 # norms/denorms into ext/sgl/dbl precisions. Extended precision can be # 12817 # emulated by simply setting sign bit. Sgl/d 12817 # emulated by simply setting sign bit. Sgl/dbl operands must be scaled # 12818 # and an actual fneg performed to see if ove 12818 # and an actual fneg performed to see if overflow/underflow would have # 12819 # occurred. If so, return default underflow/ 12819 # occurred. If so, return default underflow/overflow result. Else, # 12820 # scale the result exponent and return resul 12820 # scale the result exponent and return result. FPSR gets set based on # 12821 # the result value. 12821 # the result value. # 12822 # 12822 # # 12823 ############################################ 12823 ######################################################################### 12824 12824 12825 global fsneg 12825 global fsneg 12826 fsneg: 12826 fsneg: 12827 andi.b &0x30,%d0 12827 andi.b &0x30,%d0 # clear rnd prec 12828 ori.b &s_mode*0x10,%d0 12828 ori.b &s_mode*0x10,%d0 # insert sgl precision 12829 bra.b fneg 12829 bra.b fneg 12830 12830 12831 global fdneg 12831 global fdneg 12832 fdneg: 12832 fdneg: 12833 andi.b &0x30,%d0 12833 andi.b &0x30,%d0 # clear rnd prec 12834 ori.b &d_mode*0x10,%d0 12834 ori.b &d_mode*0x10,%d0 # insert dbl prec 12835 12835 12836 global fneg 12836 global fneg 12837 fneg: 12837 fneg: 12838 mov.l %d0,L_SCR3(%a6) 12838 mov.l %d0,L_SCR3(%a6) # store rnd info 12839 mov.b STAG(%a6),%d1 12839 mov.b STAG(%a6),%d1 12840 bne.w fneg_not_norm 12840 bne.w fneg_not_norm # optimize on non-norm input 12841 12841 12842 # 12842 # 12843 # NEGATE SIGN : norms and denorms ONLY! 12843 # NEGATE SIGN : norms and denorms ONLY! 12844 # 12844 # 12845 fneg_norm: 12845 fneg_norm: 12846 andi.b &0xc0,%d0 12846 andi.b &0xc0,%d0 # is precision extended? 12847 bne.w fneg_not_ext 12847 bne.w fneg_not_ext # no; go handle sgl or dbl 12848 12848 12849 # 12849 # 12850 # precision selected is extended. so...we ca 12850 # precision selected is extended. so...we can not get an underflow 12851 # or overflow because of rounding to the cor 12851 # or overflow because of rounding to the correct precision. so... 12852 # skip the scaling and unscaling... 12852 # skip the scaling and unscaling... 12853 # 12853 # 12854 mov.l SRC_HI(%a0),FP_SCR0_ 12854 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12855 mov.l SRC_LO(%a0),FP_SCR0_ 12855 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12856 mov.w SRC_EX(%a0),%d0 12856 mov.w SRC_EX(%a0),%d0 12857 eori.w &0x8000,%d0 12857 eori.w &0x8000,%d0 # negate sign 12858 bpl.b fneg_norm_load 12858 bpl.b fneg_norm_load # sign is positive 12859 mov.b &neg_bmask,FPSR_CC(% 12859 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 12860 fneg_norm_load: 12860 fneg_norm_load: 12861 mov.w %d0,FP_SCR0_EX(%a6) 12861 mov.w %d0,FP_SCR0_EX(%a6) 12862 fmovm.x FP_SCR0(%a6),&0x80 12862 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 12863 rts 12863 rts 12864 12864 12865 # 12865 # 12866 # for an extended precision DENORM, the UNFL 12866 # for an extended precision DENORM, the UNFL exception bit is set 12867 # the accrued bit is NOT set in this instanc 12867 # the accrued bit is NOT set in this instance(no inexactness!) 12868 # 12868 # 12869 fneg_denorm: 12869 fneg_denorm: 12870 andi.b &0xc0,%d0 12870 andi.b &0xc0,%d0 # is precision extended? 12871 bne.b fneg_not_ext 12871 bne.b fneg_not_ext # no; go handle sgl or dbl 12872 12872 12873 bset &unfl_bit,FPSR_EXCEP 12873 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 12874 12874 12875 mov.l SRC_HI(%a0),FP_SCR0_ 12875 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12876 mov.l SRC_LO(%a0),FP_SCR0_ 12876 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12877 mov.w SRC_EX(%a0),%d0 12877 mov.w SRC_EX(%a0),%d0 12878 eori.w &0x8000,%d0 12878 eori.w &0x8000,%d0 # negate sign 12879 bpl.b fneg_denorm_done 12879 bpl.b fneg_denorm_done # no 12880 mov.b &neg_bmask,FPSR_CC(% 12880 mov.b &neg_bmask,FPSR_CC(%a6) # yes, set 'N' ccode bit 12881 fneg_denorm_done: 12881 fneg_denorm_done: 12882 mov.w %d0,FP_SCR0_EX(%a6) 12882 mov.w %d0,FP_SCR0_EX(%a6) 12883 fmovm.x FP_SCR0(%a6),&0x80 12883 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 12884 12884 12885 btst &unfl_bit,FPCR_ENABL 12885 btst &unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled? 12886 bne.b fneg_ext_unfl_ena 12886 bne.b fneg_ext_unfl_ena # yes 12887 rts 12887 rts 12888 12888 12889 # 12889 # 12890 # the input is an extended DENORM and underf 12890 # the input is an extended DENORM and underflow is enabled in the FPCR. 12891 # normalize the mantissa and add the bias of 12891 # normalize the mantissa and add the bias of 0x6000 to the resulting negative 12892 # exponent and insert back into the operand. 12892 # exponent and insert back into the operand. 12893 # 12893 # 12894 fneg_ext_unfl_ena: 12894 fneg_ext_unfl_ena: 12895 lea FP_SCR0(%a6),%a0 12895 lea FP_SCR0(%a6),%a0 # pass: ptr to operand 12896 bsr.l norm 12896 bsr.l norm # normalize result 12897 neg.w %d0 12897 neg.w %d0 # new exponent = -(shft val) 12898 addi.w &0x6000,%d0 12898 addi.w &0x6000,%d0 # add new bias to exponent 12899 mov.w FP_SCR0_EX(%a6),%d1 12899 mov.w FP_SCR0_EX(%a6),%d1 # fetch old sign,exp 12900 andi.w &0x8000,%d1 12900 andi.w &0x8000,%d1 # keep old sign 12901 andi.w &0x7fff,%d0 12901 andi.w &0x7fff,%d0 # clear sign position 12902 or.w %d1,%d0 12902 or.w %d1,%d0 # concat old sign, new exponent 12903 mov.w %d0,FP_SCR0_EX(%a6) 12903 mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent 12904 fmovm.x FP_SCR0(%a6),&0x40 12904 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 12905 rts 12905 rts 12906 12906 12907 # 12907 # 12908 # operand is either single or double 12908 # operand is either single or double 12909 # 12909 # 12910 fneg_not_ext: 12910 fneg_not_ext: 12911 cmpi.b %d0,&s_mode*0x10 12911 cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec 12912 bne.b fneg_dbl 12912 bne.b fneg_dbl 12913 12913 12914 # 12914 # 12915 # operand is to be rounded to single precisi 12915 # operand is to be rounded to single precision 12916 # 12916 # 12917 fneg_sgl: 12917 fneg_sgl: 12918 mov.w SRC_EX(%a0),FP_SCR0_ 12918 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 12919 mov.l SRC_HI(%a0),FP_SCR0_ 12919 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12920 mov.l SRC_LO(%a0),FP_SCR0_ 12920 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12921 bsr.l scale_to_zero_src 12921 bsr.l scale_to_zero_src # calculate scale factor 12922 12922 12923 cmpi.l %d0,&0x3fff-0x3f80 12923 cmpi.l %d0,&0x3fff-0x3f80 # will move in underflow? 12924 bge.w fneg_sd_unfl 12924 bge.w fneg_sd_unfl # yes; go handle underflow 12925 cmpi.l %d0,&0x3fff-0x407e 12925 cmpi.l %d0,&0x3fff-0x407e # will move in overflow? 12926 beq.w fneg_sd_may_ovfl 12926 beq.w fneg_sd_may_ovfl # maybe; go check 12927 blt.w fneg_sd_ovfl 12927 blt.w fneg_sd_ovfl # yes; go handle overflow 12928 12928 12929 # 12929 # 12930 # operand will NOT overflow or underflow whe 12930 # operand will NOT overflow or underflow when moved in to the fp reg file 12931 # 12931 # 12932 fneg_sd_normal: 12932 fneg_sd_normal: 12933 fmov.l &0x0,%fpsr 12933 fmov.l &0x0,%fpsr # clear FPSR 12934 fmov.l L_SCR3(%a6),%fpcr 12934 fmov.l L_SCR3(%a6),%fpcr # set FPCR 12935 12935 12936 fneg.x FP_SCR0(%a6),%fp0 12936 fneg.x FP_SCR0(%a6),%fp0 # perform negation 12937 12937 12938 fmov.l %fpsr,%d1 12938 fmov.l %fpsr,%d1 # save FPSR 12939 fmov.l &0x0,%fpcr 12939 fmov.l &0x0,%fpcr # clear FPCR 12940 12940 12941 or.l %d1,USER_FPSR(%a6) 12941 or.l %d1,USER_FPSR(%a6) # save INEX2,N 12942 12942 12943 fneg_sd_normal_exit: 12943 fneg_sd_normal_exit: 12944 mov.l %d2,-(%sp) 12944 mov.l %d2,-(%sp) # save d2 12945 fmovm.x &0x80,FP_SCR0(%a6) 12945 fmovm.x &0x80,FP_SCR0(%a6) # store out result 12946 mov.w FP_SCR0_EX(%a6),%d1 12946 mov.w FP_SCR0_EX(%a6),%d1 # load sgn,exp 12947 mov.w %d1,%d2 12947 mov.w %d1,%d2 # make a copy 12948 andi.l &0x7fff,%d1 12948 andi.l &0x7fff,%d1 # strip sign 12949 sub.l %d0,%d1 12949 sub.l %d0,%d1 # add scale factor 12950 andi.w &0x8000,%d2 12950 andi.w &0x8000,%d2 # keep old sign 12951 or.w %d1,%d2 12951 or.w %d1,%d2 # concat old sign,new exp 12952 mov.w %d2,FP_SCR0_EX(%a6) 12952 mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent 12953 mov.l (%sp)+,%d2 12953 mov.l (%sp)+,%d2 # restore d2 12954 fmovm.x FP_SCR0(%a6),&0x80 12954 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 12955 rts 12955 rts 12956 12956 12957 # 12957 # 12958 # operand is to be rounded to double precisi 12958 # operand is to be rounded to double precision 12959 # 12959 # 12960 fneg_dbl: 12960 fneg_dbl: 12961 mov.w SRC_EX(%a0),FP_SCR0_ 12961 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 12962 mov.l SRC_HI(%a0),FP_SCR0_ 12962 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 12963 mov.l SRC_LO(%a0),FP_SCR0_ 12963 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 12964 bsr.l scale_to_zero_src 12964 bsr.l scale_to_zero_src # calculate scale factor 12965 12965 12966 cmpi.l %d0,&0x3fff-0x3c00 12966 cmpi.l %d0,&0x3fff-0x3c00 # will move in underflow? 12967 bge.b fneg_sd_unfl 12967 bge.b fneg_sd_unfl # yes; go handle underflow 12968 cmpi.l %d0,&0x3fff-0x43fe 12968 cmpi.l %d0,&0x3fff-0x43fe # will move in overflow? 12969 beq.w fneg_sd_may_ovfl 12969 beq.w fneg_sd_may_ovfl # maybe; go check 12970 blt.w fneg_sd_ovfl 12970 blt.w fneg_sd_ovfl # yes; go handle overflow 12971 bra.w fneg_sd_normal 12971 bra.w fneg_sd_normal # no; ho handle normalized op 12972 12972 12973 # 12973 # 12974 # operand WILL underflow when moved in to th 12974 # operand WILL underflow when moved in to the fp register file 12975 # 12975 # 12976 fneg_sd_unfl: 12976 fneg_sd_unfl: 12977 bset &unfl_bit,FPSR_EXCEP 12977 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 12978 12978 12979 eori.b &0x80,FP_SCR0_EX(%a6 12979 eori.b &0x80,FP_SCR0_EX(%a6) # negate sign 12980 bpl.b fneg_sd_unfl_tst 12980 bpl.b fneg_sd_unfl_tst 12981 bset &neg_bit,FPSR_CC(%a6 12981 bset &neg_bit,FPSR_CC(%a6) # set 'N' ccode bit 12982 12982 12983 # if underflow or inexact is enabled, go cal 12983 # if underflow or inexact is enabled, go calculate EXOP first. 12984 fneg_sd_unfl_tst: 12984 fneg_sd_unfl_tst: 12985 mov.b FPCR_ENABLE(%a6),%d1 12985 mov.b FPCR_ENABLE(%a6),%d1 12986 andi.b &0x0b,%d1 12986 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 12987 bne.b fneg_sd_unfl_ena 12987 bne.b fneg_sd_unfl_ena # yes 12988 12988 12989 fneg_sd_unfl_dis: 12989 fneg_sd_unfl_dis: 12990 lea FP_SCR0(%a6),%a0 12990 lea FP_SCR0(%a6),%a0 # pass: result addr 12991 mov.l L_SCR3(%a6),%d1 12991 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 12992 bsr.l unf_res 12992 bsr.l unf_res # calculate default result 12993 or.b %d0,FPSR_CC(%a6) 12993 or.b %d0,FPSR_CC(%a6) # unf_res may have set 'Z' 12994 fmovm.x FP_SCR0(%a6),&0x80 12994 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 12995 rts 12995 rts 12996 12996 12997 # 12997 # 12998 # operand will underflow AND underflow is en 12998 # operand will underflow AND underflow is enabled. 12999 # Therefore, we must return the result round 12999 # Therefore, we must return the result rounded to extended precision. 13000 # 13000 # 13001 fneg_sd_unfl_ena: 13001 fneg_sd_unfl_ena: 13002 mov.l FP_SCR0_HI(%a6),FP_S 13002 mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) 13003 mov.l FP_SCR0_LO(%a6),FP_S 13003 mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6) 13004 mov.w FP_SCR0_EX(%a6),%d1 13004 mov.w FP_SCR0_EX(%a6),%d1 # load current exponent 13005 13005 13006 mov.l %d2,-(%sp) 13006 mov.l %d2,-(%sp) # save d2 13007 mov.l %d1,%d2 13007 mov.l %d1,%d2 # make a copy 13008 andi.l &0x7fff,%d1 13008 andi.l &0x7fff,%d1 # strip sign 13009 andi.w &0x8000,%d2 13009 andi.w &0x8000,%d2 # keep old sign 13010 sub.l %d0,%d1 13010 sub.l %d0,%d1 # subtract scale factor 13011 addi.l &0x6000,%d1 13011 addi.l &0x6000,%d1 # add new bias 13012 andi.w &0x7fff,%d1 13012 andi.w &0x7fff,%d1 13013 or.w %d2,%d1 13013 or.w %d2,%d1 # concat new sign,new exp 13014 mov.w %d1,FP_SCR1_EX(%a6) 13014 mov.w %d1,FP_SCR1_EX(%a6) # insert new exp 13015 fmovm.x FP_SCR1(%a6),&0x40 13015 fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1 13016 mov.l (%sp)+,%d2 13016 mov.l (%sp)+,%d2 # restore d2 13017 bra.b fneg_sd_unfl_dis 13017 bra.b fneg_sd_unfl_dis 13018 13018 13019 # 13019 # 13020 # operand WILL overflow. 13020 # operand WILL overflow. 13021 # 13021 # 13022 fneg_sd_ovfl: 13022 fneg_sd_ovfl: 13023 fmov.l &0x0,%fpsr 13023 fmov.l &0x0,%fpsr # clear FPSR 13024 fmov.l L_SCR3(%a6),%fpcr 13024 fmov.l L_SCR3(%a6),%fpcr # set FPCR 13025 13025 13026 fneg.x FP_SCR0(%a6),%fp0 13026 fneg.x FP_SCR0(%a6),%fp0 # perform negation 13027 13027 13028 fmov.l &0x0,%fpcr 13028 fmov.l &0x0,%fpcr # clear FPCR 13029 fmov.l %fpsr,%d1 13029 fmov.l %fpsr,%d1 # save FPSR 13030 13030 13031 or.l %d1,USER_FPSR(%a6) 13031 or.l %d1,USER_FPSR(%a6) # save INEX2,N 13032 13032 13033 fneg_sd_ovfl_tst: 13033 fneg_sd_ovfl_tst: 13034 or.l &ovfl_inx_mask,USER_ 13034 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 13035 13035 13036 mov.b FPCR_ENABLE(%a6),%d1 13036 mov.b FPCR_ENABLE(%a6),%d1 13037 andi.b &0x13,%d1 13037 andi.b &0x13,%d1 # is OVFL or INEX enabled? 13038 bne.b fneg_sd_ovfl_ena 13038 bne.b fneg_sd_ovfl_ena # yes 13039 13039 13040 # 13040 # 13041 # OVFL is not enabled; therefore, we must cr 13041 # OVFL is not enabled; therefore, we must create the default result by 13042 # calling ovf_res(). 13042 # calling ovf_res(). 13043 # 13043 # 13044 fneg_sd_ovfl_dis: 13044 fneg_sd_ovfl_dis: 13045 btst &neg_bit,FPSR_CC(%a6 13045 btst &neg_bit,FPSR_CC(%a6) # is result negative? 13046 sne %d1 13046 sne %d1 # set sign param accordingly 13047 mov.l L_SCR3(%a6),%d0 13047 mov.l L_SCR3(%a6),%d0 # pass: prec,mode 13048 bsr.l ovf_res 13048 bsr.l ovf_res # calculate default result 13049 or.b %d0,FPSR_CC(%a6) 13049 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 13050 fmovm.x (%a0),&0x80 13050 fmovm.x (%a0),&0x80 # return default result in fp0 13051 rts 13051 rts 13052 13052 13053 # 13053 # 13054 # OVFL is enabled. 13054 # OVFL is enabled. 13055 # the INEX2 bit has already been updated by 13055 # the INEX2 bit has already been updated by the round to the correct precision. 13056 # now, round to extended(and don't alter the 13056 # now, round to extended(and don't alter the FPSR). 13057 # 13057 # 13058 fneg_sd_ovfl_ena: 13058 fneg_sd_ovfl_ena: 13059 mov.l %d2,-(%sp) 13059 mov.l %d2,-(%sp) # save d2 13060 mov.w FP_SCR0_EX(%a6),%d1 13060 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 13061 mov.l %d1,%d2 13061 mov.l %d1,%d2 # make a copy 13062 andi.l &0x7fff,%d1 13062 andi.l &0x7fff,%d1 # strip sign 13063 andi.w &0x8000,%d2 13063 andi.w &0x8000,%d2 # keep old sign 13064 sub.l %d0,%d1 13064 sub.l %d0,%d1 # add scale factor 13065 subi.l &0x6000,%d1 13065 subi.l &0x6000,%d1 # subtract bias 13066 andi.w &0x7fff,%d1 13066 andi.w &0x7fff,%d1 13067 or.w %d2,%d1 13067 or.w %d2,%d1 # concat sign,exp 13068 mov.w %d1,FP_SCR0_EX(%a6) 13068 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 13069 fmovm.x FP_SCR0(%a6),&0x40 13069 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 13070 mov.l (%sp)+,%d2 13070 mov.l (%sp)+,%d2 # restore d2 13071 bra.b fneg_sd_ovfl_dis 13071 bra.b fneg_sd_ovfl_dis 13072 13072 13073 # 13073 # 13074 # the move in MAY underflow. so... 13074 # the move in MAY underflow. so... 13075 # 13075 # 13076 fneg_sd_may_ovfl: 13076 fneg_sd_may_ovfl: 13077 fmov.l &0x0,%fpsr 13077 fmov.l &0x0,%fpsr # clear FPSR 13078 fmov.l L_SCR3(%a6),%fpcr 13078 fmov.l L_SCR3(%a6),%fpcr # set FPCR 13079 13079 13080 fneg.x FP_SCR0(%a6),%fp0 13080 fneg.x FP_SCR0(%a6),%fp0 # perform negation 13081 13081 13082 fmov.l %fpsr,%d1 13082 fmov.l %fpsr,%d1 # save status 13083 fmov.l &0x0,%fpcr 13083 fmov.l &0x0,%fpcr # clear FPCR 13084 13084 13085 or.l %d1,USER_FPSR(%a6) 13085 or.l %d1,USER_FPSR(%a6) # save INEX2,N 13086 13086 13087 fabs.x %fp0,%fp1 13087 fabs.x %fp0,%fp1 # make a copy of result 13088 fcmp.b %fp1,&0x2 13088 fcmp.b %fp1,&0x2 # is |result| >= 2.b? 13089 fbge.w fneg_sd_ovfl_tst 13089 fbge.w fneg_sd_ovfl_tst # yes; overflow has occurred 13090 13090 13091 # no, it didn't overflow; we have correct re 13091 # no, it didn't overflow; we have correct result 13092 bra.w fneg_sd_normal_exit 13092 bra.w fneg_sd_normal_exit 13093 13093 13094 ############################################ 13094 ########################################################################## 13095 13095 13096 # 13096 # 13097 # input is not normalized; what is it? 13097 # input is not normalized; what is it? 13098 # 13098 # 13099 fneg_not_norm: 13099 fneg_not_norm: 13100 cmpi.b %d1,&DENORM 13100 cmpi.b %d1,&DENORM # weed out DENORM 13101 beq.w fneg_denorm 13101 beq.w fneg_denorm 13102 cmpi.b %d1,&SNAN 13102 cmpi.b %d1,&SNAN # weed out SNAN 13103 beq.l res_snan_1op 13103 beq.l res_snan_1op 13104 cmpi.b %d1,&QNAN 13104 cmpi.b %d1,&QNAN # weed out QNAN 13105 beq.l res_qnan_1op 13105 beq.l res_qnan_1op 13106 13106 13107 # 13107 # 13108 # do the fneg; at this point, only possible 13108 # do the fneg; at this point, only possible ops are ZERO and INF. 13109 # use fneg to determine ccodes. 13109 # use fneg to determine ccodes. 13110 # prec:mode should be zero at this point but 13110 # prec:mode should be zero at this point but it won't affect answer anyways. 13111 # 13111 # 13112 fneg.x SRC_EX(%a0),%fp0 13112 fneg.x SRC_EX(%a0),%fp0 # do fneg 13113 fmov.l %fpsr,%d0 13113 fmov.l %fpsr,%d0 13114 rol.l &0x8,%d0 13114 rol.l &0x8,%d0 # put ccodes in lo byte 13115 mov.b %d0,FPSR_CC(%a6) 13115 mov.b %d0,FPSR_CC(%a6) # insert correct ccodes 13116 rts 13116 rts 13117 13117 13118 ############################################ 13118 ######################################################################### 13119 # XDEF ************************************* 13119 # XDEF **************************************************************** # 13120 # ftst(): emulates the ftest instructi 13120 # ftst(): emulates the ftest instruction # 13121 # 13121 # # 13122 # XREF ************************************* 13122 # XREF **************************************************************** # 13123 # res{s,q}nan_1op() - set NAN result f 13123 # res{s,q}nan_1op() - set NAN result for monadic instruction # 13124 # 13124 # # 13125 # INPUT ************************************ 13125 # INPUT *************************************************************** # 13126 # a0 = pointer to extended precision s 13126 # a0 = pointer to extended precision source operand # 13127 # 13127 # # 13128 # OUTPUT *********************************** 13128 # OUTPUT ************************************************************** # 13129 # none 13129 # none # 13130 # 13130 # # 13131 # ALGORITHM ******************************** 13131 # ALGORITHM *********************************************************** # 13132 # Check the source operand tag (STAG) 13132 # Check the source operand tag (STAG) and set the FPCR according # 13133 # to the operand type and sign. 13133 # to the operand type and sign. # 13134 # 13134 # # 13135 ############################################ 13135 ######################################################################### 13136 13136 13137 global ftst 13137 global ftst 13138 ftst: 13138 ftst: 13139 mov.b STAG(%a6),%d1 13139 mov.b STAG(%a6),%d1 13140 bne.b ftst_not_norm 13140 bne.b ftst_not_norm # optimize on non-norm input 13141 13141 13142 # 13142 # 13143 # Norm: 13143 # Norm: 13144 # 13144 # 13145 ftst_norm: 13145 ftst_norm: 13146 tst.b SRC_EX(%a0) 13146 tst.b SRC_EX(%a0) # is operand negative? 13147 bmi.b ftst_norm_m 13147 bmi.b ftst_norm_m # yes 13148 rts 13148 rts 13149 ftst_norm_m: 13149 ftst_norm_m: 13150 mov.b &neg_bmask,FPSR_CC(% 13150 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 13151 rts 13151 rts 13152 13152 13153 # 13153 # 13154 # input is not normalized; what is it? 13154 # input is not normalized; what is it? 13155 # 13155 # 13156 ftst_not_norm: 13156 ftst_not_norm: 13157 cmpi.b %d1,&ZERO 13157 cmpi.b %d1,&ZERO # weed out ZERO 13158 beq.b ftst_zero 13158 beq.b ftst_zero 13159 cmpi.b %d1,&INF 13159 cmpi.b %d1,&INF # weed out INF 13160 beq.b ftst_inf 13160 beq.b ftst_inf 13161 cmpi.b %d1,&SNAN 13161 cmpi.b %d1,&SNAN # weed out SNAN 13162 beq.l res_snan_1op 13162 beq.l res_snan_1op 13163 cmpi.b %d1,&QNAN 13163 cmpi.b %d1,&QNAN # weed out QNAN 13164 beq.l res_qnan_1op 13164 beq.l res_qnan_1op 13165 13165 13166 # 13166 # 13167 # Denorm: 13167 # Denorm: 13168 # 13168 # 13169 ftst_denorm: 13169 ftst_denorm: 13170 tst.b SRC_EX(%a0) 13170 tst.b SRC_EX(%a0) # is operand negative? 13171 bmi.b ftst_denorm_m 13171 bmi.b ftst_denorm_m # yes 13172 rts 13172 rts 13173 ftst_denorm_m: 13173 ftst_denorm_m: 13174 mov.b &neg_bmask,FPSR_CC(% 13174 mov.b &neg_bmask,FPSR_CC(%a6) # set 'N' ccode bit 13175 rts 13175 rts 13176 13176 13177 # 13177 # 13178 # Infinity: 13178 # Infinity: 13179 # 13179 # 13180 ftst_inf: 13180 ftst_inf: 13181 tst.b SRC_EX(%a0) 13181 tst.b SRC_EX(%a0) # is operand negative? 13182 bmi.b ftst_inf_m 13182 bmi.b ftst_inf_m # yes 13183 ftst_inf_p: 13183 ftst_inf_p: 13184 mov.b &inf_bmask,FPSR_CC(% 13184 mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit 13185 rts 13185 rts 13186 ftst_inf_m: 13186 ftst_inf_m: 13187 mov.b &inf_bmask+neg_bmask 13187 mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'I','N' ccode bits 13188 rts 13188 rts 13189 13189 13190 # 13190 # 13191 # Zero: 13191 # Zero: 13192 # 13192 # 13193 ftst_zero: 13193 ftst_zero: 13194 tst.b SRC_EX(%a0) 13194 tst.b SRC_EX(%a0) # is operand negative? 13195 bmi.b ftst_zero_m 13195 bmi.b ftst_zero_m # yes 13196 ftst_zero_p: 13196 ftst_zero_p: 13197 mov.b &z_bmask,FPSR_CC(%a6 13197 mov.b &z_bmask,FPSR_CC(%a6) # set 'N' ccode bit 13198 rts 13198 rts 13199 ftst_zero_m: 13199 ftst_zero_m: 13200 mov.b &z_bmask+neg_bmask,F 13200 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits 13201 rts 13201 rts 13202 13202 13203 ############################################ 13203 ######################################################################### 13204 # XDEF ************************************* 13204 # XDEF **************************************************************** # 13205 # fint(): emulates the fint instructio 13205 # fint(): emulates the fint instruction # 13206 # 13206 # # 13207 # XREF ************************************* 13207 # XREF **************************************************************** # 13208 # res_{s,q}nan_1op() - set NAN result 13208 # res_{s,q}nan_1op() - set NAN result for monadic operation # 13209 # 13209 # # 13210 # INPUT ************************************ 13210 # INPUT *************************************************************** # 13211 # a0 = pointer to extended precision s 13211 # a0 = pointer to extended precision source operand # 13212 # d0 = round precision/mode 13212 # d0 = round precision/mode # 13213 # 13213 # # 13214 # OUTPUT *********************************** 13214 # OUTPUT ************************************************************** # 13215 # fp0 = result 13215 # fp0 = result # 13216 # 13216 # # 13217 # ALGORITHM ******************************** 13217 # ALGORITHM *********************************************************** # 13218 # Separate according to operand type. 13218 # Separate according to operand type. Unnorms don't pass through # 13219 # here. For norms, load the rounding mode/pr 13219 # here. For norms, load the rounding mode/prec, execute a "fint", then # 13220 # store the resulting FPSR bits. 13220 # store the resulting FPSR bits. # 13221 # For denorms, force the j-bit to a on 13221 # For denorms, force the j-bit to a one and do the same as for # 13222 # norms. Denorms are so low that the answer 13222 # norms. Denorms are so low that the answer will either be a zero or a # 13223 # one. 13223 # one. # 13224 # For zeroes/infs/NANs, return the sam 13224 # For zeroes/infs/NANs, return the same while setting the FPSR # 13225 # as appropriate. 13225 # as appropriate. # 13226 # 13226 # # 13227 ############################################ 13227 ######################################################################### 13228 13228 13229 global fint 13229 global fint 13230 fint: 13230 fint: 13231 mov.b STAG(%a6),%d1 13231 mov.b STAG(%a6),%d1 13232 bne.b fint_not_norm 13232 bne.b fint_not_norm # optimize on non-norm input 13233 13233 13234 # 13234 # 13235 # Norm: 13235 # Norm: 13236 # 13236 # 13237 fint_norm: 13237 fint_norm: 13238 andi.b &0x30,%d0 13238 andi.b &0x30,%d0 # set prec = ext 13239 13239 13240 fmov.l %d0,%fpcr 13240 fmov.l %d0,%fpcr # set FPCR 13241 fmov.l &0x0,%fpsr 13241 fmov.l &0x0,%fpsr # clear FPSR 13242 13242 13243 fint.x SRC(%a0),%fp0 13243 fint.x SRC(%a0),%fp0 # execute fint 13244 13244 13245 fmov.l &0x0,%fpcr 13245 fmov.l &0x0,%fpcr # clear FPCR 13246 fmov.l %fpsr,%d0 13246 fmov.l %fpsr,%d0 # save FPSR 13247 or.l %d0,USER_FPSR(%a6) 13247 or.l %d0,USER_FPSR(%a6) # set exception bits 13248 13248 13249 rts 13249 rts 13250 13250 13251 # 13251 # 13252 # input is not normalized; what is it? 13252 # input is not normalized; what is it? 13253 # 13253 # 13254 fint_not_norm: 13254 fint_not_norm: 13255 cmpi.b %d1,&ZERO 13255 cmpi.b %d1,&ZERO # weed out ZERO 13256 beq.b fint_zero 13256 beq.b fint_zero 13257 cmpi.b %d1,&INF 13257 cmpi.b %d1,&INF # weed out INF 13258 beq.b fint_inf 13258 beq.b fint_inf 13259 cmpi.b %d1,&DENORM 13259 cmpi.b %d1,&DENORM # weed out DENORM 13260 beq.b fint_denorm 13260 beq.b fint_denorm 13261 cmpi.b %d1,&SNAN 13261 cmpi.b %d1,&SNAN # weed out SNAN 13262 beq.l res_snan_1op 13262 beq.l res_snan_1op 13263 bra.l res_qnan_1op 13263 bra.l res_qnan_1op # weed out QNAN 13264 13264 13265 # 13265 # 13266 # Denorm: 13266 # Denorm: 13267 # 13267 # 13268 # for DENORMs, the result will be either (+/ 13268 # for DENORMs, the result will be either (+/-)ZERO or (+/-)1. 13269 # also, the INEX2 and AINEX exception bits w 13269 # also, the INEX2 and AINEX exception bits will be set. 13270 # so, we could either set these manually or 13270 # so, we could either set these manually or force the DENORM 13271 # to a very small NORM and ship it to the NO 13271 # to a very small NORM and ship it to the NORM routine. 13272 # I do the latter. 13272 # I do the latter. 13273 # 13273 # 13274 fint_denorm: 13274 fint_denorm: 13275 mov.w SRC_EX(%a0),FP_SCR0_ 13275 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp 13276 mov.b &0x80,FP_SCR0_HI(%a6 13276 mov.b &0x80,FP_SCR0_HI(%a6) # force DENORM ==> small NORM 13277 lea FP_SCR0(%a6),%a0 13277 lea FP_SCR0(%a6),%a0 13278 bra.b fint_norm 13278 bra.b fint_norm 13279 13279 13280 # 13280 # 13281 # Zero: 13281 # Zero: 13282 # 13282 # 13283 fint_zero: 13283 fint_zero: 13284 tst.b SRC_EX(%a0) 13284 tst.b SRC_EX(%a0) # is ZERO negative? 13285 bmi.b fint_zero_m 13285 bmi.b fint_zero_m # yes 13286 fint_zero_p: 13286 fint_zero_p: 13287 fmov.s &0x00000000,%fp0 13287 fmov.s &0x00000000,%fp0 # return +ZERO in fp0 13288 mov.b &z_bmask,FPSR_CC(%a6 13288 mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 13289 rts 13289 rts 13290 fint_zero_m: 13290 fint_zero_m: 13291 fmov.s &0x80000000,%fp0 13291 fmov.s &0x80000000,%fp0 # return -ZERO in fp0 13292 mov.b &z_bmask+neg_bmask,F 13292 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits 13293 rts 13293 rts 13294 13294 13295 # 13295 # 13296 # Infinity: 13296 # Infinity: 13297 # 13297 # 13298 fint_inf: 13298 fint_inf: 13299 fmovm.x SRC(%a0),&0x80 13299 fmovm.x SRC(%a0),&0x80 # return result in fp0 13300 tst.b SRC_EX(%a0) 13300 tst.b SRC_EX(%a0) # is INF negative? 13301 bmi.b fint_inf_m 13301 bmi.b fint_inf_m # yes 13302 fint_inf_p: 13302 fint_inf_p: 13303 mov.b &inf_bmask,FPSR_CC(% 13303 mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit 13304 rts 13304 rts 13305 fint_inf_m: 13305 fint_inf_m: 13306 mov.b &inf_bmask+neg_bmask 13306 mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits 13307 rts 13307 rts 13308 13308 13309 ############################################ 13309 ######################################################################### 13310 # XDEF ************************************* 13310 # XDEF **************************************************************** # 13311 # fintrz(): emulates the fintrz instru 13311 # fintrz(): emulates the fintrz instruction # 13312 # 13312 # # 13313 # XREF ************************************* 13313 # XREF **************************************************************** # 13314 # res_{s,q}nan_1op() - set NAN result 13314 # res_{s,q}nan_1op() - set NAN result for monadic operation # 13315 # 13315 # # 13316 # INPUT ************************************ 13316 # INPUT *************************************************************** # 13317 # a0 = pointer to extended precision s 13317 # a0 = pointer to extended precision source operand # 13318 # d0 = round precision/mode 13318 # d0 = round precision/mode # 13319 # 13319 # # 13320 # OUTPUT *********************************** 13320 # OUTPUT ************************************************************** # 13321 # fp0 = result 13321 # fp0 = result # 13322 # 13322 # # 13323 # ALGORITHM ******************************** 13323 # ALGORITHM *********************************************************** # 13324 # Separate according to operand type. 13324 # Separate according to operand type. Unnorms don't pass through # 13325 # here. For norms, load the rounding mode/pr 13325 # here. For norms, load the rounding mode/prec, execute a "fintrz", # 13326 # then store the resulting FPSR bits. 13326 # then store the resulting FPSR bits. # 13327 # For denorms, force the j-bit to a on 13327 # For denorms, force the j-bit to a one and do the same as for # 13328 # norms. Denorms are so low that the answer 13328 # norms. Denorms are so low that the answer will either be a zero or a # 13329 # one. 13329 # one. # 13330 # For zeroes/infs/NANs, return the sam 13330 # For zeroes/infs/NANs, return the same while setting the FPSR # 13331 # as appropriate. 13331 # as appropriate. # 13332 # 13332 # # 13333 ############################################ 13333 ######################################################################### 13334 13334 13335 global fintrz 13335 global fintrz 13336 fintrz: 13336 fintrz: 13337 mov.b STAG(%a6),%d1 13337 mov.b STAG(%a6),%d1 13338 bne.b fintrz_not_norm 13338 bne.b fintrz_not_norm # optimize on non-norm input 13339 13339 13340 # 13340 # 13341 # Norm: 13341 # Norm: 13342 # 13342 # 13343 fintrz_norm: 13343 fintrz_norm: 13344 fmov.l &0x0,%fpsr 13344 fmov.l &0x0,%fpsr # clear FPSR 13345 13345 13346 fintrz.x SRC(%a0),%fp0 13346 fintrz.x SRC(%a0),%fp0 # execute fintrz 13347 13347 13348 fmov.l %fpsr,%d0 13348 fmov.l %fpsr,%d0 # save FPSR 13349 or.l %d0,USER_FPSR(%a6) 13349 or.l %d0,USER_FPSR(%a6) # set exception bits 13350 13350 13351 rts 13351 rts 13352 13352 13353 # 13353 # 13354 # input is not normalized; what is it? 13354 # input is not normalized; what is it? 13355 # 13355 # 13356 fintrz_not_norm: 13356 fintrz_not_norm: 13357 cmpi.b %d1,&ZERO 13357 cmpi.b %d1,&ZERO # weed out ZERO 13358 beq.b fintrz_zero 13358 beq.b fintrz_zero 13359 cmpi.b %d1,&INF 13359 cmpi.b %d1,&INF # weed out INF 13360 beq.b fintrz_inf 13360 beq.b fintrz_inf 13361 cmpi.b %d1,&DENORM 13361 cmpi.b %d1,&DENORM # weed out DENORM 13362 beq.b fintrz_denorm 13362 beq.b fintrz_denorm 13363 cmpi.b %d1,&SNAN 13363 cmpi.b %d1,&SNAN # weed out SNAN 13364 beq.l res_snan_1op 13364 beq.l res_snan_1op 13365 bra.l res_qnan_1op 13365 bra.l res_qnan_1op # weed out QNAN 13366 13366 13367 # 13367 # 13368 # Denorm: 13368 # Denorm: 13369 # 13369 # 13370 # for DENORMs, the result will be (+/-)ZERO. 13370 # for DENORMs, the result will be (+/-)ZERO. 13371 # also, the INEX2 and AINEX exception bits w 13371 # also, the INEX2 and AINEX exception bits will be set. 13372 # so, we could either set these manually or 13372 # so, we could either set these manually or force the DENORM 13373 # to a very small NORM and ship it to the NO 13373 # to a very small NORM and ship it to the NORM routine. 13374 # I do the latter. 13374 # I do the latter. 13375 # 13375 # 13376 fintrz_denorm: 13376 fintrz_denorm: 13377 mov.w SRC_EX(%a0),FP_SCR0_ 13377 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) # copy sign, zero exp 13378 mov.b &0x80,FP_SCR0_HI(%a6 13378 mov.b &0x80,FP_SCR0_HI(%a6) # force DENORM ==> small NORM 13379 lea FP_SCR0(%a6),%a0 13379 lea FP_SCR0(%a6),%a0 13380 bra.b fintrz_norm 13380 bra.b fintrz_norm 13381 13381 13382 # 13382 # 13383 # Zero: 13383 # Zero: 13384 # 13384 # 13385 fintrz_zero: 13385 fintrz_zero: 13386 tst.b SRC_EX(%a0) 13386 tst.b SRC_EX(%a0) # is ZERO negative? 13387 bmi.b fintrz_zero_m 13387 bmi.b fintrz_zero_m # yes 13388 fintrz_zero_p: 13388 fintrz_zero_p: 13389 fmov.s &0x00000000,%fp0 13389 fmov.s &0x00000000,%fp0 # return +ZERO in fp0 13390 mov.b &z_bmask,FPSR_CC(%a6 13390 mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 13391 rts 13391 rts 13392 fintrz_zero_m: 13392 fintrz_zero_m: 13393 fmov.s &0x80000000,%fp0 13393 fmov.s &0x80000000,%fp0 # return -ZERO in fp0 13394 mov.b &z_bmask+neg_bmask,F 13394 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits 13395 rts 13395 rts 13396 13396 13397 # 13397 # 13398 # Infinity: 13398 # Infinity: 13399 # 13399 # 13400 fintrz_inf: 13400 fintrz_inf: 13401 fmovm.x SRC(%a0),&0x80 13401 fmovm.x SRC(%a0),&0x80 # return result in fp0 13402 tst.b SRC_EX(%a0) 13402 tst.b SRC_EX(%a0) # is INF negative? 13403 bmi.b fintrz_inf_m 13403 bmi.b fintrz_inf_m # yes 13404 fintrz_inf_p: 13404 fintrz_inf_p: 13405 mov.b &inf_bmask,FPSR_CC(% 13405 mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit 13406 rts 13406 rts 13407 fintrz_inf_m: 13407 fintrz_inf_m: 13408 mov.b &inf_bmask+neg_bmask 13408 mov.b &inf_bmask+neg_bmask,FPSR_CC(%a6) # set 'N','I' ccode bits 13409 rts 13409 rts 13410 13410 13411 ############################################ 13411 ######################################################################### 13412 # XDEF ************************************* 13412 # XDEF **************************************************************** # 13413 # fabs(): emulates the fabs instructi 13413 # fabs(): emulates the fabs instruction # 13414 # fsabs(): emulates the fsabs instruct 13414 # fsabs(): emulates the fsabs instruction # 13415 # fdabs(): emulates the fdabs instruct 13415 # fdabs(): emulates the fdabs instruction # 13416 # 13416 # # 13417 # XREF ************************************* 13417 # XREF **************************************************************** # 13418 # norm() - normalize denorm mantissa t 13418 # norm() - normalize denorm mantissa to provide EXOP # 13419 # scale_to_zero_src() - make exponent. 13419 # scale_to_zero_src() - make exponent. = 0; get scale factor # 13420 # unf_res() - calculate underflow resu 13420 # unf_res() - calculate underflow result # 13421 # ovf_res() - calculate overflow resul 13421 # ovf_res() - calculate overflow result # 13422 # res_{s,q}nan_1op() - set NAN result 13422 # res_{s,q}nan_1op() - set NAN result for monadic operation # 13423 # 13423 # # 13424 # INPUT ************************************ 13424 # INPUT *************************************************************** # 13425 # a0 = pointer to extended precision s 13425 # a0 = pointer to extended precision source operand # 13426 # d0 = rnd precision/mode 13426 # d0 = rnd precision/mode # 13427 # 13427 # # 13428 # OUTPUT *********************************** 13428 # OUTPUT ************************************************************** # 13429 # fp0 = result 13429 # fp0 = result # 13430 # fp1 = EXOP (if exception occurred) 13430 # fp1 = EXOP (if exception occurred) # 13431 # 13431 # # 13432 # ALGORITHM ******************************** 13432 # ALGORITHM *********************************************************** # 13433 # Handle NANs, infinities, and zeroes 13433 # Handle NANs, infinities, and zeroes as special cases. Divide # 13434 # norms into extended, single, and double pr 13434 # norms into extended, single, and double precision. # 13435 # Simply clear sign for extended preci 13435 # Simply clear sign for extended precision norm. Ext prec denorm # 13436 # gets an EXOP created for it since it's an 13436 # gets an EXOP created for it since it's an underflow. # 13437 # Double and single precision can over 13437 # Double and single precision can overflow and underflow. First, # 13438 # scale the operand such that the exponent i 13438 # scale the operand such that the exponent is zero. Perform an "fabs" # 13439 # using the correct rnd mode/prec. Check to 13439 # using the correct rnd mode/prec. Check to see if the original # 13440 # exponent would take an exception. If so, u 13440 # exponent would take an exception. If so, use unf_res() or ovf_res() # 13441 # to calculate the default result. Also, cre 13441 # to calculate the default result. Also, create the EXOP for the # 13442 # exceptional case. If no exception should o 13442 # exceptional case. If no exception should occur, insert the correct # 13443 # result exponent and return. 13443 # result exponent and return. # 13444 # Unnorms don't pass through here. 13444 # Unnorms don't pass through here. # 13445 # 13445 # # 13446 ############################################ 13446 ######################################################################### 13447 13447 13448 global fsabs 13448 global fsabs 13449 fsabs: 13449 fsabs: 13450 andi.b &0x30,%d0 13450 andi.b &0x30,%d0 # clear rnd prec 13451 ori.b &s_mode*0x10,%d0 13451 ori.b &s_mode*0x10,%d0 # insert sgl precision 13452 bra.b fabs 13452 bra.b fabs 13453 13453 13454 global fdabs 13454 global fdabs 13455 fdabs: 13455 fdabs: 13456 andi.b &0x30,%d0 13456 andi.b &0x30,%d0 # clear rnd prec 13457 ori.b &d_mode*0x10,%d0 13457 ori.b &d_mode*0x10,%d0 # insert dbl precision 13458 13458 13459 global fabs 13459 global fabs 13460 fabs: 13460 fabs: 13461 mov.l %d0,L_SCR3(%a6) 13461 mov.l %d0,L_SCR3(%a6) # store rnd info 13462 mov.b STAG(%a6),%d1 13462 mov.b STAG(%a6),%d1 13463 bne.w fabs_not_norm 13463 bne.w fabs_not_norm # optimize on non-norm input 13464 13464 13465 # 13465 # 13466 # ABSOLUTE VALUE: norms and denorms ONLY! 13466 # ABSOLUTE VALUE: norms and denorms ONLY! 13467 # 13467 # 13468 fabs_norm: 13468 fabs_norm: 13469 andi.b &0xc0,%d0 13469 andi.b &0xc0,%d0 # is precision extended? 13470 bne.b fabs_not_ext 13470 bne.b fabs_not_ext # no; go handle sgl or dbl 13471 13471 13472 # 13472 # 13473 # precision selected is extended. so...we ca 13473 # precision selected is extended. so...we can not get an underflow 13474 # or overflow because of rounding to the cor 13474 # or overflow because of rounding to the correct precision. so... 13475 # skip the scaling and unscaling... 13475 # skip the scaling and unscaling... 13476 # 13476 # 13477 mov.l SRC_HI(%a0),FP_SCR0_ 13477 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 13478 mov.l SRC_LO(%a0),FP_SCR0_ 13478 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 13479 mov.w SRC_EX(%a0),%d1 13479 mov.w SRC_EX(%a0),%d1 13480 bclr &15,%d1 13480 bclr &15,%d1 # force absolute value 13481 mov.w %d1,FP_SCR0_EX(%a6) 13481 mov.w %d1,FP_SCR0_EX(%a6) # insert exponent 13482 fmovm.x FP_SCR0(%a6),&0x80 13482 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 13483 rts 13483 rts 13484 13484 13485 # 13485 # 13486 # for an extended precision DENORM, the UNFL 13486 # for an extended precision DENORM, the UNFL exception bit is set 13487 # the accrued bit is NOT set in this instanc 13487 # the accrued bit is NOT set in this instance(no inexactness!) 13488 # 13488 # 13489 fabs_denorm: 13489 fabs_denorm: 13490 andi.b &0xc0,%d0 13490 andi.b &0xc0,%d0 # is precision extended? 13491 bne.b fabs_not_ext 13491 bne.b fabs_not_ext # no 13492 13492 13493 bset &unfl_bit,FPSR_EXCEP 13493 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 13494 13494 13495 mov.l SRC_HI(%a0),FP_SCR0_ 13495 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 13496 mov.l SRC_LO(%a0),FP_SCR0_ 13496 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 13497 mov.w SRC_EX(%a0),%d0 13497 mov.w SRC_EX(%a0),%d0 13498 bclr &15,%d0 13498 bclr &15,%d0 # clear sign 13499 mov.w %d0,FP_SCR0_EX(%a6) 13499 mov.w %d0,FP_SCR0_EX(%a6) # insert exponent 13500 13500 13501 fmovm.x FP_SCR0(%a6),&0x80 13501 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 13502 13502 13503 btst &unfl_bit,FPCR_ENABL 13503 btst &unfl_bit,FPCR_ENABLE(%a6) # is UNFL enabled? 13504 bne.b fabs_ext_unfl_ena 13504 bne.b fabs_ext_unfl_ena 13505 rts 13505 rts 13506 13506 13507 # 13507 # 13508 # the input is an extended DENORM and underf 13508 # the input is an extended DENORM and underflow is enabled in the FPCR. 13509 # normalize the mantissa and add the bias of 13509 # normalize the mantissa and add the bias of 0x6000 to the resulting negative 13510 # exponent and insert back into the operand. 13510 # exponent and insert back into the operand. 13511 # 13511 # 13512 fabs_ext_unfl_ena: 13512 fabs_ext_unfl_ena: 13513 lea FP_SCR0(%a6),%a0 13513 lea FP_SCR0(%a6),%a0 # pass: ptr to operand 13514 bsr.l norm 13514 bsr.l norm # normalize result 13515 neg.w %d0 13515 neg.w %d0 # new exponent = -(shft val) 13516 addi.w &0x6000,%d0 13516 addi.w &0x6000,%d0 # add new bias to exponent 13517 mov.w FP_SCR0_EX(%a6),%d1 13517 mov.w FP_SCR0_EX(%a6),%d1 # fetch old sign,exp 13518 andi.w &0x8000,%d1 13518 andi.w &0x8000,%d1 # keep old sign 13519 andi.w &0x7fff,%d0 13519 andi.w &0x7fff,%d0 # clear sign position 13520 or.w %d1,%d0 13520 or.w %d1,%d0 # concat old sign, new exponent 13521 mov.w %d0,FP_SCR0_EX(%a6) 13521 mov.w %d0,FP_SCR0_EX(%a6) # insert new exponent 13522 fmovm.x FP_SCR0(%a6),&0x40 13522 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 13523 rts 13523 rts 13524 13524 13525 # 13525 # 13526 # operand is either single or double 13526 # operand is either single or double 13527 # 13527 # 13528 fabs_not_ext: 13528 fabs_not_ext: 13529 cmpi.b %d0,&s_mode*0x10 13529 cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec 13530 bne.b fabs_dbl 13530 bne.b fabs_dbl 13531 13531 13532 # 13532 # 13533 # operand is to be rounded to single precisi 13533 # operand is to be rounded to single precision 13534 # 13534 # 13535 fabs_sgl: 13535 fabs_sgl: 13536 mov.w SRC_EX(%a0),FP_SCR0_ 13536 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 13537 mov.l SRC_HI(%a0),FP_SCR0_ 13537 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 13538 mov.l SRC_LO(%a0),FP_SCR0_ 13538 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 13539 bsr.l scale_to_zero_src 13539 bsr.l scale_to_zero_src # calculate scale factor 13540 13540 13541 cmpi.l %d0,&0x3fff-0x3f80 13541 cmpi.l %d0,&0x3fff-0x3f80 # will move in underflow? 13542 bge.w fabs_sd_unfl 13542 bge.w fabs_sd_unfl # yes; go handle underflow 13543 cmpi.l %d0,&0x3fff-0x407e 13543 cmpi.l %d0,&0x3fff-0x407e # will move in overflow? 13544 beq.w fabs_sd_may_ovfl 13544 beq.w fabs_sd_may_ovfl # maybe; go check 13545 blt.w fabs_sd_ovfl 13545 blt.w fabs_sd_ovfl # yes; go handle overflow 13546 13546 13547 # 13547 # 13548 # operand will NOT overflow or underflow whe 13548 # operand will NOT overflow or underflow when moved in to the fp reg file 13549 # 13549 # 13550 fabs_sd_normal: 13550 fabs_sd_normal: 13551 fmov.l &0x0,%fpsr 13551 fmov.l &0x0,%fpsr # clear FPSR 13552 fmov.l L_SCR3(%a6),%fpcr 13552 fmov.l L_SCR3(%a6),%fpcr # set FPCR 13553 13553 13554 fabs.x FP_SCR0(%a6),%fp0 13554 fabs.x FP_SCR0(%a6),%fp0 # perform absolute 13555 13555 13556 fmov.l %fpsr,%d1 13556 fmov.l %fpsr,%d1 # save FPSR 13557 fmov.l &0x0,%fpcr 13557 fmov.l &0x0,%fpcr # clear FPCR 13558 13558 13559 or.l %d1,USER_FPSR(%a6) 13559 or.l %d1,USER_FPSR(%a6) # save INEX2,N 13560 13560 13561 fabs_sd_normal_exit: 13561 fabs_sd_normal_exit: 13562 mov.l %d2,-(%sp) 13562 mov.l %d2,-(%sp) # save d2 13563 fmovm.x &0x80,FP_SCR0(%a6) 13563 fmovm.x &0x80,FP_SCR0(%a6) # store out result 13564 mov.w FP_SCR0_EX(%a6),%d1 13564 mov.w FP_SCR0_EX(%a6),%d1 # load sgn,exp 13565 mov.l %d1,%d2 13565 mov.l %d1,%d2 # make a copy 13566 andi.l &0x7fff,%d1 13566 andi.l &0x7fff,%d1 # strip sign 13567 sub.l %d0,%d1 13567 sub.l %d0,%d1 # add scale factor 13568 andi.w &0x8000,%d2 13568 andi.w &0x8000,%d2 # keep old sign 13569 or.w %d1,%d2 13569 or.w %d1,%d2 # concat old sign,new exp 13570 mov.w %d2,FP_SCR0_EX(%a6) 13570 mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent 13571 mov.l (%sp)+,%d2 13571 mov.l (%sp)+,%d2 # restore d2 13572 fmovm.x FP_SCR0(%a6),&0x80 13572 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 13573 rts 13573 rts 13574 13574 13575 # 13575 # 13576 # operand is to be rounded to double precisi 13576 # operand is to be rounded to double precision 13577 # 13577 # 13578 fabs_dbl: 13578 fabs_dbl: 13579 mov.w SRC_EX(%a0),FP_SCR0_ 13579 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 13580 mov.l SRC_HI(%a0),FP_SCR0_ 13580 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 13581 mov.l SRC_LO(%a0),FP_SCR0_ 13581 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 13582 bsr.l scale_to_zero_src 13582 bsr.l scale_to_zero_src # calculate scale factor 13583 13583 13584 cmpi.l %d0,&0x3fff-0x3c00 13584 cmpi.l %d0,&0x3fff-0x3c00 # will move in underflow? 13585 bge.b fabs_sd_unfl 13585 bge.b fabs_sd_unfl # yes; go handle underflow 13586 cmpi.l %d0,&0x3fff-0x43fe 13586 cmpi.l %d0,&0x3fff-0x43fe # will move in overflow? 13587 beq.w fabs_sd_may_ovfl 13587 beq.w fabs_sd_may_ovfl # maybe; go check 13588 blt.w fabs_sd_ovfl 13588 blt.w fabs_sd_ovfl # yes; go handle overflow 13589 bra.w fabs_sd_normal 13589 bra.w fabs_sd_normal # no; ho handle normalized op 13590 13590 13591 # 13591 # 13592 # operand WILL underflow when moved in to th 13592 # operand WILL underflow when moved in to the fp register file 13593 # 13593 # 13594 fabs_sd_unfl: 13594 fabs_sd_unfl: 13595 bset &unfl_bit,FPSR_EXCEP 13595 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 13596 13596 13597 bclr &0x7,FP_SCR0_EX(%a6) 13597 bclr &0x7,FP_SCR0_EX(%a6) # force absolute value 13598 13598 13599 # if underflow or inexact is enabled, go cal 13599 # if underflow or inexact is enabled, go calculate EXOP first. 13600 mov.b FPCR_ENABLE(%a6),%d1 13600 mov.b FPCR_ENABLE(%a6),%d1 13601 andi.b &0x0b,%d1 13601 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 13602 bne.b fabs_sd_unfl_ena 13602 bne.b fabs_sd_unfl_ena # yes 13603 13603 13604 fabs_sd_unfl_dis: 13604 fabs_sd_unfl_dis: 13605 lea FP_SCR0(%a6),%a0 13605 lea FP_SCR0(%a6),%a0 # pass: result addr 13606 mov.l L_SCR3(%a6),%d1 13606 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 13607 bsr.l unf_res 13607 bsr.l unf_res # calculate default result 13608 or.b %d0,FPSR_CC(%a6) 13608 or.b %d0,FPSR_CC(%a6) # set possible 'Z' ccode 13609 fmovm.x FP_SCR0(%a6),&0x80 13609 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 13610 rts 13610 rts 13611 13611 13612 # 13612 # 13613 # operand will underflow AND underflow is en 13613 # operand will underflow AND underflow is enabled. 13614 # Therefore, we must return the result round 13614 # Therefore, we must return the result rounded to extended precision. 13615 # 13615 # 13616 fabs_sd_unfl_ena: 13616 fabs_sd_unfl_ena: 13617 mov.l FP_SCR0_HI(%a6),FP_S 13617 mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) 13618 mov.l FP_SCR0_LO(%a6),FP_S 13618 mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6) 13619 mov.w FP_SCR0_EX(%a6),%d1 13619 mov.w FP_SCR0_EX(%a6),%d1 # load current exponent 13620 13620 13621 mov.l %d2,-(%sp) 13621 mov.l %d2,-(%sp) # save d2 13622 mov.l %d1,%d2 13622 mov.l %d1,%d2 # make a copy 13623 andi.l &0x7fff,%d1 13623 andi.l &0x7fff,%d1 # strip sign 13624 andi.w &0x8000,%d2 13624 andi.w &0x8000,%d2 # keep old sign 13625 sub.l %d0,%d1 13625 sub.l %d0,%d1 # subtract scale factor 13626 addi.l &0x6000,%d1 13626 addi.l &0x6000,%d1 # add new bias 13627 andi.w &0x7fff,%d1 13627 andi.w &0x7fff,%d1 13628 or.w %d2,%d1 13628 or.w %d2,%d1 # concat new sign,new exp 13629 mov.w %d1,FP_SCR1_EX(%a6) 13629 mov.w %d1,FP_SCR1_EX(%a6) # insert new exp 13630 fmovm.x FP_SCR1(%a6),&0x40 13630 fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1 13631 mov.l (%sp)+,%d2 13631 mov.l (%sp)+,%d2 # restore d2 13632 bra.b fabs_sd_unfl_dis 13632 bra.b fabs_sd_unfl_dis 13633 13633 13634 # 13634 # 13635 # operand WILL overflow. 13635 # operand WILL overflow. 13636 # 13636 # 13637 fabs_sd_ovfl: 13637 fabs_sd_ovfl: 13638 fmov.l &0x0,%fpsr 13638 fmov.l &0x0,%fpsr # clear FPSR 13639 fmov.l L_SCR3(%a6),%fpcr 13639 fmov.l L_SCR3(%a6),%fpcr # set FPCR 13640 13640 13641 fabs.x FP_SCR0(%a6),%fp0 13641 fabs.x FP_SCR0(%a6),%fp0 # perform absolute 13642 13642 13643 fmov.l &0x0,%fpcr 13643 fmov.l &0x0,%fpcr # clear FPCR 13644 fmov.l %fpsr,%d1 13644 fmov.l %fpsr,%d1 # save FPSR 13645 13645 13646 or.l %d1,USER_FPSR(%a6) 13646 or.l %d1,USER_FPSR(%a6) # save INEX2,N 13647 13647 13648 fabs_sd_ovfl_tst: 13648 fabs_sd_ovfl_tst: 13649 or.l &ovfl_inx_mask,USER_ 13649 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 13650 13650 13651 mov.b FPCR_ENABLE(%a6),%d1 13651 mov.b FPCR_ENABLE(%a6),%d1 13652 andi.b &0x13,%d1 13652 andi.b &0x13,%d1 # is OVFL or INEX enabled? 13653 bne.b fabs_sd_ovfl_ena 13653 bne.b fabs_sd_ovfl_ena # yes 13654 13654 13655 # 13655 # 13656 # OVFL is not enabled; therefore, we must cr 13656 # OVFL is not enabled; therefore, we must create the default result by 13657 # calling ovf_res(). 13657 # calling ovf_res(). 13658 # 13658 # 13659 fabs_sd_ovfl_dis: 13659 fabs_sd_ovfl_dis: 13660 btst &neg_bit,FPSR_CC(%a6 13660 btst &neg_bit,FPSR_CC(%a6) # is result negative? 13661 sne %d1 13661 sne %d1 # set sign param accordingly 13662 mov.l L_SCR3(%a6),%d0 13662 mov.l L_SCR3(%a6),%d0 # pass: prec,mode 13663 bsr.l ovf_res 13663 bsr.l ovf_res # calculate default result 13664 or.b %d0,FPSR_CC(%a6) 13664 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 13665 fmovm.x (%a0),&0x80 13665 fmovm.x (%a0),&0x80 # return default result in fp0 13666 rts 13666 rts 13667 13667 13668 # 13668 # 13669 # OVFL is enabled. 13669 # OVFL is enabled. 13670 # the INEX2 bit has already been updated by 13670 # the INEX2 bit has already been updated by the round to the correct precision. 13671 # now, round to extended(and don't alter the 13671 # now, round to extended(and don't alter the FPSR). 13672 # 13672 # 13673 fabs_sd_ovfl_ena: 13673 fabs_sd_ovfl_ena: 13674 mov.l %d2,-(%sp) 13674 mov.l %d2,-(%sp) # save d2 13675 mov.w FP_SCR0_EX(%a6),%d1 13675 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 13676 mov.l %d1,%d2 13676 mov.l %d1,%d2 # make a copy 13677 andi.l &0x7fff,%d1 13677 andi.l &0x7fff,%d1 # strip sign 13678 andi.w &0x8000,%d2 13678 andi.w &0x8000,%d2 # keep old sign 13679 sub.l %d0,%d1 13679 sub.l %d0,%d1 # add scale factor 13680 subi.l &0x6000,%d1 13680 subi.l &0x6000,%d1 # subtract bias 13681 andi.w &0x7fff,%d1 13681 andi.w &0x7fff,%d1 13682 or.w %d2,%d1 13682 or.w %d2,%d1 # concat sign,exp 13683 mov.w %d1,FP_SCR0_EX(%a6) 13683 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 13684 fmovm.x FP_SCR0(%a6),&0x40 13684 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 13685 mov.l (%sp)+,%d2 13685 mov.l (%sp)+,%d2 # restore d2 13686 bra.b fabs_sd_ovfl_dis 13686 bra.b fabs_sd_ovfl_dis 13687 13687 13688 # 13688 # 13689 # the move in MAY underflow. so... 13689 # the move in MAY underflow. so... 13690 # 13690 # 13691 fabs_sd_may_ovfl: 13691 fabs_sd_may_ovfl: 13692 fmov.l &0x0,%fpsr 13692 fmov.l &0x0,%fpsr # clear FPSR 13693 fmov.l L_SCR3(%a6),%fpcr 13693 fmov.l L_SCR3(%a6),%fpcr # set FPCR 13694 13694 13695 fabs.x FP_SCR0(%a6),%fp0 13695 fabs.x FP_SCR0(%a6),%fp0 # perform absolute 13696 13696 13697 fmov.l %fpsr,%d1 13697 fmov.l %fpsr,%d1 # save status 13698 fmov.l &0x0,%fpcr 13698 fmov.l &0x0,%fpcr # clear FPCR 13699 13699 13700 or.l %d1,USER_FPSR(%a6) 13700 or.l %d1,USER_FPSR(%a6) # save INEX2,N 13701 13701 13702 fabs.x %fp0,%fp1 13702 fabs.x %fp0,%fp1 # make a copy of result 13703 fcmp.b %fp1,&0x2 13703 fcmp.b %fp1,&0x2 # is |result| >= 2.b? 13704 fbge.w fabs_sd_ovfl_tst 13704 fbge.w fabs_sd_ovfl_tst # yes; overflow has occurred 13705 13705 13706 # no, it didn't overflow; we have correct re 13706 # no, it didn't overflow; we have correct result 13707 bra.w fabs_sd_normal_exit 13707 bra.w fabs_sd_normal_exit 13708 13708 13709 ############################################ 13709 ########################################################################## 13710 13710 13711 # 13711 # 13712 # input is not normalized; what is it? 13712 # input is not normalized; what is it? 13713 # 13713 # 13714 fabs_not_norm: 13714 fabs_not_norm: 13715 cmpi.b %d1,&DENORM 13715 cmpi.b %d1,&DENORM # weed out DENORM 13716 beq.w fabs_denorm 13716 beq.w fabs_denorm 13717 cmpi.b %d1,&SNAN 13717 cmpi.b %d1,&SNAN # weed out SNAN 13718 beq.l res_snan_1op 13718 beq.l res_snan_1op 13719 cmpi.b %d1,&QNAN 13719 cmpi.b %d1,&QNAN # weed out QNAN 13720 beq.l res_qnan_1op 13720 beq.l res_qnan_1op 13721 13721 13722 fabs.x SRC(%a0),%fp0 13722 fabs.x SRC(%a0),%fp0 # force absolute value 13723 13723 13724 cmpi.b %d1,&INF 13724 cmpi.b %d1,&INF # weed out INF 13725 beq.b fabs_inf 13725 beq.b fabs_inf 13726 fabs_zero: 13726 fabs_zero: 13727 mov.b &z_bmask,FPSR_CC(%a6 13727 mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 13728 rts 13728 rts 13729 fabs_inf: 13729 fabs_inf: 13730 mov.b &inf_bmask,FPSR_CC(% 13730 mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit 13731 rts 13731 rts 13732 13732 13733 ############################################ 13733 ######################################################################### 13734 # XDEF ************************************* 13734 # XDEF **************************************************************** # 13735 # fcmp(): fp compare op routine 13735 # fcmp(): fp compare op routine # 13736 # 13736 # # 13737 # XREF ************************************* 13737 # XREF **************************************************************** # 13738 # res_qnan() - return QNAN result 13738 # res_qnan() - return QNAN result # 13739 # res_snan() - return SNAN result 13739 # res_snan() - return SNAN result # 13740 # 13740 # # 13741 # INPUT ************************************ 13741 # INPUT *************************************************************** # 13742 # a0 = pointer to extended precision s 13742 # a0 = pointer to extended precision source operand # 13743 # a1 = pointer to extended precision d 13743 # a1 = pointer to extended precision destination operand # 13744 # d0 = round prec/mode 13744 # d0 = round prec/mode # 13745 # 13745 # # 13746 # OUTPUT *********************************** 13746 # OUTPUT ************************************************************** # 13747 # None 13747 # None # 13748 # 13748 # # 13749 # ALGORITHM ******************************** 13749 # ALGORITHM *********************************************************** # 13750 # Handle NANs and denorms as special c 13750 # Handle NANs and denorms as special cases. For everything else, # 13751 # just use the actual fcmp instruction to pr 13751 # just use the actual fcmp instruction to produce the correct condition # 13752 # codes. 13752 # codes. # 13753 # 13753 # # 13754 ############################################ 13754 ######################################################################### 13755 13755 13756 global fcmp 13756 global fcmp 13757 fcmp: 13757 fcmp: 13758 clr.w %d1 13758 clr.w %d1 13759 mov.b DTAG(%a6),%d1 13759 mov.b DTAG(%a6),%d1 13760 lsl.b &0x3,%d1 13760 lsl.b &0x3,%d1 13761 or.b STAG(%a6),%d1 13761 or.b STAG(%a6),%d1 13762 bne.b fcmp_not_norm 13762 bne.b fcmp_not_norm # optimize on non-norm input 13763 13763 13764 # 13764 # 13765 # COMPARE FP OPs : NORMs, ZEROs, INFs, and " 13765 # COMPARE FP OPs : NORMs, ZEROs, INFs, and "corrected" DENORMs 13766 # 13766 # 13767 fcmp_norm: 13767 fcmp_norm: 13768 fmovm.x DST(%a1),&0x80 13768 fmovm.x DST(%a1),&0x80 # load dst op 13769 13769 13770 fcmp.x %fp0,SRC(%a0) 13770 fcmp.x %fp0,SRC(%a0) # do compare 13771 13771 13772 fmov.l %fpsr,%d0 13772 fmov.l %fpsr,%d0 # save FPSR 13773 rol.l &0x8,%d0 13773 rol.l &0x8,%d0 # extract ccode bits 13774 mov.b %d0,FPSR_CC(%a6) 13774 mov.b %d0,FPSR_CC(%a6) # set ccode bits(no exc bits are set) 13775 13775 13776 rts 13776 rts 13777 13777 13778 # 13778 # 13779 # fcmp: inputs are not both normalized; what 13779 # fcmp: inputs are not both normalized; what are they? 13780 # 13780 # 13781 fcmp_not_norm: 13781 fcmp_not_norm: 13782 mov.w (tbl_fcmp_op.b,%pc,% 13782 mov.w (tbl_fcmp_op.b,%pc,%d1.w*2),%d1 13783 jmp (tbl_fcmp_op.b,%pc,% 13783 jmp (tbl_fcmp_op.b,%pc,%d1.w*1) 13784 13784 13785 swbeg &48 13785 swbeg &48 13786 tbl_fcmp_op: 13786 tbl_fcmp_op: 13787 short fcmp_norm - tb 13787 short fcmp_norm - tbl_fcmp_op # NORM - NORM 13788 short fcmp_norm - tb 13788 short fcmp_norm - tbl_fcmp_op # NORM - ZERO 13789 short fcmp_norm - tb 13789 short fcmp_norm - tbl_fcmp_op # NORM - INF 13790 short fcmp_res_qnan - tb 13790 short fcmp_res_qnan - tbl_fcmp_op # NORM - QNAN 13791 short fcmp_nrm_dnrm - tb 13791 short fcmp_nrm_dnrm - tbl_fcmp_op # NORM - DENORM 13792 short fcmp_res_snan - tb 13792 short fcmp_res_snan - tbl_fcmp_op # NORM - SNAN 13793 short tbl_fcmp_op - tb 13793 short tbl_fcmp_op - tbl_fcmp_op # 13794 short tbl_fcmp_op - tb 13794 short tbl_fcmp_op - tbl_fcmp_op # 13795 13795 13796 short fcmp_norm - tb 13796 short fcmp_norm - tbl_fcmp_op # ZERO - NORM 13797 short fcmp_norm - tb 13797 short fcmp_norm - tbl_fcmp_op # ZERO - ZERO 13798 short fcmp_norm - tb 13798 short fcmp_norm - tbl_fcmp_op # ZERO - INF 13799 short fcmp_res_qnan - tb 13799 short fcmp_res_qnan - tbl_fcmp_op # ZERO - QNAN 13800 short fcmp_dnrm_s - tb 13800 short fcmp_dnrm_s - tbl_fcmp_op # ZERO - DENORM 13801 short fcmp_res_snan - tb 13801 short fcmp_res_snan - tbl_fcmp_op # ZERO - SNAN 13802 short tbl_fcmp_op - tb 13802 short tbl_fcmp_op - tbl_fcmp_op # 13803 short tbl_fcmp_op - tb 13803 short tbl_fcmp_op - tbl_fcmp_op # 13804 13804 13805 short fcmp_norm - tb 13805 short fcmp_norm - tbl_fcmp_op # INF - NORM 13806 short fcmp_norm - tb 13806 short fcmp_norm - tbl_fcmp_op # INF - ZERO 13807 short fcmp_norm - tb 13807 short fcmp_norm - tbl_fcmp_op # INF - INF 13808 short fcmp_res_qnan - tb 13808 short fcmp_res_qnan - tbl_fcmp_op # INF - QNAN 13809 short fcmp_dnrm_s - tb 13809 short fcmp_dnrm_s - tbl_fcmp_op # INF - DENORM 13810 short fcmp_res_snan - tb 13810 short fcmp_res_snan - tbl_fcmp_op # INF - SNAN 13811 short tbl_fcmp_op - tb 13811 short tbl_fcmp_op - tbl_fcmp_op # 13812 short tbl_fcmp_op - tb 13812 short tbl_fcmp_op - tbl_fcmp_op # 13813 13813 13814 short fcmp_res_qnan - tb 13814 short fcmp_res_qnan - tbl_fcmp_op # QNAN - NORM 13815 short fcmp_res_qnan - tb 13815 short fcmp_res_qnan - tbl_fcmp_op # QNAN - ZERO 13816 short fcmp_res_qnan - tb 13816 short fcmp_res_qnan - tbl_fcmp_op # QNAN - INF 13817 short fcmp_res_qnan - tb 13817 short fcmp_res_qnan - tbl_fcmp_op # QNAN - QNAN 13818 short fcmp_res_qnan - tb 13818 short fcmp_res_qnan - tbl_fcmp_op # QNAN - DENORM 13819 short fcmp_res_snan - tb 13819 short fcmp_res_snan - tbl_fcmp_op # QNAN - SNAN 13820 short tbl_fcmp_op - tb 13820 short tbl_fcmp_op - tbl_fcmp_op # 13821 short tbl_fcmp_op - tb 13821 short tbl_fcmp_op - tbl_fcmp_op # 13822 13822 13823 short fcmp_dnrm_nrm - tb 13823 short fcmp_dnrm_nrm - tbl_fcmp_op # DENORM - NORM 13824 short fcmp_dnrm_d - tb 13824 short fcmp_dnrm_d - tbl_fcmp_op # DENORM - ZERO 13825 short fcmp_dnrm_d - tb 13825 short fcmp_dnrm_d - tbl_fcmp_op # DENORM - INF 13826 short fcmp_res_qnan - tb 13826 short fcmp_res_qnan - tbl_fcmp_op # DENORM - QNAN 13827 short fcmp_dnrm_sd - tb 13827 short fcmp_dnrm_sd - tbl_fcmp_op # DENORM - DENORM 13828 short fcmp_res_snan - tb 13828 short fcmp_res_snan - tbl_fcmp_op # DENORM - SNAN 13829 short tbl_fcmp_op - tb 13829 short tbl_fcmp_op - tbl_fcmp_op # 13830 short tbl_fcmp_op - tb 13830 short tbl_fcmp_op - tbl_fcmp_op # 13831 13831 13832 short fcmp_res_snan - tb 13832 short fcmp_res_snan - tbl_fcmp_op # SNAN - NORM 13833 short fcmp_res_snan - tb 13833 short fcmp_res_snan - tbl_fcmp_op # SNAN - ZERO 13834 short fcmp_res_snan - tb 13834 short fcmp_res_snan - tbl_fcmp_op # SNAN - INF 13835 short fcmp_res_snan - tb 13835 short fcmp_res_snan - tbl_fcmp_op # SNAN - QNAN 13836 short fcmp_res_snan - tb 13836 short fcmp_res_snan - tbl_fcmp_op # SNAN - DENORM 13837 short fcmp_res_snan - tb 13837 short fcmp_res_snan - tbl_fcmp_op # SNAN - SNAN 13838 short tbl_fcmp_op - tb 13838 short tbl_fcmp_op - tbl_fcmp_op # 13839 short tbl_fcmp_op - tb 13839 short tbl_fcmp_op - tbl_fcmp_op # 13840 13840 13841 # unlike all other functions for QNAN and SN 13841 # unlike all other functions for QNAN and SNAN, fcmp does NOT set the 13842 # 'N' bit for a negative QNAN or SNAN input 13842 # 'N' bit for a negative QNAN or SNAN input so we must squelch it here. 13843 fcmp_res_qnan: 13843 fcmp_res_qnan: 13844 bsr.l res_qnan 13844 bsr.l res_qnan 13845 andi.b &0xf7,FPSR_CC(%a6) 13845 andi.b &0xf7,FPSR_CC(%a6) 13846 rts 13846 rts 13847 fcmp_res_snan: 13847 fcmp_res_snan: 13848 bsr.l res_snan 13848 bsr.l res_snan 13849 andi.b &0xf7,FPSR_CC(%a6) 13849 andi.b &0xf7,FPSR_CC(%a6) 13850 rts 13850 rts 13851 13851 13852 # 13852 # 13853 # DENORMs are a little more difficult. 13853 # DENORMs are a little more difficult. 13854 # If you have a 2 DENORMs, then you can just 13854 # If you have a 2 DENORMs, then you can just force the j-bit to a one 13855 # and use the fcmp_norm routine. 13855 # and use the fcmp_norm routine. 13856 # If you have a DENORM and an INF or ZERO, j 13856 # If you have a DENORM and an INF or ZERO, just force the DENORM's j-bit to a one 13857 # and use the fcmp_norm routine. 13857 # and use the fcmp_norm routine. 13858 # If you have a DENORM and a NORM with oppos 13858 # If you have a DENORM and a NORM with opposite signs, then use fcmp_norm, also. 13859 # But with a DENORM and a NORM of the same s 13859 # But with a DENORM and a NORM of the same sign, the neg bit is set if the 13860 # (1) signs are (+) and the DENORM is the ds 13860 # (1) signs are (+) and the DENORM is the dst or 13861 # (2) signs are (-) and the DENORM is the sr 13861 # (2) signs are (-) and the DENORM is the src 13862 # 13862 # 13863 13863 13864 fcmp_dnrm_s: 13864 fcmp_dnrm_s: 13865 mov.w SRC_EX(%a0),FP_SCR0_ 13865 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 13866 mov.l SRC_HI(%a0),%d0 13866 mov.l SRC_HI(%a0),%d0 13867 bset &31,%d0 13867 bset &31,%d0 # DENORM src; make into small norm 13868 mov.l %d0,FP_SCR0_HI(%a6) 13868 mov.l %d0,FP_SCR0_HI(%a6) 13869 mov.l SRC_LO(%a0),FP_SCR0_ 13869 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 13870 lea FP_SCR0(%a6),%a0 13870 lea FP_SCR0(%a6),%a0 13871 bra.w fcmp_norm 13871 bra.w fcmp_norm 13872 13872 13873 fcmp_dnrm_d: 13873 fcmp_dnrm_d: 13874 mov.l DST_EX(%a1),FP_SCR0_ 13874 mov.l DST_EX(%a1),FP_SCR0_EX(%a6) 13875 mov.l DST_HI(%a1),%d0 13875 mov.l DST_HI(%a1),%d0 13876 bset &31,%d0 13876 bset &31,%d0 # DENORM src; make into small norm 13877 mov.l %d0,FP_SCR0_HI(%a6) 13877 mov.l %d0,FP_SCR0_HI(%a6) 13878 mov.l DST_LO(%a1),FP_SCR0_ 13878 mov.l DST_LO(%a1),FP_SCR0_LO(%a6) 13879 lea FP_SCR0(%a6),%a1 13879 lea FP_SCR0(%a6),%a1 13880 bra.w fcmp_norm 13880 bra.w fcmp_norm 13881 13881 13882 fcmp_dnrm_sd: 13882 fcmp_dnrm_sd: 13883 mov.w DST_EX(%a1),FP_SCR1_ 13883 mov.w DST_EX(%a1),FP_SCR1_EX(%a6) 13884 mov.w SRC_EX(%a0),FP_SCR0_ 13884 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 13885 mov.l DST_HI(%a1),%d0 13885 mov.l DST_HI(%a1),%d0 13886 bset &31,%d0 13886 bset &31,%d0 # DENORM dst; make into small norm 13887 mov.l %d0,FP_SCR1_HI(%a6) 13887 mov.l %d0,FP_SCR1_HI(%a6) 13888 mov.l SRC_HI(%a0),%d0 13888 mov.l SRC_HI(%a0),%d0 13889 bset &31,%d0 13889 bset &31,%d0 # DENORM dst; make into small norm 13890 mov.l %d0,FP_SCR0_HI(%a6) 13890 mov.l %d0,FP_SCR0_HI(%a6) 13891 mov.l DST_LO(%a1),FP_SCR1_ 13891 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 13892 mov.l SRC_LO(%a0),FP_SCR0_ 13892 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 13893 lea FP_SCR1(%a6),%a1 13893 lea FP_SCR1(%a6),%a1 13894 lea FP_SCR0(%a6),%a0 13894 lea FP_SCR0(%a6),%a0 13895 bra.w fcmp_norm 13895 bra.w fcmp_norm 13896 13896 13897 fcmp_nrm_dnrm: 13897 fcmp_nrm_dnrm: 13898 mov.b SRC_EX(%a0),%d0 13898 mov.b SRC_EX(%a0),%d0 # determine if like signs 13899 mov.b DST_EX(%a1),%d1 13899 mov.b DST_EX(%a1),%d1 13900 eor.b %d0,%d1 13900 eor.b %d0,%d1 13901 bmi.w fcmp_dnrm_s 13901 bmi.w fcmp_dnrm_s 13902 13902 13903 # signs are the same, so must determine the 13903 # signs are the same, so must determine the answer ourselves. 13904 tst.b %d0 13904 tst.b %d0 # is src op negative? 13905 bmi.b fcmp_nrm_dnrm_m 13905 bmi.b fcmp_nrm_dnrm_m # yes 13906 rts 13906 rts 13907 fcmp_nrm_dnrm_m: 13907 fcmp_nrm_dnrm_m: 13908 mov.b &neg_bmask,FPSR_CC(% 13908 mov.b &neg_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 13909 rts 13909 rts 13910 13910 13911 fcmp_dnrm_nrm: 13911 fcmp_dnrm_nrm: 13912 mov.b SRC_EX(%a0),%d0 13912 mov.b SRC_EX(%a0),%d0 # determine if like signs 13913 mov.b DST_EX(%a1),%d1 13913 mov.b DST_EX(%a1),%d1 13914 eor.b %d0,%d1 13914 eor.b %d0,%d1 13915 bmi.w fcmp_dnrm_d 13915 bmi.w fcmp_dnrm_d 13916 13916 13917 # signs are the same, so must determine the 13917 # signs are the same, so must determine the answer ourselves. 13918 tst.b %d0 13918 tst.b %d0 # is src op negative? 13919 bpl.b fcmp_dnrm_nrm_m 13919 bpl.b fcmp_dnrm_nrm_m # no 13920 rts 13920 rts 13921 fcmp_dnrm_nrm_m: 13921 fcmp_dnrm_nrm_m: 13922 mov.b &neg_bmask,FPSR_CC(% 13922 mov.b &neg_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 13923 rts 13923 rts 13924 13924 13925 ############################################ 13925 ######################################################################### 13926 # XDEF ************************************* 13926 # XDEF **************************************************************** # 13927 # fsglmul(): emulates the fsglmul inst 13927 # fsglmul(): emulates the fsglmul instruction # 13928 # 13928 # # 13929 # XREF ************************************* 13929 # XREF **************************************************************** # 13930 # scale_to_zero_src() - scale src expo 13930 # scale_to_zero_src() - scale src exponent to zero # 13931 # scale_to_zero_dst() - scale dst expo 13931 # scale_to_zero_dst() - scale dst exponent to zero # 13932 # unf_res4() - return default underflo 13932 # unf_res4() - return default underflow result for sglop # 13933 # ovf_res() - return default overflow 13933 # ovf_res() - return default overflow result # 13934 # res_qnan() - return QNAN result 13934 # res_qnan() - return QNAN result # 13935 # res_snan() - return SNAN result 13935 # res_snan() - return SNAN result # 13936 # 13936 # # 13937 # INPUT ************************************ 13937 # INPUT *************************************************************** # 13938 # a0 = pointer to extended precision s 13938 # a0 = pointer to extended precision source operand # 13939 # a1 = pointer to extended precision d 13939 # a1 = pointer to extended precision destination operand # 13940 # d0 rnd prec,mode 13940 # d0 rnd prec,mode # 13941 # 13941 # # 13942 # OUTPUT *********************************** 13942 # OUTPUT ************************************************************** # 13943 # fp0 = result 13943 # fp0 = result # 13944 # fp1 = EXOP (if exception occurred) 13944 # fp1 = EXOP (if exception occurred) # 13945 # 13945 # # 13946 # ALGORITHM ******************************** 13946 # ALGORITHM *********************************************************** # 13947 # Handle NANs, infinities, and zeroes 13947 # Handle NANs, infinities, and zeroes as special cases. Divide # 13948 # norms/denorms into ext/sgl/dbl precision. 13948 # norms/denorms into ext/sgl/dbl precision. # 13949 # For norms/denorms, scale the exponen 13949 # For norms/denorms, scale the exponents such that a multiply # 13950 # instruction won't cause an exception. Use 13950 # instruction won't cause an exception. Use the regular fsglmul to # 13951 # compute a result. Check if the regular ope 13951 # compute a result. Check if the regular operands would have taken # 13952 # an exception. If so, return the default ov 13952 # an exception. If so, return the default overflow/underflow result # 13953 # and return the EXOP if exceptions are enab 13953 # and return the EXOP if exceptions are enabled. Else, scale the # 13954 # result operand to the proper exponent. 13954 # result operand to the proper exponent. # 13955 # 13955 # # 13956 ############################################ 13956 ######################################################################### 13957 13957 13958 global fsglmul 13958 global fsglmul 13959 fsglmul: 13959 fsglmul: 13960 mov.l %d0,L_SCR3(%a6) 13960 mov.l %d0,L_SCR3(%a6) # store rnd info 13961 13961 13962 clr.w %d1 13962 clr.w %d1 13963 mov.b DTAG(%a6),%d1 13963 mov.b DTAG(%a6),%d1 13964 lsl.b &0x3,%d1 13964 lsl.b &0x3,%d1 13965 or.b STAG(%a6),%d1 13965 or.b STAG(%a6),%d1 13966 13966 13967 bne.w fsglmul_not_norm 13967 bne.w fsglmul_not_norm # optimize on non-norm input 13968 13968 13969 fsglmul_norm: 13969 fsglmul_norm: 13970 mov.w DST_EX(%a1),FP_SCR1_ 13970 mov.w DST_EX(%a1),FP_SCR1_EX(%a6) 13971 mov.l DST_HI(%a1),FP_SCR1_ 13971 mov.l DST_HI(%a1),FP_SCR1_HI(%a6) 13972 mov.l DST_LO(%a1),FP_SCR1_ 13972 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 13973 13973 13974 mov.w SRC_EX(%a0),FP_SCR0_ 13974 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 13975 mov.l SRC_HI(%a0),FP_SCR0_ 13975 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 13976 mov.l SRC_LO(%a0),FP_SCR0_ 13976 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 13977 13977 13978 bsr.l scale_to_zero_src 13978 bsr.l scale_to_zero_src # scale exponent 13979 mov.l %d0,-(%sp) 13979 mov.l %d0,-(%sp) # save scale factor 1 13980 13980 13981 bsr.l scale_to_zero_dst 13981 bsr.l scale_to_zero_dst # scale dst exponent 13982 13982 13983 add.l (%sp)+,%d0 13983 add.l (%sp)+,%d0 # SCALE_FACTOR = scale1 + scale2 13984 13984 13985 cmpi.l %d0,&0x3fff-0x7ffe 13985 cmpi.l %d0,&0x3fff-0x7ffe # would result ovfl? 13986 beq.w fsglmul_may_ovfl 13986 beq.w fsglmul_may_ovfl # result may rnd to overflow 13987 blt.w fsglmul_ovfl 13987 blt.w fsglmul_ovfl # result will overflow 13988 13988 13989 cmpi.l %d0,&0x3fff+0x0001 13989 cmpi.l %d0,&0x3fff+0x0001 # would result unfl? 13990 beq.w fsglmul_may_unfl 13990 beq.w fsglmul_may_unfl # result may rnd to no unfl 13991 bgt.w fsglmul_unfl 13991 bgt.w fsglmul_unfl # result will underflow 13992 13992 13993 fsglmul_normal: 13993 fsglmul_normal: 13994 fmovm.x FP_SCR1(%a6),&0x80 13994 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 13995 13995 13996 fmov.l L_SCR3(%a6),%fpcr 13996 fmov.l L_SCR3(%a6),%fpcr # set FPCR 13997 fmov.l &0x0,%fpsr 13997 fmov.l &0x0,%fpsr # clear FPSR 13998 13998 13999 fsglmul.x FP_SCR0(%a6),%fp0 13999 fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply 14000 14000 14001 fmov.l %fpsr,%d1 14001 fmov.l %fpsr,%d1 # save status 14002 fmov.l &0x0,%fpcr 14002 fmov.l &0x0,%fpcr # clear FPCR 14003 14003 14004 or.l %d1,USER_FPSR(%a6) 14004 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14005 14005 14006 fsglmul_normal_exit: 14006 fsglmul_normal_exit: 14007 fmovm.x &0x80,FP_SCR0(%a6) 14007 fmovm.x &0x80,FP_SCR0(%a6) # store out result 14008 mov.l %d2,-(%sp) 14008 mov.l %d2,-(%sp) # save d2 14009 mov.w FP_SCR0_EX(%a6),%d1 14009 mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp} 14010 mov.l %d1,%d2 14010 mov.l %d1,%d2 # make a copy 14011 andi.l &0x7fff,%d1 14011 andi.l &0x7fff,%d1 # strip sign 14012 andi.w &0x8000,%d2 14012 andi.w &0x8000,%d2 # keep old sign 14013 sub.l %d0,%d1 14013 sub.l %d0,%d1 # add scale factor 14014 or.w %d2,%d1 14014 or.w %d2,%d1 # concat old sign,new exp 14015 mov.w %d1,FP_SCR0_EX(%a6) 14015 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 14016 mov.l (%sp)+,%d2 14016 mov.l (%sp)+,%d2 # restore d2 14017 fmovm.x FP_SCR0(%a6),&0x80 14017 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 14018 rts 14018 rts 14019 14019 14020 fsglmul_ovfl: 14020 fsglmul_ovfl: 14021 fmovm.x FP_SCR1(%a6),&0x80 14021 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14022 14022 14023 fmov.l L_SCR3(%a6),%fpcr 14023 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14024 fmov.l &0x0,%fpsr 14024 fmov.l &0x0,%fpsr # clear FPSR 14025 14025 14026 fsglmul.x FP_SCR0(%a6),%fp0 14026 fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply 14027 14027 14028 fmov.l %fpsr,%d1 14028 fmov.l %fpsr,%d1 # save status 14029 fmov.l &0x0,%fpcr 14029 fmov.l &0x0,%fpcr # clear FPCR 14030 14030 14031 or.l %d1,USER_FPSR(%a6) 14031 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14032 14032 14033 fsglmul_ovfl_tst: 14033 fsglmul_ovfl_tst: 14034 14034 14035 # save setting this until now because this i 14035 # save setting this until now because this is where fsglmul_may_ovfl may jump in 14036 or.l &ovfl_inx_mask, USER 14036 or.l &ovfl_inx_mask, USER_FPSR(%a6) # set ovfl/aovfl/ainex 14037 14037 14038 mov.b FPCR_ENABLE(%a6),%d1 14038 mov.b FPCR_ENABLE(%a6),%d1 14039 andi.b &0x13,%d1 14039 andi.b &0x13,%d1 # is OVFL or INEX enabled? 14040 bne.b fsglmul_ovfl_ena 14040 bne.b fsglmul_ovfl_ena # yes 14041 14041 14042 fsglmul_ovfl_dis: 14042 fsglmul_ovfl_dis: 14043 btst &neg_bit,FPSR_CC(%a6 14043 btst &neg_bit,FPSR_CC(%a6) # is result negative? 14044 sne %d1 14044 sne %d1 # set sign param accordingly 14045 mov.l L_SCR3(%a6),%d0 14045 mov.l L_SCR3(%a6),%d0 # pass prec:rnd 14046 andi.b &0x30,%d0 14046 andi.b &0x30,%d0 # force prec = ext 14047 bsr.l ovf_res 14047 bsr.l ovf_res # calculate default result 14048 or.b %d0,FPSR_CC(%a6) 14048 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 14049 fmovm.x (%a0),&0x80 14049 fmovm.x (%a0),&0x80 # return default result in fp0 14050 rts 14050 rts 14051 14051 14052 fsglmul_ovfl_ena: 14052 fsglmul_ovfl_ena: 14053 fmovm.x &0x80,FP_SCR0(%a6) 14053 fmovm.x &0x80,FP_SCR0(%a6) # move result to stack 14054 14054 14055 mov.l %d2,-(%sp) 14055 mov.l %d2,-(%sp) # save d2 14056 mov.w FP_SCR0_EX(%a6),%d1 14056 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 14057 mov.l %d1,%d2 14057 mov.l %d1,%d2 # make a copy 14058 andi.l &0x7fff,%d1 14058 andi.l &0x7fff,%d1 # strip sign 14059 sub.l %d0,%d1 14059 sub.l %d0,%d1 # add scale factor 14060 subi.l &0x6000,%d1 14060 subi.l &0x6000,%d1 # subtract bias 14061 andi.w &0x7fff,%d1 14061 andi.w &0x7fff,%d1 14062 andi.w &0x8000,%d2 14062 andi.w &0x8000,%d2 # keep old sign 14063 or.w %d2,%d1 14063 or.w %d2,%d1 # concat old sign,new exp 14064 mov.w %d1,FP_SCR0_EX(%a6) 14064 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 14065 mov.l (%sp)+,%d2 14065 mov.l (%sp)+,%d2 # restore d2 14066 fmovm.x FP_SCR0(%a6),&0x40 14066 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 14067 bra.b fsglmul_ovfl_dis 14067 bra.b fsglmul_ovfl_dis 14068 14068 14069 fsglmul_may_ovfl: 14069 fsglmul_may_ovfl: 14070 fmovm.x FP_SCR1(%a6),&0x80 14070 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14071 14071 14072 fmov.l L_SCR3(%a6),%fpcr 14072 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14073 fmov.l &0x0,%fpsr 14073 fmov.l &0x0,%fpsr # clear FPSR 14074 14074 14075 fsglmul.x FP_SCR0(%a6),%fp0 14075 fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply 14076 14076 14077 fmov.l %fpsr,%d1 14077 fmov.l %fpsr,%d1 # save status 14078 fmov.l &0x0,%fpcr 14078 fmov.l &0x0,%fpcr # clear FPCR 14079 14079 14080 or.l %d1,USER_FPSR(%a6) 14080 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14081 14081 14082 fabs.x %fp0,%fp1 14082 fabs.x %fp0,%fp1 # make a copy of result 14083 fcmp.b %fp1,&0x2 14083 fcmp.b %fp1,&0x2 # is |result| >= 2.b? 14084 fbge.w fsglmul_ovfl_tst 14084 fbge.w fsglmul_ovfl_tst # yes; overflow has occurred 14085 14085 14086 # no, it didn't overflow; we have correct re 14086 # no, it didn't overflow; we have correct result 14087 bra.w fsglmul_normal_exit 14087 bra.w fsglmul_normal_exit 14088 14088 14089 fsglmul_unfl: 14089 fsglmul_unfl: 14090 bset &unfl_bit,FPSR_EXCEP 14090 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 14091 14091 14092 fmovm.x FP_SCR1(%a6),&0x80 14092 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14093 14093 14094 fmov.l &rz_mode*0x10,%fpcr 14094 fmov.l &rz_mode*0x10,%fpcr # set FPCR 14095 fmov.l &0x0,%fpsr 14095 fmov.l &0x0,%fpsr # clear FPSR 14096 14096 14097 fsglmul.x FP_SCR0(%a6),%fp0 14097 fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply 14098 14098 14099 fmov.l %fpsr,%d1 14099 fmov.l %fpsr,%d1 # save status 14100 fmov.l &0x0,%fpcr 14100 fmov.l &0x0,%fpcr # clear FPCR 14101 14101 14102 or.l %d1,USER_FPSR(%a6) 14102 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14103 14103 14104 mov.b FPCR_ENABLE(%a6),%d1 14104 mov.b FPCR_ENABLE(%a6),%d1 14105 andi.b &0x0b,%d1 14105 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 14106 bne.b fsglmul_unfl_ena 14106 bne.b fsglmul_unfl_ena # yes 14107 14107 14108 fsglmul_unfl_dis: 14108 fsglmul_unfl_dis: 14109 fmovm.x &0x80,FP_SCR0(%a6) 14109 fmovm.x &0x80,FP_SCR0(%a6) # store out result 14110 14110 14111 lea FP_SCR0(%a6),%a0 14111 lea FP_SCR0(%a6),%a0 # pass: result addr 14112 mov.l L_SCR3(%a6),%d1 14112 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 14113 bsr.l unf_res4 14113 bsr.l unf_res4 # calculate default result 14114 or.b %d0,FPSR_CC(%a6) 14114 or.b %d0,FPSR_CC(%a6) # 'Z' bit may have been set 14115 fmovm.x FP_SCR0(%a6),&0x80 14115 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 14116 rts 14116 rts 14117 14117 14118 # 14118 # 14119 # UNFL is enabled. 14119 # UNFL is enabled. 14120 # 14120 # 14121 fsglmul_unfl_ena: 14121 fsglmul_unfl_ena: 14122 fmovm.x FP_SCR1(%a6),&0x40 14122 fmovm.x FP_SCR1(%a6),&0x40 # load dst op 14123 14123 14124 fmov.l L_SCR3(%a6),%fpcr 14124 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14125 fmov.l &0x0,%fpsr 14125 fmov.l &0x0,%fpsr # clear FPSR 14126 14126 14127 fsglmul.x FP_SCR0(%a6),%fp1 14127 fsglmul.x FP_SCR0(%a6),%fp1 # execute sgl multiply 14128 14128 14129 fmov.l &0x0,%fpcr 14129 fmov.l &0x0,%fpcr # clear FPCR 14130 14130 14131 fmovm.x &0x40,FP_SCR0(%a6) 14131 fmovm.x &0x40,FP_SCR0(%a6) # save result to stack 14132 mov.l %d2,-(%sp) 14132 mov.l %d2,-(%sp) # save d2 14133 mov.w FP_SCR0_EX(%a6),%d1 14133 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 14134 mov.l %d1,%d2 14134 mov.l %d1,%d2 # make a copy 14135 andi.l &0x7fff,%d1 14135 andi.l &0x7fff,%d1 # strip sign 14136 andi.w &0x8000,%d2 14136 andi.w &0x8000,%d2 # keep old sign 14137 sub.l %d0,%d1 14137 sub.l %d0,%d1 # add scale factor 14138 addi.l &0x6000,%d1 14138 addi.l &0x6000,%d1 # add bias 14139 andi.w &0x7fff,%d1 14139 andi.w &0x7fff,%d1 14140 or.w %d2,%d1 14140 or.w %d2,%d1 # concat old sign,new exp 14141 mov.w %d1,FP_SCR0_EX(%a6) 14141 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 14142 mov.l (%sp)+,%d2 14142 mov.l (%sp)+,%d2 # restore d2 14143 fmovm.x FP_SCR0(%a6),&0x40 14143 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 14144 bra.w fsglmul_unfl_dis 14144 bra.w fsglmul_unfl_dis 14145 14145 14146 fsglmul_may_unfl: 14146 fsglmul_may_unfl: 14147 fmovm.x FP_SCR1(%a6),&0x80 14147 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14148 14148 14149 fmov.l L_SCR3(%a6),%fpcr 14149 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14150 fmov.l &0x0,%fpsr 14150 fmov.l &0x0,%fpsr # clear FPSR 14151 14151 14152 fsglmul.x FP_SCR0(%a6),%fp0 14152 fsglmul.x FP_SCR0(%a6),%fp0 # execute sgl multiply 14153 14153 14154 fmov.l %fpsr,%d1 14154 fmov.l %fpsr,%d1 # save status 14155 fmov.l &0x0,%fpcr 14155 fmov.l &0x0,%fpcr # clear FPCR 14156 14156 14157 or.l %d1,USER_FPSR(%a6) 14157 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14158 14158 14159 fabs.x %fp0,%fp1 14159 fabs.x %fp0,%fp1 # make a copy of result 14160 fcmp.b %fp1,&0x2 14160 fcmp.b %fp1,&0x2 # is |result| > 2.b? 14161 fbgt.w fsglmul_normal_exit 14161 fbgt.w fsglmul_normal_exit # no; no underflow occurred 14162 fblt.w fsglmul_unfl 14162 fblt.w fsglmul_unfl # yes; underflow occurred 14163 14163 14164 # 14164 # 14165 # we still don't know if underflow occurred. 14165 # we still don't know if underflow occurred. result is ~ equal to 2. but, 14166 # we don't know if the result was an underfl 14166 # we don't know if the result was an underflow that rounded up to a 2 or 14167 # a normalized number that rounded down to a 14167 # a normalized number that rounded down to a 2. so, redo the entire operation 14168 # using RZ as the rounding mode to see what 14168 # using RZ as the rounding mode to see what the pre-rounded result is. 14169 # this case should be relatively rare. 14169 # this case should be relatively rare. 14170 # 14170 # 14171 fmovm.x FP_SCR1(%a6),&0x40 14171 fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1 14172 14172 14173 mov.l L_SCR3(%a6),%d1 14173 mov.l L_SCR3(%a6),%d1 14174 andi.b &0xc0,%d1 14174 andi.b &0xc0,%d1 # keep rnd prec 14175 ori.b &rz_mode*0x10,%d1 14175 ori.b &rz_mode*0x10,%d1 # insert RZ 14176 14176 14177 fmov.l %d1,%fpcr 14177 fmov.l %d1,%fpcr # set FPCR 14178 fmov.l &0x0,%fpsr 14178 fmov.l &0x0,%fpsr # clear FPSR 14179 14179 14180 fsglmul.x FP_SCR0(%a6),%fp1 14180 fsglmul.x FP_SCR0(%a6),%fp1 # execute sgl multiply 14181 14181 14182 fmov.l &0x0,%fpcr 14182 fmov.l &0x0,%fpcr # clear FPCR 14183 fabs.x %fp1 14183 fabs.x %fp1 # make absolute value 14184 fcmp.b %fp1,&0x2 14184 fcmp.b %fp1,&0x2 # is |result| < 2.b? 14185 fbge.w fsglmul_normal_exit 14185 fbge.w fsglmul_normal_exit # no; no underflow occurred 14186 bra.w fsglmul_unfl 14186 bra.w fsglmul_unfl # yes, underflow occurred 14187 14187 14188 ############################################ 14188 ############################################################################## 14189 14189 14190 # 14190 # 14191 # Single Precision Multiply: inputs are not 14191 # Single Precision Multiply: inputs are not both normalized; what are they? 14192 # 14192 # 14193 fsglmul_not_norm: 14193 fsglmul_not_norm: 14194 mov.w (tbl_fsglmul_op.b,%p 14194 mov.w (tbl_fsglmul_op.b,%pc,%d1.w*2),%d1 14195 jmp (tbl_fsglmul_op.b,%p 14195 jmp (tbl_fsglmul_op.b,%pc,%d1.w*1) 14196 14196 14197 swbeg &48 14197 swbeg &48 14198 tbl_fsglmul_op: 14198 tbl_fsglmul_op: 14199 short fsglmul_norm 14199 short fsglmul_norm - tbl_fsglmul_op # NORM x NORM 14200 short fsglmul_zero 14200 short fsglmul_zero - tbl_fsglmul_op # NORM x ZERO 14201 short fsglmul_inf_src 14201 short fsglmul_inf_src - tbl_fsglmul_op # NORM x INF 14202 short fsglmul_res_qnan 14202 short fsglmul_res_qnan - tbl_fsglmul_op # NORM x QNAN 14203 short fsglmul_norm 14203 short fsglmul_norm - tbl_fsglmul_op # NORM x DENORM 14204 short fsglmul_res_snan 14204 short fsglmul_res_snan - tbl_fsglmul_op # NORM x SNAN 14205 short tbl_fsglmul_op 14205 short tbl_fsglmul_op - tbl_fsglmul_op # 14206 short tbl_fsglmul_op 14206 short tbl_fsglmul_op - tbl_fsglmul_op # 14207 14207 14208 short fsglmul_zero 14208 short fsglmul_zero - tbl_fsglmul_op # ZERO x NORM 14209 short fsglmul_zero 14209 short fsglmul_zero - tbl_fsglmul_op # ZERO x ZERO 14210 short fsglmul_res_operr 14210 short fsglmul_res_operr - tbl_fsglmul_op # ZERO x INF 14211 short fsglmul_res_qnan 14211 short fsglmul_res_qnan - tbl_fsglmul_op # ZERO x QNAN 14212 short fsglmul_zero 14212 short fsglmul_zero - tbl_fsglmul_op # ZERO x DENORM 14213 short fsglmul_res_snan 14213 short fsglmul_res_snan - tbl_fsglmul_op # ZERO x SNAN 14214 short tbl_fsglmul_op 14214 short tbl_fsglmul_op - tbl_fsglmul_op # 14215 short tbl_fsglmul_op 14215 short tbl_fsglmul_op - tbl_fsglmul_op # 14216 14216 14217 short fsglmul_inf_dst 14217 short fsglmul_inf_dst - tbl_fsglmul_op # INF x NORM 14218 short fsglmul_res_operr 14218 short fsglmul_res_operr - tbl_fsglmul_op # INF x ZERO 14219 short fsglmul_inf_dst 14219 short fsglmul_inf_dst - tbl_fsglmul_op # INF x INF 14220 short fsglmul_res_qnan 14220 short fsglmul_res_qnan - tbl_fsglmul_op # INF x QNAN 14221 short fsglmul_inf_dst 14221 short fsglmul_inf_dst - tbl_fsglmul_op # INF x DENORM 14222 short fsglmul_res_snan 14222 short fsglmul_res_snan - tbl_fsglmul_op # INF x SNAN 14223 short tbl_fsglmul_op 14223 short tbl_fsglmul_op - tbl_fsglmul_op # 14224 short tbl_fsglmul_op 14224 short tbl_fsglmul_op - tbl_fsglmul_op # 14225 14225 14226 short fsglmul_res_qnan 14226 short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x NORM 14227 short fsglmul_res_qnan 14227 short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x ZERO 14228 short fsglmul_res_qnan 14228 short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x INF 14229 short fsglmul_res_qnan 14229 short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x QNAN 14230 short fsglmul_res_qnan 14230 short fsglmul_res_qnan - tbl_fsglmul_op # QNAN x DENORM 14231 short fsglmul_res_snan 14231 short fsglmul_res_snan - tbl_fsglmul_op # QNAN x SNAN 14232 short tbl_fsglmul_op 14232 short tbl_fsglmul_op - tbl_fsglmul_op # 14233 short tbl_fsglmul_op 14233 short tbl_fsglmul_op - tbl_fsglmul_op # 14234 14234 14235 short fsglmul_norm 14235 short fsglmul_norm - tbl_fsglmul_op # NORM x NORM 14236 short fsglmul_zero 14236 short fsglmul_zero - tbl_fsglmul_op # NORM x ZERO 14237 short fsglmul_inf_src 14237 short fsglmul_inf_src - tbl_fsglmul_op # NORM x INF 14238 short fsglmul_res_qnan 14238 short fsglmul_res_qnan - tbl_fsglmul_op # NORM x QNAN 14239 short fsglmul_norm 14239 short fsglmul_norm - tbl_fsglmul_op # NORM x DENORM 14240 short fsglmul_res_snan 14240 short fsglmul_res_snan - tbl_fsglmul_op # NORM x SNAN 14241 short tbl_fsglmul_op 14241 short tbl_fsglmul_op - tbl_fsglmul_op # 14242 short tbl_fsglmul_op 14242 short tbl_fsglmul_op - tbl_fsglmul_op # 14243 14243 14244 short fsglmul_res_snan 14244 short fsglmul_res_snan - tbl_fsglmul_op # SNAN x NORM 14245 short fsglmul_res_snan 14245 short fsglmul_res_snan - tbl_fsglmul_op # SNAN x ZERO 14246 short fsglmul_res_snan 14246 short fsglmul_res_snan - tbl_fsglmul_op # SNAN x INF 14247 short fsglmul_res_snan 14247 short fsglmul_res_snan - tbl_fsglmul_op # SNAN x QNAN 14248 short fsglmul_res_snan 14248 short fsglmul_res_snan - tbl_fsglmul_op # SNAN x DENORM 14249 short fsglmul_res_snan 14249 short fsglmul_res_snan - tbl_fsglmul_op # SNAN x SNAN 14250 short tbl_fsglmul_op 14250 short tbl_fsglmul_op - tbl_fsglmul_op # 14251 short tbl_fsglmul_op 14251 short tbl_fsglmul_op - tbl_fsglmul_op # 14252 14252 14253 fsglmul_res_operr: 14253 fsglmul_res_operr: 14254 bra.l res_operr 14254 bra.l res_operr 14255 fsglmul_res_snan: 14255 fsglmul_res_snan: 14256 bra.l res_snan 14256 bra.l res_snan 14257 fsglmul_res_qnan: 14257 fsglmul_res_qnan: 14258 bra.l res_qnan 14258 bra.l res_qnan 14259 fsglmul_zero: 14259 fsglmul_zero: 14260 bra.l fmul_zero 14260 bra.l fmul_zero 14261 fsglmul_inf_src: 14261 fsglmul_inf_src: 14262 bra.l fmul_inf_src 14262 bra.l fmul_inf_src 14263 fsglmul_inf_dst: 14263 fsglmul_inf_dst: 14264 bra.l fmul_inf_dst 14264 bra.l fmul_inf_dst 14265 14265 14266 ############################################ 14266 ######################################################################### 14267 # XDEF ************************************* 14267 # XDEF **************************************************************** # 14268 # fsgldiv(): emulates the fsgldiv inst 14268 # fsgldiv(): emulates the fsgldiv instruction # 14269 # 14269 # # 14270 # XREF ************************************* 14270 # XREF **************************************************************** # 14271 # scale_to_zero_src() - scale src expo 14271 # scale_to_zero_src() - scale src exponent to zero # 14272 # scale_to_zero_dst() - scale dst expo 14272 # scale_to_zero_dst() - scale dst exponent to zero # 14273 # unf_res4() - return default underflo 14273 # unf_res4() - return default underflow result for sglop # 14274 # ovf_res() - return default overflow 14274 # ovf_res() - return default overflow result # 14275 # res_qnan() - return QNAN result 14275 # res_qnan() - return QNAN result # 14276 # res_snan() - return SNAN result 14276 # res_snan() - return SNAN result # 14277 # 14277 # # 14278 # INPUT ************************************ 14278 # INPUT *************************************************************** # 14279 # a0 = pointer to extended precision s 14279 # a0 = pointer to extended precision source operand # 14280 # a1 = pointer to extended precision d 14280 # a1 = pointer to extended precision destination operand # 14281 # d0 rnd prec,mode 14281 # d0 rnd prec,mode # 14282 # 14282 # # 14283 # OUTPUT *********************************** 14283 # OUTPUT ************************************************************** # 14284 # fp0 = result 14284 # fp0 = result # 14285 # fp1 = EXOP (if exception occurred) 14285 # fp1 = EXOP (if exception occurred) # 14286 # 14286 # # 14287 # ALGORITHM ******************************** 14287 # ALGORITHM *********************************************************** # 14288 # Handle NANs, infinities, and zeroes 14288 # Handle NANs, infinities, and zeroes as special cases. Divide # 14289 # norms/denorms into ext/sgl/dbl precision. 14289 # norms/denorms into ext/sgl/dbl precision. # 14290 # For norms/denorms, scale the exponen 14290 # For norms/denorms, scale the exponents such that a divide # 14291 # instruction won't cause an exception. Use 14291 # instruction won't cause an exception. Use the regular fsgldiv to # 14292 # compute a result. Check if the regular ope 14292 # compute a result. Check if the regular operands would have taken # 14293 # an exception. If so, return the default ov 14293 # an exception. If so, return the default overflow/underflow result # 14294 # and return the EXOP if exceptions are enab 14294 # and return the EXOP if exceptions are enabled. Else, scale the # 14295 # result operand to the proper exponent. 14295 # result operand to the proper exponent. # 14296 # 14296 # # 14297 ############################################ 14297 ######################################################################### 14298 14298 14299 global fsgldiv 14299 global fsgldiv 14300 fsgldiv: 14300 fsgldiv: 14301 mov.l %d0,L_SCR3(%a6) 14301 mov.l %d0,L_SCR3(%a6) # store rnd info 14302 14302 14303 clr.w %d1 14303 clr.w %d1 14304 mov.b DTAG(%a6),%d1 14304 mov.b DTAG(%a6),%d1 14305 lsl.b &0x3,%d1 14305 lsl.b &0x3,%d1 14306 or.b STAG(%a6),%d1 14306 or.b STAG(%a6),%d1 # combine src tags 14307 14307 14308 bne.w fsgldiv_not_norm 14308 bne.w fsgldiv_not_norm # optimize on non-norm input 14309 14309 14310 # 14310 # 14311 # DIVIDE: NORMs and DENORMs ONLY! 14311 # DIVIDE: NORMs and DENORMs ONLY! 14312 # 14312 # 14313 fsgldiv_norm: 14313 fsgldiv_norm: 14314 mov.w DST_EX(%a1),FP_SCR1_ 14314 mov.w DST_EX(%a1),FP_SCR1_EX(%a6) 14315 mov.l DST_HI(%a1),FP_SCR1_ 14315 mov.l DST_HI(%a1),FP_SCR1_HI(%a6) 14316 mov.l DST_LO(%a1),FP_SCR1_ 14316 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 14317 14317 14318 mov.w SRC_EX(%a0),FP_SCR0_ 14318 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 14319 mov.l SRC_HI(%a0),FP_SCR0_ 14319 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 14320 mov.l SRC_LO(%a0),FP_SCR0_ 14320 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 14321 14321 14322 bsr.l scale_to_zero_src 14322 bsr.l scale_to_zero_src # calculate scale factor 1 14323 mov.l %d0,-(%sp) 14323 mov.l %d0,-(%sp) # save scale factor 1 14324 14324 14325 bsr.l scale_to_zero_dst 14325 bsr.l scale_to_zero_dst # calculate scale factor 2 14326 14326 14327 neg.l (%sp) 14327 neg.l (%sp) # S.F. = scale1 - scale2 14328 add.l %d0,(%sp) 14328 add.l %d0,(%sp) 14329 14329 14330 mov.w 2+L_SCR3(%a6),%d1 14330 mov.w 2+L_SCR3(%a6),%d1 # fetch precision,mode 14331 lsr.b &0x6,%d1 14331 lsr.b &0x6,%d1 14332 mov.l (%sp)+,%d0 14332 mov.l (%sp)+,%d0 14333 cmpi.l %d0,&0x3fff-0x7ffe 14333 cmpi.l %d0,&0x3fff-0x7ffe 14334 ble.w fsgldiv_may_ovfl 14334 ble.w fsgldiv_may_ovfl 14335 14335 14336 cmpi.l %d0,&0x3fff-0x0000 14336 cmpi.l %d0,&0x3fff-0x0000 # will result underflow? 14337 beq.w fsgldiv_may_unfl 14337 beq.w fsgldiv_may_unfl # maybe 14338 bgt.w fsgldiv_unfl 14338 bgt.w fsgldiv_unfl # yes; go handle underflow 14339 14339 14340 fsgldiv_normal: 14340 fsgldiv_normal: 14341 fmovm.x FP_SCR1(%a6),&0x80 14341 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14342 14342 14343 fmov.l L_SCR3(%a6),%fpcr 14343 fmov.l L_SCR3(%a6),%fpcr # save FPCR 14344 fmov.l &0x0,%fpsr 14344 fmov.l &0x0,%fpsr # clear FPSR 14345 14345 14346 fsgldiv.x FP_SCR0(%a6),%fp0 14346 fsgldiv.x FP_SCR0(%a6),%fp0 # perform sgl divide 14347 14347 14348 fmov.l %fpsr,%d1 14348 fmov.l %fpsr,%d1 # save FPSR 14349 fmov.l &0x0,%fpcr 14349 fmov.l &0x0,%fpcr # clear FPCR 14350 14350 14351 or.l %d1,USER_FPSR(%a6) 14351 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14352 14352 14353 fsgldiv_normal_exit: 14353 fsgldiv_normal_exit: 14354 fmovm.x &0x80,FP_SCR0(%a6) 14354 fmovm.x &0x80,FP_SCR0(%a6) # store result on stack 14355 mov.l %d2,-(%sp) 14355 mov.l %d2,-(%sp) # save d2 14356 mov.w FP_SCR0_EX(%a6),%d1 14356 mov.w FP_SCR0_EX(%a6),%d1 # load {sgn,exp} 14357 mov.l %d1,%d2 14357 mov.l %d1,%d2 # make a copy 14358 andi.l &0x7fff,%d1 14358 andi.l &0x7fff,%d1 # strip sign 14359 andi.w &0x8000,%d2 14359 andi.w &0x8000,%d2 # keep old sign 14360 sub.l %d0,%d1 14360 sub.l %d0,%d1 # add scale factor 14361 or.w %d2,%d1 14361 or.w %d2,%d1 # concat old sign,new exp 14362 mov.w %d1,FP_SCR0_EX(%a6) 14362 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 14363 mov.l (%sp)+,%d2 14363 mov.l (%sp)+,%d2 # restore d2 14364 fmovm.x FP_SCR0(%a6),&0x80 14364 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 14365 rts 14365 rts 14366 14366 14367 fsgldiv_may_ovfl: 14367 fsgldiv_may_ovfl: 14368 fmovm.x FP_SCR1(%a6),&0x80 14368 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14369 14369 14370 fmov.l L_SCR3(%a6),%fpcr 14370 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14371 fmov.l &0x0,%fpsr 14371 fmov.l &0x0,%fpsr # set FPSR 14372 14372 14373 fsgldiv.x FP_SCR0(%a6),%fp0 14373 fsgldiv.x FP_SCR0(%a6),%fp0 # execute divide 14374 14374 14375 fmov.l %fpsr,%d1 14375 fmov.l %fpsr,%d1 14376 fmov.l &0x0,%fpcr 14376 fmov.l &0x0,%fpcr 14377 14377 14378 or.l %d1,USER_FPSR(%a6) 14378 or.l %d1,USER_FPSR(%a6) # save INEX,N 14379 14379 14380 fmovm.x &0x01,-(%sp) 14380 fmovm.x &0x01,-(%sp) # save result to stack 14381 mov.w (%sp),%d1 14381 mov.w (%sp),%d1 # fetch new exponent 14382 add.l &0xc,%sp 14382 add.l &0xc,%sp # clear result 14383 andi.l &0x7fff,%d1 14383 andi.l &0x7fff,%d1 # strip sign 14384 sub.l %d0,%d1 14384 sub.l %d0,%d1 # add scale factor 14385 cmp.l %d1,&0x7fff 14385 cmp.l %d1,&0x7fff # did divide overflow? 14386 blt.b fsgldiv_normal_exit 14386 blt.b fsgldiv_normal_exit 14387 14387 14388 fsgldiv_ovfl_tst: 14388 fsgldiv_ovfl_tst: 14389 or.w &ovfl_inx_mask,2+USE 14389 or.w &ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex 14390 14390 14391 mov.b FPCR_ENABLE(%a6),%d1 14391 mov.b FPCR_ENABLE(%a6),%d1 14392 andi.b &0x13,%d1 14392 andi.b &0x13,%d1 # is OVFL or INEX enabled? 14393 bne.b fsgldiv_ovfl_ena 14393 bne.b fsgldiv_ovfl_ena # yes 14394 14394 14395 fsgldiv_ovfl_dis: 14395 fsgldiv_ovfl_dis: 14396 btst &neg_bit,FPSR_CC(%a6 14396 btst &neg_bit,FPSR_CC(%a6) # is result negative 14397 sne %d1 14397 sne %d1 # set sign param accordingly 14398 mov.l L_SCR3(%a6),%d0 14398 mov.l L_SCR3(%a6),%d0 # pass prec:rnd 14399 andi.b &0x30,%d0 14399 andi.b &0x30,%d0 # kill precision 14400 bsr.l ovf_res 14400 bsr.l ovf_res # calculate default result 14401 or.b %d0,FPSR_CC(%a6) 14401 or.b %d0,FPSR_CC(%a6) # set INF if applicable 14402 fmovm.x (%a0),&0x80 14402 fmovm.x (%a0),&0x80 # return default result in fp0 14403 rts 14403 rts 14404 14404 14405 fsgldiv_ovfl_ena: 14405 fsgldiv_ovfl_ena: 14406 fmovm.x &0x80,FP_SCR0(%a6) 14406 fmovm.x &0x80,FP_SCR0(%a6) # move result to stack 14407 14407 14408 mov.l %d2,-(%sp) 14408 mov.l %d2,-(%sp) # save d2 14409 mov.w FP_SCR0_EX(%a6),%d1 14409 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 14410 mov.l %d1,%d2 14410 mov.l %d1,%d2 # make a copy 14411 andi.l &0x7fff,%d1 14411 andi.l &0x7fff,%d1 # strip sign 14412 andi.w &0x8000,%d2 14412 andi.w &0x8000,%d2 # keep old sign 14413 sub.l %d0,%d1 14413 sub.l %d0,%d1 # add scale factor 14414 subi.l &0x6000,%d1 14414 subi.l &0x6000,%d1 # subtract new bias 14415 andi.w &0x7fff,%d1 14415 andi.w &0x7fff,%d1 # clear ms bit 14416 or.w %d2,%d1 14416 or.w %d2,%d1 # concat old sign,new exp 14417 mov.w %d1,FP_SCR0_EX(%a6) 14417 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 14418 mov.l (%sp)+,%d2 14418 mov.l (%sp)+,%d2 # restore d2 14419 fmovm.x FP_SCR0(%a6),&0x40 14419 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 14420 bra.b fsgldiv_ovfl_dis 14420 bra.b fsgldiv_ovfl_dis 14421 14421 14422 fsgldiv_unfl: 14422 fsgldiv_unfl: 14423 bset &unfl_bit,FPSR_EXCEP 14423 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 14424 14424 14425 fmovm.x FP_SCR1(%a6),&0x80 14425 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14426 14426 14427 fmov.l &rz_mode*0x10,%fpcr 14427 fmov.l &rz_mode*0x10,%fpcr # set FPCR 14428 fmov.l &0x0,%fpsr 14428 fmov.l &0x0,%fpsr # clear FPSR 14429 14429 14430 fsgldiv.x FP_SCR0(%a6),%fp0 14430 fsgldiv.x FP_SCR0(%a6),%fp0 # execute sgl divide 14431 14431 14432 fmov.l %fpsr,%d1 14432 fmov.l %fpsr,%d1 # save status 14433 fmov.l &0x0,%fpcr 14433 fmov.l &0x0,%fpcr # clear FPCR 14434 14434 14435 or.l %d1,USER_FPSR(%a6) 14435 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14436 14436 14437 mov.b FPCR_ENABLE(%a6),%d1 14437 mov.b FPCR_ENABLE(%a6),%d1 14438 andi.b &0x0b,%d1 14438 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 14439 bne.b fsgldiv_unfl_ena 14439 bne.b fsgldiv_unfl_ena # yes 14440 14440 14441 fsgldiv_unfl_dis: 14441 fsgldiv_unfl_dis: 14442 fmovm.x &0x80,FP_SCR0(%a6) 14442 fmovm.x &0x80,FP_SCR0(%a6) # store out result 14443 14443 14444 lea FP_SCR0(%a6),%a0 14444 lea FP_SCR0(%a6),%a0 # pass: result addr 14445 mov.l L_SCR3(%a6),%d1 14445 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 14446 bsr.l unf_res4 14446 bsr.l unf_res4 # calculate default result 14447 or.b %d0,FPSR_CC(%a6) 14447 or.b %d0,FPSR_CC(%a6) # 'Z' bit may have been set 14448 fmovm.x FP_SCR0(%a6),&0x80 14448 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 14449 rts 14449 rts 14450 14450 14451 # 14451 # 14452 # UNFL is enabled. 14452 # UNFL is enabled. 14453 # 14453 # 14454 fsgldiv_unfl_ena: 14454 fsgldiv_unfl_ena: 14455 fmovm.x FP_SCR1(%a6),&0x40 14455 fmovm.x FP_SCR1(%a6),&0x40 # load dst op 14456 14456 14457 fmov.l L_SCR3(%a6),%fpcr 14457 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14458 fmov.l &0x0,%fpsr 14458 fmov.l &0x0,%fpsr # clear FPSR 14459 14459 14460 fsgldiv.x FP_SCR0(%a6),%fp1 14460 fsgldiv.x FP_SCR0(%a6),%fp1 # execute sgl divide 14461 14461 14462 fmov.l &0x0,%fpcr 14462 fmov.l &0x0,%fpcr # clear FPCR 14463 14463 14464 fmovm.x &0x40,FP_SCR0(%a6) 14464 fmovm.x &0x40,FP_SCR0(%a6) # save result to stack 14465 mov.l %d2,-(%sp) 14465 mov.l %d2,-(%sp) # save d2 14466 mov.w FP_SCR0_EX(%a6),%d1 14466 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 14467 mov.l %d1,%d2 14467 mov.l %d1,%d2 # make a copy 14468 andi.l &0x7fff,%d1 14468 andi.l &0x7fff,%d1 # strip sign 14469 andi.w &0x8000,%d2 14469 andi.w &0x8000,%d2 # keep old sign 14470 sub.l %d0,%d1 14470 sub.l %d0,%d1 # add scale factor 14471 addi.l &0x6000,%d1 14471 addi.l &0x6000,%d1 # add bias 14472 andi.w &0x7fff,%d1 14472 andi.w &0x7fff,%d1 # clear top bit 14473 or.w %d2,%d1 14473 or.w %d2,%d1 # concat old sign, new exp 14474 mov.w %d1,FP_SCR0_EX(%a6) 14474 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 14475 mov.l (%sp)+,%d2 14475 mov.l (%sp)+,%d2 # restore d2 14476 fmovm.x FP_SCR0(%a6),&0x40 14476 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 14477 bra.b fsgldiv_unfl_dis 14477 bra.b fsgldiv_unfl_dis 14478 14478 14479 # 14479 # 14480 # the divide operation MAY underflow: 14480 # the divide operation MAY underflow: 14481 # 14481 # 14482 fsgldiv_may_unfl: 14482 fsgldiv_may_unfl: 14483 fmovm.x FP_SCR1(%a6),&0x80 14483 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14484 14484 14485 fmov.l L_SCR3(%a6),%fpcr 14485 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14486 fmov.l &0x0,%fpsr 14486 fmov.l &0x0,%fpsr # clear FPSR 14487 14487 14488 fsgldiv.x FP_SCR0(%a6),%fp0 14488 fsgldiv.x FP_SCR0(%a6),%fp0 # execute sgl divide 14489 14489 14490 fmov.l %fpsr,%d1 14490 fmov.l %fpsr,%d1 # save status 14491 fmov.l &0x0,%fpcr 14491 fmov.l &0x0,%fpcr # clear FPCR 14492 14492 14493 or.l %d1,USER_FPSR(%a6) 14493 or.l %d1,USER_FPSR(%a6) # save INEX2,N 14494 14494 14495 fabs.x %fp0,%fp1 14495 fabs.x %fp0,%fp1 # make a copy of result 14496 fcmp.b %fp1,&0x1 14496 fcmp.b %fp1,&0x1 # is |result| > 1.b? 14497 fbgt.w fsgldiv_normal_exit 14497 fbgt.w fsgldiv_normal_exit # no; no underflow occurred 14498 fblt.w fsgldiv_unfl 14498 fblt.w fsgldiv_unfl # yes; underflow occurred 14499 14499 14500 # 14500 # 14501 # we still don't know if underflow occurred. 14501 # we still don't know if underflow occurred. result is ~ equal to 1. but, 14502 # we don't know if the result was an underfl 14502 # we don't know if the result was an underflow that rounded up to a 1 14503 # or a normalized number that rounded down t 14503 # or a normalized number that rounded down to a 1. so, redo the entire 14504 # operation using RZ as the rounding mode to 14504 # operation using RZ as the rounding mode to see what the pre-rounded 14505 # result is. this case should be relatively 14505 # result is. this case should be relatively rare. 14506 # 14506 # 14507 fmovm.x FP_SCR1(%a6),&0x40 14507 fmovm.x FP_SCR1(%a6),&0x40 # load dst op into %fp1 14508 14508 14509 clr.l %d1 14509 clr.l %d1 # clear scratch register 14510 ori.b &rz_mode*0x10,%d1 14510 ori.b &rz_mode*0x10,%d1 # force RZ rnd mode 14511 14511 14512 fmov.l %d1,%fpcr 14512 fmov.l %d1,%fpcr # set FPCR 14513 fmov.l &0x0,%fpsr 14513 fmov.l &0x0,%fpsr # clear FPSR 14514 14514 14515 fsgldiv.x FP_SCR0(%a6),%fp1 14515 fsgldiv.x FP_SCR0(%a6),%fp1 # execute sgl divide 14516 14516 14517 fmov.l &0x0,%fpcr 14517 fmov.l &0x0,%fpcr # clear FPCR 14518 fabs.x %fp1 14518 fabs.x %fp1 # make absolute value 14519 fcmp.b %fp1,&0x1 14519 fcmp.b %fp1,&0x1 # is |result| < 1.b? 14520 fbge.w fsgldiv_normal_exit 14520 fbge.w fsgldiv_normal_exit # no; no underflow occurred 14521 bra.w fsgldiv_unfl 14521 bra.w fsgldiv_unfl # yes; underflow occurred 14522 14522 14523 ############################################ 14523 ############################################################################ 14524 14524 14525 # 14525 # 14526 # Divide: inputs are not both normalized; wh 14526 # Divide: inputs are not both normalized; what are they? 14527 # 14527 # 14528 fsgldiv_not_norm: 14528 fsgldiv_not_norm: 14529 mov.w (tbl_fsgldiv_op.b,%p 14529 mov.w (tbl_fsgldiv_op.b,%pc,%d1.w*2),%d1 14530 jmp (tbl_fsgldiv_op.b,%p 14530 jmp (tbl_fsgldiv_op.b,%pc,%d1.w*1) 14531 14531 14532 swbeg &48 14532 swbeg &48 14533 tbl_fsgldiv_op: 14533 tbl_fsgldiv_op: 14534 short fsgldiv_norm 14534 short fsgldiv_norm - tbl_fsgldiv_op # NORM / NORM 14535 short fsgldiv_inf_load 14535 short fsgldiv_inf_load - tbl_fsgldiv_op # NORM / ZERO 14536 short fsgldiv_zero_load 14536 short fsgldiv_zero_load - tbl_fsgldiv_op # NORM / INF 14537 short fsgldiv_res_qnan 14537 short fsgldiv_res_qnan - tbl_fsgldiv_op # NORM / QNAN 14538 short fsgldiv_norm 14538 short fsgldiv_norm - tbl_fsgldiv_op # NORM / DENORM 14539 short fsgldiv_res_snan 14539 short fsgldiv_res_snan - tbl_fsgldiv_op # NORM / SNAN 14540 short tbl_fsgldiv_op 14540 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14541 short tbl_fsgldiv_op 14541 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14542 14542 14543 short fsgldiv_zero_load 14543 short fsgldiv_zero_load - tbl_fsgldiv_op # ZERO / NORM 14544 short fsgldiv_res_operr 14544 short fsgldiv_res_operr - tbl_fsgldiv_op # ZERO / ZERO 14545 short fsgldiv_zero_load 14545 short fsgldiv_zero_load - tbl_fsgldiv_op # ZERO / INF 14546 short fsgldiv_res_qnan 14546 short fsgldiv_res_qnan - tbl_fsgldiv_op # ZERO / QNAN 14547 short fsgldiv_zero_load 14547 short fsgldiv_zero_load - tbl_fsgldiv_op # ZERO / DENORM 14548 short fsgldiv_res_snan 14548 short fsgldiv_res_snan - tbl_fsgldiv_op # ZERO / SNAN 14549 short tbl_fsgldiv_op 14549 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14550 short tbl_fsgldiv_op 14550 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14551 14551 14552 short fsgldiv_inf_dst 14552 short fsgldiv_inf_dst - tbl_fsgldiv_op # INF / NORM 14553 short fsgldiv_inf_dst 14553 short fsgldiv_inf_dst - tbl_fsgldiv_op # INF / ZERO 14554 short fsgldiv_res_operr 14554 short fsgldiv_res_operr - tbl_fsgldiv_op # INF / INF 14555 short fsgldiv_res_qnan 14555 short fsgldiv_res_qnan - tbl_fsgldiv_op # INF / QNAN 14556 short fsgldiv_inf_dst 14556 short fsgldiv_inf_dst - tbl_fsgldiv_op # INF / DENORM 14557 short fsgldiv_res_snan 14557 short fsgldiv_res_snan - tbl_fsgldiv_op # INF / SNAN 14558 short tbl_fsgldiv_op 14558 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14559 short tbl_fsgldiv_op 14559 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14560 14560 14561 short fsgldiv_res_qnan 14561 short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / NORM 14562 short fsgldiv_res_qnan 14562 short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / ZERO 14563 short fsgldiv_res_qnan 14563 short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / INF 14564 short fsgldiv_res_qnan 14564 short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / QNAN 14565 short fsgldiv_res_qnan 14565 short fsgldiv_res_qnan - tbl_fsgldiv_op # QNAN / DENORM 14566 short fsgldiv_res_snan 14566 short fsgldiv_res_snan - tbl_fsgldiv_op # QNAN / SNAN 14567 short tbl_fsgldiv_op 14567 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14568 short tbl_fsgldiv_op 14568 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14569 14569 14570 short fsgldiv_norm 14570 short fsgldiv_norm - tbl_fsgldiv_op # DENORM / NORM 14571 short fsgldiv_inf_load 14571 short fsgldiv_inf_load - tbl_fsgldiv_op # DENORM / ZERO 14572 short fsgldiv_zero_load 14572 short fsgldiv_zero_load - tbl_fsgldiv_op # DENORM / INF 14573 short fsgldiv_res_qnan 14573 short fsgldiv_res_qnan - tbl_fsgldiv_op # DENORM / QNAN 14574 short fsgldiv_norm 14574 short fsgldiv_norm - tbl_fsgldiv_op # DENORM / DENORM 14575 short fsgldiv_res_snan 14575 short fsgldiv_res_snan - tbl_fsgldiv_op # DENORM / SNAN 14576 short tbl_fsgldiv_op 14576 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14577 short tbl_fsgldiv_op 14577 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14578 14578 14579 short fsgldiv_res_snan 14579 short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / NORM 14580 short fsgldiv_res_snan 14580 short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / ZERO 14581 short fsgldiv_res_snan 14581 short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / INF 14582 short fsgldiv_res_snan 14582 short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / QNAN 14583 short fsgldiv_res_snan 14583 short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / DENORM 14584 short fsgldiv_res_snan 14584 short fsgldiv_res_snan - tbl_fsgldiv_op # SNAN / SNAN 14585 short tbl_fsgldiv_op 14585 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14586 short tbl_fsgldiv_op 14586 short tbl_fsgldiv_op - tbl_fsgldiv_op # 14587 14587 14588 fsgldiv_res_qnan: 14588 fsgldiv_res_qnan: 14589 bra.l res_qnan 14589 bra.l res_qnan 14590 fsgldiv_res_snan: 14590 fsgldiv_res_snan: 14591 bra.l res_snan 14591 bra.l res_snan 14592 fsgldiv_res_operr: 14592 fsgldiv_res_operr: 14593 bra.l res_operr 14593 bra.l res_operr 14594 fsgldiv_inf_load: 14594 fsgldiv_inf_load: 14595 bra.l fdiv_inf_load 14595 bra.l fdiv_inf_load 14596 fsgldiv_zero_load: 14596 fsgldiv_zero_load: 14597 bra.l fdiv_zero_load 14597 bra.l fdiv_zero_load 14598 fsgldiv_inf_dst: 14598 fsgldiv_inf_dst: 14599 bra.l fdiv_inf_dst 14599 bra.l fdiv_inf_dst 14600 14600 14601 ############################################ 14601 ######################################################################### 14602 # XDEF ************************************* 14602 # XDEF **************************************************************** # 14603 # fadd(): emulates the fadd instructio 14603 # fadd(): emulates the fadd instruction # 14604 # fsadd(): emulates the fadd instructi 14604 # fsadd(): emulates the fadd instruction # 14605 # fdadd(): emulates the fdadd instruct 14605 # fdadd(): emulates the fdadd instruction # 14606 # 14606 # # 14607 # XREF ************************************* 14607 # XREF **************************************************************** # 14608 # addsub_scaler2() - scale the operand 14608 # addsub_scaler2() - scale the operands so they won't take exc # 14609 # ovf_res() - return default overflow 14609 # ovf_res() - return default overflow result # 14610 # unf_res() - return default underflow 14610 # unf_res() - return default underflow result # 14611 # res_qnan() - set QNAN result 14611 # res_qnan() - set QNAN result # 14612 # res_snan() - set SNAN result 14612 # res_snan() - set SNAN result # 14613 # res_operr() - set OPERR result 14613 # res_operr() - set OPERR result # 14614 # scale_to_zero_src() - set src operan 14614 # scale_to_zero_src() - set src operand exponent equal to zero # 14615 # scale_to_zero_dst() - set dst operan 14615 # scale_to_zero_dst() - set dst operand exponent equal to zero # 14616 # 14616 # # 14617 # INPUT ************************************ 14617 # INPUT *************************************************************** # 14618 # a0 = pointer to extended precision s 14618 # a0 = pointer to extended precision source operand # 14619 # a1 = pointer to extended precision d 14619 # a1 = pointer to extended precision destination operand # 14620 # 14620 # # 14621 # OUTPUT *********************************** 14621 # OUTPUT ************************************************************** # 14622 # fp0 = result 14622 # fp0 = result # 14623 # fp1 = EXOP (if exception occurred) 14623 # fp1 = EXOP (if exception occurred) # 14624 # 14624 # # 14625 # ALGORITHM ******************************** 14625 # ALGORITHM *********************************************************** # 14626 # Handle NANs, infinities, and zeroes 14626 # Handle NANs, infinities, and zeroes as special cases. Divide # 14627 # norms into extended, single, and double pr 14627 # norms into extended, single, and double precision. # 14628 # Do addition after scaling exponents 14628 # Do addition after scaling exponents such that exception won't # 14629 # occur. Then, check result exponent to see 14629 # occur. Then, check result exponent to see if exception would have # 14630 # occurred. If so, return default result and 14630 # occurred. If so, return default result and maybe EXOP. Else, insert # 14631 # the correct result exponent and return. Se 14631 # the correct result exponent and return. Set FPSR bits as appropriate. # 14632 # 14632 # # 14633 ############################################ 14633 ######################################################################### 14634 14634 14635 global fsadd 14635 global fsadd 14636 fsadd: 14636 fsadd: 14637 andi.b &0x30,%d0 14637 andi.b &0x30,%d0 # clear rnd prec 14638 ori.b &s_mode*0x10,%d0 14638 ori.b &s_mode*0x10,%d0 # insert sgl prec 14639 bra.b fadd 14639 bra.b fadd 14640 14640 14641 global fdadd 14641 global fdadd 14642 fdadd: 14642 fdadd: 14643 andi.b &0x30,%d0 14643 andi.b &0x30,%d0 # clear rnd prec 14644 ori.b &d_mode*0x10,%d0 14644 ori.b &d_mode*0x10,%d0 # insert dbl prec 14645 14645 14646 global fadd 14646 global fadd 14647 fadd: 14647 fadd: 14648 mov.l %d0,L_SCR3(%a6) 14648 mov.l %d0,L_SCR3(%a6) # store rnd info 14649 14649 14650 clr.w %d1 14650 clr.w %d1 14651 mov.b DTAG(%a6),%d1 14651 mov.b DTAG(%a6),%d1 14652 lsl.b &0x3,%d1 14652 lsl.b &0x3,%d1 14653 or.b STAG(%a6),%d1 14653 or.b STAG(%a6),%d1 # combine src tags 14654 14654 14655 bne.w fadd_not_norm 14655 bne.w fadd_not_norm # optimize on non-norm input 14656 14656 14657 # 14657 # 14658 # ADD: norms and denorms 14658 # ADD: norms and denorms 14659 # 14659 # 14660 fadd_norm: 14660 fadd_norm: 14661 bsr.l addsub_scaler2 14661 bsr.l addsub_scaler2 # scale exponents 14662 14662 14663 fadd_zero_entry: 14663 fadd_zero_entry: 14664 fmovm.x FP_SCR1(%a6),&0x80 14664 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14665 14665 14666 fmov.l &0x0,%fpsr 14666 fmov.l &0x0,%fpsr # clear FPSR 14667 fmov.l L_SCR3(%a6),%fpcr 14667 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14668 14668 14669 fadd.x FP_SCR0(%a6),%fp0 14669 fadd.x FP_SCR0(%a6),%fp0 # execute add 14670 14670 14671 fmov.l &0x0,%fpcr 14671 fmov.l &0x0,%fpcr # clear FPCR 14672 fmov.l %fpsr,%d1 14672 fmov.l %fpsr,%d1 # fetch INEX2,N,Z 14673 14673 14674 or.l %d1,USER_FPSR(%a6) 14674 or.l %d1,USER_FPSR(%a6) # save exc and ccode bits 14675 14675 14676 fbeq.w fadd_zero_exit 14676 fbeq.w fadd_zero_exit # if result is zero, end now 14677 14677 14678 mov.l %d2,-(%sp) 14678 mov.l %d2,-(%sp) # save d2 14679 14679 14680 fmovm.x &0x01,-(%sp) 14680 fmovm.x &0x01,-(%sp) # save result to stack 14681 14681 14682 mov.w 2+L_SCR3(%a6),%d1 14682 mov.w 2+L_SCR3(%a6),%d1 14683 lsr.b &0x6,%d1 14683 lsr.b &0x6,%d1 14684 14684 14685 mov.w (%sp),%d2 14685 mov.w (%sp),%d2 # fetch new sign, exp 14686 andi.l &0x7fff,%d2 14686 andi.l &0x7fff,%d2 # strip sign 14687 sub.l %d0,%d2 14687 sub.l %d0,%d2 # add scale factor 14688 14688 14689 cmp.l %d2,(tbl_fadd_ovfl.b 14689 cmp.l %d2,(tbl_fadd_ovfl.b,%pc,%d1.w*4) # is it an overflow? 14690 bge.b fadd_ovfl 14690 bge.b fadd_ovfl # yes 14691 14691 14692 cmp.l %d2,(tbl_fadd_unfl.b 14692 cmp.l %d2,(tbl_fadd_unfl.b,%pc,%d1.w*4) # is it an underflow? 14693 blt.w fadd_unfl 14693 blt.w fadd_unfl # yes 14694 beq.w fadd_may_unfl 14694 beq.w fadd_may_unfl # maybe; go find out 14695 14695 14696 fadd_normal: 14696 fadd_normal: 14697 mov.w (%sp),%d1 14697 mov.w (%sp),%d1 14698 andi.w &0x8000,%d1 14698 andi.w &0x8000,%d1 # keep sign 14699 or.w %d2,%d1 14699 or.w %d2,%d1 # concat sign,new exp 14700 mov.w %d1,(%sp) 14700 mov.w %d1,(%sp) # insert new exponent 14701 14701 14702 fmovm.x (%sp)+,&0x80 14702 fmovm.x (%sp)+,&0x80 # return result in fp0 14703 14703 14704 mov.l (%sp)+,%d2 14704 mov.l (%sp)+,%d2 # restore d2 14705 rts 14705 rts 14706 14706 14707 fadd_zero_exit: 14707 fadd_zero_exit: 14708 # fmov.s &0x00000000,%fp0 14708 # fmov.s &0x00000000,%fp0 # return zero in fp0 14709 rts 14709 rts 14710 14710 14711 tbl_fadd_ovfl: 14711 tbl_fadd_ovfl: 14712 long 0x7fff 14712 long 0x7fff # ext ovfl 14713 long 0x407f 14713 long 0x407f # sgl ovfl 14714 long 0x43ff 14714 long 0x43ff # dbl ovfl 14715 14715 14716 tbl_fadd_unfl: 14716 tbl_fadd_unfl: 14717 long 0x0000 14717 long 0x0000 # ext unfl 14718 long 0x3f81 14718 long 0x3f81 # sgl unfl 14719 long 0x3c01 14719 long 0x3c01 # dbl unfl 14720 14720 14721 fadd_ovfl: 14721 fadd_ovfl: 14722 or.l &ovfl_inx_mask,USER_ 14722 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 14723 14723 14724 mov.b FPCR_ENABLE(%a6),%d1 14724 mov.b FPCR_ENABLE(%a6),%d1 14725 andi.b &0x13,%d1 14725 andi.b &0x13,%d1 # is OVFL or INEX enabled? 14726 bne.b fadd_ovfl_ena 14726 bne.b fadd_ovfl_ena # yes 14727 14727 14728 add.l &0xc,%sp 14728 add.l &0xc,%sp 14729 fadd_ovfl_dis: 14729 fadd_ovfl_dis: 14730 btst &neg_bit,FPSR_CC(%a6 14730 btst &neg_bit,FPSR_CC(%a6) # is result negative? 14731 sne %d1 14731 sne %d1 # set sign param accordingly 14732 mov.l L_SCR3(%a6),%d0 14732 mov.l L_SCR3(%a6),%d0 # pass prec:rnd 14733 bsr.l ovf_res 14733 bsr.l ovf_res # calculate default result 14734 or.b %d0,FPSR_CC(%a6) 14734 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 14735 fmovm.x (%a0),&0x80 14735 fmovm.x (%a0),&0x80 # return default result in fp0 14736 mov.l (%sp)+,%d2 14736 mov.l (%sp)+,%d2 # restore d2 14737 rts 14737 rts 14738 14738 14739 fadd_ovfl_ena: 14739 fadd_ovfl_ena: 14740 mov.b L_SCR3(%a6),%d1 14740 mov.b L_SCR3(%a6),%d1 14741 andi.b &0xc0,%d1 14741 andi.b &0xc0,%d1 # is precision extended? 14742 bne.b fadd_ovfl_ena_sd 14742 bne.b fadd_ovfl_ena_sd # no; prec = sgl or dbl 14743 14743 14744 fadd_ovfl_ena_cont: 14744 fadd_ovfl_ena_cont: 14745 mov.w (%sp),%d1 14745 mov.w (%sp),%d1 14746 andi.w &0x8000,%d1 14746 andi.w &0x8000,%d1 # keep sign 14747 subi.l &0x6000,%d2 14747 subi.l &0x6000,%d2 # add extra bias 14748 andi.w &0x7fff,%d2 14748 andi.w &0x7fff,%d2 14749 or.w %d2,%d1 14749 or.w %d2,%d1 # concat sign,new exp 14750 mov.w %d1,(%sp) 14750 mov.w %d1,(%sp) # insert new exponent 14751 14751 14752 fmovm.x (%sp)+,&0x40 14752 fmovm.x (%sp)+,&0x40 # return EXOP in fp1 14753 bra.b fadd_ovfl_dis 14753 bra.b fadd_ovfl_dis 14754 14754 14755 fadd_ovfl_ena_sd: 14755 fadd_ovfl_ena_sd: 14756 fmovm.x FP_SCR1(%a6),&0x80 14756 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14757 14757 14758 mov.l L_SCR3(%a6),%d1 14758 mov.l L_SCR3(%a6),%d1 14759 andi.b &0x30,%d1 14759 andi.b &0x30,%d1 # keep rnd mode 14760 fmov.l %d1,%fpcr 14760 fmov.l %d1,%fpcr # set FPCR 14761 14761 14762 fadd.x FP_SCR0(%a6),%fp0 14762 fadd.x FP_SCR0(%a6),%fp0 # execute add 14763 14763 14764 fmov.l &0x0,%fpcr 14764 fmov.l &0x0,%fpcr # clear FPCR 14765 14765 14766 add.l &0xc,%sp 14766 add.l &0xc,%sp 14767 fmovm.x &0x01,-(%sp) 14767 fmovm.x &0x01,-(%sp) 14768 bra.b fadd_ovfl_ena_cont 14768 bra.b fadd_ovfl_ena_cont 14769 14769 14770 fadd_unfl: 14770 fadd_unfl: 14771 bset &unfl_bit,FPSR_EXCEP 14771 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 14772 14772 14773 add.l &0xc,%sp 14773 add.l &0xc,%sp 14774 14774 14775 fmovm.x FP_SCR1(%a6),&0x80 14775 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 14776 14776 14777 fmov.l &rz_mode*0x10,%fpcr 14777 fmov.l &rz_mode*0x10,%fpcr # set FPCR 14778 fmov.l &0x0,%fpsr 14778 fmov.l &0x0,%fpsr # clear FPSR 14779 14779 14780 fadd.x FP_SCR0(%a6),%fp0 14780 fadd.x FP_SCR0(%a6),%fp0 # execute add 14781 14781 14782 fmov.l &0x0,%fpcr 14782 fmov.l &0x0,%fpcr # clear FPCR 14783 fmov.l %fpsr,%d1 14783 fmov.l %fpsr,%d1 # save status 14784 14784 14785 or.l %d1,USER_FPSR(%a6) 14785 or.l %d1,USER_FPSR(%a6) # save INEX,N 14786 14786 14787 mov.b FPCR_ENABLE(%a6),%d1 14787 mov.b FPCR_ENABLE(%a6),%d1 14788 andi.b &0x0b,%d1 14788 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 14789 bne.b fadd_unfl_ena 14789 bne.b fadd_unfl_ena # yes 14790 14790 14791 fadd_unfl_dis: 14791 fadd_unfl_dis: 14792 fmovm.x &0x80,FP_SCR0(%a6) 14792 fmovm.x &0x80,FP_SCR0(%a6) # store out result 14793 14793 14794 lea FP_SCR0(%a6),%a0 14794 lea FP_SCR0(%a6),%a0 # pass: result addr 14795 mov.l L_SCR3(%a6),%d1 14795 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 14796 bsr.l unf_res 14796 bsr.l unf_res # calculate default result 14797 or.b %d0,FPSR_CC(%a6) 14797 or.b %d0,FPSR_CC(%a6) # 'Z' bit may have been set 14798 fmovm.x FP_SCR0(%a6),&0x80 14798 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 14799 mov.l (%sp)+,%d2 14799 mov.l (%sp)+,%d2 # restore d2 14800 rts 14800 rts 14801 14801 14802 fadd_unfl_ena: 14802 fadd_unfl_ena: 14803 fmovm.x FP_SCR1(%a6),&0x40 14803 fmovm.x FP_SCR1(%a6),&0x40 # load dst op 14804 14804 14805 mov.l L_SCR3(%a6),%d1 14805 mov.l L_SCR3(%a6),%d1 14806 andi.b &0xc0,%d1 14806 andi.b &0xc0,%d1 # is precision extended? 14807 bne.b fadd_unfl_ena_sd 14807 bne.b fadd_unfl_ena_sd # no; sgl or dbl 14808 14808 14809 fmov.l L_SCR3(%a6),%fpcr 14809 fmov.l L_SCR3(%a6),%fpcr # set FPCR 14810 14810 14811 fadd_unfl_ena_cont: 14811 fadd_unfl_ena_cont: 14812 fmov.l &0x0,%fpsr 14812 fmov.l &0x0,%fpsr # clear FPSR 14813 14813 14814 fadd.x FP_SCR0(%a6),%fp1 14814 fadd.x FP_SCR0(%a6),%fp1 # execute multiply 14815 14815 14816 fmov.l &0x0,%fpcr 14816 fmov.l &0x0,%fpcr # clear FPCR 14817 14817 14818 fmovm.x &0x40,FP_SCR0(%a6) 14818 fmovm.x &0x40,FP_SCR0(%a6) # save result to stack 14819 mov.w FP_SCR0_EX(%a6),%d1 14819 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 14820 mov.l %d1,%d2 14820 mov.l %d1,%d2 # make a copy 14821 andi.l &0x7fff,%d1 14821 andi.l &0x7fff,%d1 # strip sign 14822 andi.w &0x8000,%d2 14822 andi.w &0x8000,%d2 # keep old sign 14823 sub.l %d0,%d1 14823 sub.l %d0,%d1 # add scale factor 14824 addi.l &0x6000,%d1 14824 addi.l &0x6000,%d1 # add new bias 14825 andi.w &0x7fff,%d1 14825 andi.w &0x7fff,%d1 # clear top bit 14826 or.w %d2,%d1 14826 or.w %d2,%d1 # concat sign,new exp 14827 mov.w %d1,FP_SCR0_EX(%a6) 14827 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 14828 fmovm.x FP_SCR0(%a6),&0x40 14828 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 14829 bra.w fadd_unfl_dis 14829 bra.w fadd_unfl_dis 14830 14830 14831 fadd_unfl_ena_sd: 14831 fadd_unfl_ena_sd: 14832 mov.l L_SCR3(%a6),%d1 14832 mov.l L_SCR3(%a6),%d1 14833 andi.b &0x30,%d1 14833 andi.b &0x30,%d1 # use only rnd mode 14834 fmov.l %d1,%fpcr 14834 fmov.l %d1,%fpcr # set FPCR 14835 14835 14836 bra.b fadd_unfl_ena_cont 14836 bra.b fadd_unfl_ena_cont 14837 14837 14838 # 14838 # 14839 # result is equal to the smallest normalized 14839 # result is equal to the smallest normalized number in the selected precision 14840 # if the precision is extended, this result 14840 # if the precision is extended, this result could not have come from an 14841 # underflow that rounded up. 14841 # underflow that rounded up. 14842 # 14842 # 14843 fadd_may_unfl: 14843 fadd_may_unfl: 14844 mov.l L_SCR3(%a6),%d1 14844 mov.l L_SCR3(%a6),%d1 14845 andi.b &0xc0,%d1 14845 andi.b &0xc0,%d1 14846 beq.w fadd_normal 14846 beq.w fadd_normal # yes; no underflow occurred 14847 14847 14848 mov.l 0x4(%sp),%d1 14848 mov.l 0x4(%sp),%d1 # extract hi(man) 14849 cmpi.l %d1,&0x80000000 14849 cmpi.l %d1,&0x80000000 # is hi(man) = 0x80000000? 14850 bne.w fadd_normal 14850 bne.w fadd_normal # no; no underflow occurred 14851 14851 14852 tst.l 0x8(%sp) 14852 tst.l 0x8(%sp) # is lo(man) = 0x0? 14853 bne.w fadd_normal 14853 bne.w fadd_normal # no; no underflow occurred 14854 14854 14855 btst &inex2_bit,FPSR_EXCE 14855 btst &inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set? 14856 beq.w fadd_normal 14856 beq.w fadd_normal # no; no underflow occurred 14857 14857 14858 # 14858 # 14859 # ok, so now the result has a exponent equal 14859 # ok, so now the result has a exponent equal to the smallest normalized 14860 # exponent for the selected precision. also, 14860 # exponent for the selected precision. also, the mantissa is equal to 14861 # 0x8000000000000000 and this mantissa is th 14861 # 0x8000000000000000 and this mantissa is the result of rounding non-zero 14862 # g,r,s. 14862 # g,r,s. 14863 # now, we must determine whether the pre-rou 14863 # now, we must determine whether the pre-rounded result was an underflow 14864 # rounded "up" or a normalized number rounde 14864 # rounded "up" or a normalized number rounded "down". 14865 # so, we do this be re-executing the add usi 14865 # so, we do this be re-executing the add using RZ as the rounding mode and 14866 # seeing if the new result is smaller or equ 14866 # seeing if the new result is smaller or equal to the current result. 14867 # 14867 # 14868 fmovm.x FP_SCR1(%a6),&0x40 14868 fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1 14869 14869 14870 mov.l L_SCR3(%a6),%d1 14870 mov.l L_SCR3(%a6),%d1 14871 andi.b &0xc0,%d1 14871 andi.b &0xc0,%d1 # keep rnd prec 14872 ori.b &rz_mode*0x10,%d1 14872 ori.b &rz_mode*0x10,%d1 # insert rnd mode 14873 fmov.l %d1,%fpcr 14873 fmov.l %d1,%fpcr # set FPCR 14874 fmov.l &0x0,%fpsr 14874 fmov.l &0x0,%fpsr # clear FPSR 14875 14875 14876 fadd.x FP_SCR0(%a6),%fp1 14876 fadd.x FP_SCR0(%a6),%fp1 # execute add 14877 14877 14878 fmov.l &0x0,%fpcr 14878 fmov.l &0x0,%fpcr # clear FPCR 14879 14879 14880 fabs.x %fp0 14880 fabs.x %fp0 # compare absolute values 14881 fabs.x %fp1 14881 fabs.x %fp1 14882 fcmp.x %fp0,%fp1 14882 fcmp.x %fp0,%fp1 # is first result > second? 14883 14883 14884 fbgt.w fadd_unfl 14884 fbgt.w fadd_unfl # yes; it's an underflow 14885 bra.w fadd_normal 14885 bra.w fadd_normal # no; it's not an underflow 14886 14886 14887 ############################################ 14887 ########################################################################## 14888 14888 14889 # 14889 # 14890 # Add: inputs are not both normalized; what 14890 # Add: inputs are not both normalized; what are they? 14891 # 14891 # 14892 fadd_not_norm: 14892 fadd_not_norm: 14893 mov.w (tbl_fadd_op.b,%pc,% 14893 mov.w (tbl_fadd_op.b,%pc,%d1.w*2),%d1 14894 jmp (tbl_fadd_op.b,%pc,% 14894 jmp (tbl_fadd_op.b,%pc,%d1.w*1) 14895 14895 14896 swbeg &48 14896 swbeg &48 14897 tbl_fadd_op: 14897 tbl_fadd_op: 14898 short fadd_norm - tb 14898 short fadd_norm - tbl_fadd_op # NORM + NORM 14899 short fadd_zero_src - tb 14899 short fadd_zero_src - tbl_fadd_op # NORM + ZERO 14900 short fadd_inf_src - tb 14900 short fadd_inf_src - tbl_fadd_op # NORM + INF 14901 short fadd_res_qnan - tb 14901 short fadd_res_qnan - tbl_fadd_op # NORM + QNAN 14902 short fadd_norm - tb 14902 short fadd_norm - tbl_fadd_op # NORM + DENORM 14903 short fadd_res_snan - tb 14903 short fadd_res_snan - tbl_fadd_op # NORM + SNAN 14904 short tbl_fadd_op - tb 14904 short tbl_fadd_op - tbl_fadd_op # 14905 short tbl_fadd_op - tb 14905 short tbl_fadd_op - tbl_fadd_op # 14906 14906 14907 short fadd_zero_dst - tb 14907 short fadd_zero_dst - tbl_fadd_op # ZERO + NORM 14908 short fadd_zero_2 - tb 14908 short fadd_zero_2 - tbl_fadd_op # ZERO + ZERO 14909 short fadd_inf_src - tb 14909 short fadd_inf_src - tbl_fadd_op # ZERO + INF 14910 short fadd_res_qnan - tb 14910 short fadd_res_qnan - tbl_fadd_op # NORM + QNAN 14911 short fadd_zero_dst - tb 14911 short fadd_zero_dst - tbl_fadd_op # ZERO + DENORM 14912 short fadd_res_snan - tb 14912 short fadd_res_snan - tbl_fadd_op # NORM + SNAN 14913 short tbl_fadd_op - tb 14913 short tbl_fadd_op - tbl_fadd_op # 14914 short tbl_fadd_op - tb 14914 short tbl_fadd_op - tbl_fadd_op # 14915 14915 14916 short fadd_inf_dst - tb 14916 short fadd_inf_dst - tbl_fadd_op # INF + NORM 14917 short fadd_inf_dst - tb 14917 short fadd_inf_dst - tbl_fadd_op # INF + ZERO 14918 short fadd_inf_2 - tb 14918 short fadd_inf_2 - tbl_fadd_op # INF + INF 14919 short fadd_res_qnan - tb 14919 short fadd_res_qnan - tbl_fadd_op # NORM + QNAN 14920 short fadd_inf_dst - tb 14920 short fadd_inf_dst - tbl_fadd_op # INF + DENORM 14921 short fadd_res_snan - tb 14921 short fadd_res_snan - tbl_fadd_op # NORM + SNAN 14922 short tbl_fadd_op - tb 14922 short tbl_fadd_op - tbl_fadd_op # 14923 short tbl_fadd_op - tb 14923 short tbl_fadd_op - tbl_fadd_op # 14924 14924 14925 short fadd_res_qnan - tb 14925 short fadd_res_qnan - tbl_fadd_op # QNAN + NORM 14926 short fadd_res_qnan - tb 14926 short fadd_res_qnan - tbl_fadd_op # QNAN + ZERO 14927 short fadd_res_qnan - tb 14927 short fadd_res_qnan - tbl_fadd_op # QNAN + INF 14928 short fadd_res_qnan - tb 14928 short fadd_res_qnan - tbl_fadd_op # QNAN + QNAN 14929 short fadd_res_qnan - tb 14929 short fadd_res_qnan - tbl_fadd_op # QNAN + DENORM 14930 short fadd_res_snan - tb 14930 short fadd_res_snan - tbl_fadd_op # QNAN + SNAN 14931 short tbl_fadd_op - tb 14931 short tbl_fadd_op - tbl_fadd_op # 14932 short tbl_fadd_op - tb 14932 short tbl_fadd_op - tbl_fadd_op # 14933 14933 14934 short fadd_norm - tb 14934 short fadd_norm - tbl_fadd_op # DENORM + NORM 14935 short fadd_zero_src - tb 14935 short fadd_zero_src - tbl_fadd_op # DENORM + ZERO 14936 short fadd_inf_src - tb 14936 short fadd_inf_src - tbl_fadd_op # DENORM + INF 14937 short fadd_res_qnan - tb 14937 short fadd_res_qnan - tbl_fadd_op # NORM + QNAN 14938 short fadd_norm - tb 14938 short fadd_norm - tbl_fadd_op # DENORM + DENORM 14939 short fadd_res_snan - tb 14939 short fadd_res_snan - tbl_fadd_op # NORM + SNAN 14940 short tbl_fadd_op - tb 14940 short tbl_fadd_op - tbl_fadd_op # 14941 short tbl_fadd_op - tb 14941 short tbl_fadd_op - tbl_fadd_op # 14942 14942 14943 short fadd_res_snan - tb 14943 short fadd_res_snan - tbl_fadd_op # SNAN + NORM 14944 short fadd_res_snan - tb 14944 short fadd_res_snan - tbl_fadd_op # SNAN + ZERO 14945 short fadd_res_snan - tb 14945 short fadd_res_snan - tbl_fadd_op # SNAN + INF 14946 short fadd_res_snan - tb 14946 short fadd_res_snan - tbl_fadd_op # SNAN + QNAN 14947 short fadd_res_snan - tb 14947 short fadd_res_snan - tbl_fadd_op # SNAN + DENORM 14948 short fadd_res_snan - tb 14948 short fadd_res_snan - tbl_fadd_op # SNAN + SNAN 14949 short tbl_fadd_op - tb 14949 short tbl_fadd_op - tbl_fadd_op # 14950 short tbl_fadd_op - tb 14950 short tbl_fadd_op - tbl_fadd_op # 14951 14951 14952 fadd_res_qnan: 14952 fadd_res_qnan: 14953 bra.l res_qnan 14953 bra.l res_qnan 14954 fadd_res_snan: 14954 fadd_res_snan: 14955 bra.l res_snan 14955 bra.l res_snan 14956 14956 14957 # 14957 # 14958 # both operands are ZEROes 14958 # both operands are ZEROes 14959 # 14959 # 14960 fadd_zero_2: 14960 fadd_zero_2: 14961 mov.b SRC_EX(%a0),%d0 14961 mov.b SRC_EX(%a0),%d0 # are the signs opposite 14962 mov.b DST_EX(%a1),%d1 14962 mov.b DST_EX(%a1),%d1 14963 eor.b %d0,%d1 14963 eor.b %d0,%d1 14964 bmi.w fadd_zero_2_chk_rm 14964 bmi.w fadd_zero_2_chk_rm # weed out (-ZERO)+(+ZERO) 14965 14965 14966 # the signs are the same. so determine wheth 14966 # the signs are the same. so determine whether they are positive or negative 14967 # and return the appropriately signed zero. 14967 # and return the appropriately signed zero. 14968 tst.b %d0 14968 tst.b %d0 # are ZEROes positive or negative? 14969 bmi.b fadd_zero_rm 14969 bmi.b fadd_zero_rm # negative 14970 fmov.s &0x00000000,%fp0 14970 fmov.s &0x00000000,%fp0 # return +ZERO 14971 mov.b &z_bmask,FPSR_CC(%a6 14971 mov.b &z_bmask,FPSR_CC(%a6) # set Z 14972 rts 14972 rts 14973 14973 14974 # 14974 # 14975 # the ZEROes have opposite signs: 14975 # the ZEROes have opposite signs: 14976 # - Therefore, we return +ZERO if the roundi 14976 # - Therefore, we return +ZERO if the rounding modes are RN,RZ, or RP. 14977 # - -ZERO is returned in the case of RM. 14977 # - -ZERO is returned in the case of RM. 14978 # 14978 # 14979 fadd_zero_2_chk_rm: 14979 fadd_zero_2_chk_rm: 14980 mov.b 3+L_SCR3(%a6),%d1 14980 mov.b 3+L_SCR3(%a6),%d1 14981 andi.b &0x30,%d1 14981 andi.b &0x30,%d1 # extract rnd mode 14982 cmpi.b %d1,&rm_mode*0x10 14982 cmpi.b %d1,&rm_mode*0x10 # is rnd mode == RM? 14983 beq.b fadd_zero_rm 14983 beq.b fadd_zero_rm # yes 14984 fmov.s &0x00000000,%fp0 14984 fmov.s &0x00000000,%fp0 # return +ZERO 14985 mov.b &z_bmask,FPSR_CC(%a6 14985 mov.b &z_bmask,FPSR_CC(%a6) # set Z 14986 rts 14986 rts 14987 14987 14988 fadd_zero_rm: 14988 fadd_zero_rm: 14989 fmov.s &0x80000000,%fp0 14989 fmov.s &0x80000000,%fp0 # return -ZERO 14990 mov.b &neg_bmask+z_bmask,F 14990 mov.b &neg_bmask+z_bmask,FPSR_CC(%a6) # set NEG/Z 14991 rts 14991 rts 14992 14992 14993 # 14993 # 14994 # one operand is a ZERO and the other is a D 14994 # one operand is a ZERO and the other is a DENORM or NORM. scale 14995 # the DENORM or NORM and jump to the regular 14995 # the DENORM or NORM and jump to the regular fadd routine. 14996 # 14996 # 14997 fadd_zero_dst: 14997 fadd_zero_dst: 14998 mov.w SRC_EX(%a0),FP_SCR0_ 14998 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 14999 mov.l SRC_HI(%a0),FP_SCR0_ 14999 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 15000 mov.l SRC_LO(%a0),FP_SCR0_ 15000 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 15001 bsr.l scale_to_zero_src 15001 bsr.l scale_to_zero_src # scale the operand 15002 clr.w FP_SCR1_EX(%a6) 15002 clr.w FP_SCR1_EX(%a6) 15003 clr.l FP_SCR1_HI(%a6) 15003 clr.l FP_SCR1_HI(%a6) 15004 clr.l FP_SCR1_LO(%a6) 15004 clr.l FP_SCR1_LO(%a6) 15005 bra.w fadd_zero_entry 15005 bra.w fadd_zero_entry # go execute fadd 15006 15006 15007 fadd_zero_src: 15007 fadd_zero_src: 15008 mov.w DST_EX(%a1),FP_SCR1_ 15008 mov.w DST_EX(%a1),FP_SCR1_EX(%a6) 15009 mov.l DST_HI(%a1),FP_SCR1_ 15009 mov.l DST_HI(%a1),FP_SCR1_HI(%a6) 15010 mov.l DST_LO(%a1),FP_SCR1_ 15010 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 15011 bsr.l scale_to_zero_dst 15011 bsr.l scale_to_zero_dst # scale the operand 15012 clr.w FP_SCR0_EX(%a6) 15012 clr.w FP_SCR0_EX(%a6) 15013 clr.l FP_SCR0_HI(%a6) 15013 clr.l FP_SCR0_HI(%a6) 15014 clr.l FP_SCR0_LO(%a6) 15014 clr.l FP_SCR0_LO(%a6) 15015 bra.w fadd_zero_entry 15015 bra.w fadd_zero_entry # go execute fadd 15016 15016 15017 # 15017 # 15018 # both operands are INFs. an OPERR will resu 15018 # both operands are INFs. an OPERR will result if the INFs have 15019 # different signs. else, an INF of the same 15019 # different signs. else, an INF of the same sign is returned 15020 # 15020 # 15021 fadd_inf_2: 15021 fadd_inf_2: 15022 mov.b SRC_EX(%a0),%d0 15022 mov.b SRC_EX(%a0),%d0 # exclusive or the signs 15023 mov.b DST_EX(%a1),%d1 15023 mov.b DST_EX(%a1),%d1 15024 eor.b %d1,%d0 15024 eor.b %d1,%d0 15025 bmi.l res_operr 15025 bmi.l res_operr # weed out (-INF)+(+INF) 15026 15026 15027 # ok, so it's not an OPERR. but, we do have 15027 # ok, so it's not an OPERR. but, we do have to remember to return the 15028 # src INF since that's where the 881/882 get 15028 # src INF since that's where the 881/882 gets the j-bit from... 15029 15029 15030 # 15030 # 15031 # operands are INF and one of {ZERO, INF, DE 15031 # operands are INF and one of {ZERO, INF, DENORM, NORM} 15032 # 15032 # 15033 fadd_inf_src: 15033 fadd_inf_src: 15034 fmovm.x SRC(%a0),&0x80 15034 fmovm.x SRC(%a0),&0x80 # return src INF 15035 tst.b SRC_EX(%a0) 15035 tst.b SRC_EX(%a0) # is INF positive? 15036 bpl.b fadd_inf_done 15036 bpl.b fadd_inf_done # yes; we're done 15037 mov.b &neg_bmask+inf_bmask 15037 mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG 15038 rts 15038 rts 15039 15039 15040 # 15040 # 15041 # operands are INF and one of {ZERO, INF, DE 15041 # operands are INF and one of {ZERO, INF, DENORM, NORM} 15042 # 15042 # 15043 fadd_inf_dst: 15043 fadd_inf_dst: 15044 fmovm.x DST(%a1),&0x80 15044 fmovm.x DST(%a1),&0x80 # return dst INF 15045 tst.b DST_EX(%a1) 15045 tst.b DST_EX(%a1) # is INF positive? 15046 bpl.b fadd_inf_done 15046 bpl.b fadd_inf_done # yes; we're done 15047 mov.b &neg_bmask+inf_bmask 15047 mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG 15048 rts 15048 rts 15049 15049 15050 fadd_inf_done: 15050 fadd_inf_done: 15051 mov.b &inf_bmask,FPSR_CC(% 15051 mov.b &inf_bmask,FPSR_CC(%a6) # set INF 15052 rts 15052 rts 15053 15053 15054 ############################################ 15054 ######################################################################### 15055 # XDEF ************************************* 15055 # XDEF **************************************************************** # 15056 # fsub(): emulates the fsub instructio 15056 # fsub(): emulates the fsub instruction # 15057 # fssub(): emulates the fssub instruct 15057 # fssub(): emulates the fssub instruction # 15058 # fdsub(): emulates the fdsub instruct 15058 # fdsub(): emulates the fdsub instruction # 15059 # 15059 # # 15060 # XREF ************************************* 15060 # XREF **************************************************************** # 15061 # addsub_scaler2() - scale the operand 15061 # addsub_scaler2() - scale the operands so they won't take exc # 15062 # ovf_res() - return default overflow 15062 # ovf_res() - return default overflow result # 15063 # unf_res() - return default underflow 15063 # unf_res() - return default underflow result # 15064 # res_qnan() - set QNAN result 15064 # res_qnan() - set QNAN result # 15065 # res_snan() - set SNAN result 15065 # res_snan() - set SNAN result # 15066 # res_operr() - set OPERR result 15066 # res_operr() - set OPERR result # 15067 # scale_to_zero_src() - set src operan 15067 # scale_to_zero_src() - set src operand exponent equal to zero # 15068 # scale_to_zero_dst() - set dst operan 15068 # scale_to_zero_dst() - set dst operand exponent equal to zero # 15069 # 15069 # # 15070 # INPUT ************************************ 15070 # INPUT *************************************************************** # 15071 # a0 = pointer to extended precision s 15071 # a0 = pointer to extended precision source operand # 15072 # a1 = pointer to extended precision d 15072 # a1 = pointer to extended precision destination operand # 15073 # 15073 # # 15074 # OUTPUT *********************************** 15074 # OUTPUT ************************************************************** # 15075 # fp0 = result 15075 # fp0 = result # 15076 # fp1 = EXOP (if exception occurred) 15076 # fp1 = EXOP (if exception occurred) # 15077 # 15077 # # 15078 # ALGORITHM ******************************** 15078 # ALGORITHM *********************************************************** # 15079 # Handle NANs, infinities, and zeroes 15079 # Handle NANs, infinities, and zeroes as special cases. Divide # 15080 # norms into extended, single, and double pr 15080 # norms into extended, single, and double precision. # 15081 # Do subtraction after scaling exponen 15081 # Do subtraction after scaling exponents such that exception won't# 15082 # occur. Then, check result exponent to see 15082 # occur. Then, check result exponent to see if exception would have # 15083 # occurred. If so, return default result and 15083 # occurred. If so, return default result and maybe EXOP. Else, insert # 15084 # the correct result exponent and return. Se 15084 # the correct result exponent and return. Set FPSR bits as appropriate. # 15085 # 15085 # # 15086 ############################################ 15086 ######################################################################### 15087 15087 15088 global fssub 15088 global fssub 15089 fssub: 15089 fssub: 15090 andi.b &0x30,%d0 15090 andi.b &0x30,%d0 # clear rnd prec 15091 ori.b &s_mode*0x10,%d0 15091 ori.b &s_mode*0x10,%d0 # insert sgl prec 15092 bra.b fsub 15092 bra.b fsub 15093 15093 15094 global fdsub 15094 global fdsub 15095 fdsub: 15095 fdsub: 15096 andi.b &0x30,%d0 15096 andi.b &0x30,%d0 # clear rnd prec 15097 ori.b &d_mode*0x10,%d0 15097 ori.b &d_mode*0x10,%d0 # insert dbl prec 15098 15098 15099 global fsub 15099 global fsub 15100 fsub: 15100 fsub: 15101 mov.l %d0,L_SCR3(%a6) 15101 mov.l %d0,L_SCR3(%a6) # store rnd info 15102 15102 15103 clr.w %d1 15103 clr.w %d1 15104 mov.b DTAG(%a6),%d1 15104 mov.b DTAG(%a6),%d1 15105 lsl.b &0x3,%d1 15105 lsl.b &0x3,%d1 15106 or.b STAG(%a6),%d1 15106 or.b STAG(%a6),%d1 # combine src tags 15107 15107 15108 bne.w fsub_not_norm 15108 bne.w fsub_not_norm # optimize on non-norm input 15109 15109 15110 # 15110 # 15111 # SUB: norms and denorms 15111 # SUB: norms and denorms 15112 # 15112 # 15113 fsub_norm: 15113 fsub_norm: 15114 bsr.l addsub_scaler2 15114 bsr.l addsub_scaler2 # scale exponents 15115 15115 15116 fsub_zero_entry: 15116 fsub_zero_entry: 15117 fmovm.x FP_SCR1(%a6),&0x80 15117 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 15118 15118 15119 fmov.l &0x0,%fpsr 15119 fmov.l &0x0,%fpsr # clear FPSR 15120 fmov.l L_SCR3(%a6),%fpcr 15120 fmov.l L_SCR3(%a6),%fpcr # set FPCR 15121 15121 15122 fsub.x FP_SCR0(%a6),%fp0 15122 fsub.x FP_SCR0(%a6),%fp0 # execute subtract 15123 15123 15124 fmov.l &0x0,%fpcr 15124 fmov.l &0x0,%fpcr # clear FPCR 15125 fmov.l %fpsr,%d1 15125 fmov.l %fpsr,%d1 # fetch INEX2, N, Z 15126 15126 15127 or.l %d1,USER_FPSR(%a6) 15127 or.l %d1,USER_FPSR(%a6) # save exc and ccode bits 15128 15128 15129 fbeq.w fsub_zero_exit 15129 fbeq.w fsub_zero_exit # if result zero, end now 15130 15130 15131 mov.l %d2,-(%sp) 15131 mov.l %d2,-(%sp) # save d2 15132 15132 15133 fmovm.x &0x01,-(%sp) 15133 fmovm.x &0x01,-(%sp) # save result to stack 15134 15134 15135 mov.w 2+L_SCR3(%a6),%d1 15135 mov.w 2+L_SCR3(%a6),%d1 15136 lsr.b &0x6,%d1 15136 lsr.b &0x6,%d1 15137 15137 15138 mov.w (%sp),%d2 15138 mov.w (%sp),%d2 # fetch new exponent 15139 andi.l &0x7fff,%d2 15139 andi.l &0x7fff,%d2 # strip sign 15140 sub.l %d0,%d2 15140 sub.l %d0,%d2 # add scale factor 15141 15141 15142 cmp.l %d2,(tbl_fsub_ovfl.b 15142 cmp.l %d2,(tbl_fsub_ovfl.b,%pc,%d1.w*4) # is it an overflow? 15143 bge.b fsub_ovfl 15143 bge.b fsub_ovfl # yes 15144 15144 15145 cmp.l %d2,(tbl_fsub_unfl.b 15145 cmp.l %d2,(tbl_fsub_unfl.b,%pc,%d1.w*4) # is it an underflow? 15146 blt.w fsub_unfl 15146 blt.w fsub_unfl # yes 15147 beq.w fsub_may_unfl 15147 beq.w fsub_may_unfl # maybe; go find out 15148 15148 15149 fsub_normal: 15149 fsub_normal: 15150 mov.w (%sp),%d1 15150 mov.w (%sp),%d1 15151 andi.w &0x8000,%d1 15151 andi.w &0x8000,%d1 # keep sign 15152 or.w %d2,%d1 15152 or.w %d2,%d1 # insert new exponent 15153 mov.w %d1,(%sp) 15153 mov.w %d1,(%sp) # insert new exponent 15154 15154 15155 fmovm.x (%sp)+,&0x80 15155 fmovm.x (%sp)+,&0x80 # return result in fp0 15156 15156 15157 mov.l (%sp)+,%d2 15157 mov.l (%sp)+,%d2 # restore d2 15158 rts 15158 rts 15159 15159 15160 fsub_zero_exit: 15160 fsub_zero_exit: 15161 # fmov.s &0x00000000,%fp0 15161 # fmov.s &0x00000000,%fp0 # return zero in fp0 15162 rts 15162 rts 15163 15163 15164 tbl_fsub_ovfl: 15164 tbl_fsub_ovfl: 15165 long 0x7fff 15165 long 0x7fff # ext ovfl 15166 long 0x407f 15166 long 0x407f # sgl ovfl 15167 long 0x43ff 15167 long 0x43ff # dbl ovfl 15168 15168 15169 tbl_fsub_unfl: 15169 tbl_fsub_unfl: 15170 long 0x0000 15170 long 0x0000 # ext unfl 15171 long 0x3f81 15171 long 0x3f81 # sgl unfl 15172 long 0x3c01 15172 long 0x3c01 # dbl unfl 15173 15173 15174 fsub_ovfl: 15174 fsub_ovfl: 15175 or.l &ovfl_inx_mask,USER_ 15175 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 15176 15176 15177 mov.b FPCR_ENABLE(%a6),%d1 15177 mov.b FPCR_ENABLE(%a6),%d1 15178 andi.b &0x13,%d1 15178 andi.b &0x13,%d1 # is OVFL or INEX enabled? 15179 bne.b fsub_ovfl_ena 15179 bne.b fsub_ovfl_ena # yes 15180 15180 15181 add.l &0xc,%sp 15181 add.l &0xc,%sp 15182 fsub_ovfl_dis: 15182 fsub_ovfl_dis: 15183 btst &neg_bit,FPSR_CC(%a6 15183 btst &neg_bit,FPSR_CC(%a6) # is result negative? 15184 sne %d1 15184 sne %d1 # set sign param accordingly 15185 mov.l L_SCR3(%a6),%d0 15185 mov.l L_SCR3(%a6),%d0 # pass prec:rnd 15186 bsr.l ovf_res 15186 bsr.l ovf_res # calculate default result 15187 or.b %d0,FPSR_CC(%a6) 15187 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 15188 fmovm.x (%a0),&0x80 15188 fmovm.x (%a0),&0x80 # return default result in fp0 15189 mov.l (%sp)+,%d2 15189 mov.l (%sp)+,%d2 # restore d2 15190 rts 15190 rts 15191 15191 15192 fsub_ovfl_ena: 15192 fsub_ovfl_ena: 15193 mov.b L_SCR3(%a6),%d1 15193 mov.b L_SCR3(%a6),%d1 15194 andi.b &0xc0,%d1 15194 andi.b &0xc0,%d1 # is precision extended? 15195 bne.b fsub_ovfl_ena_sd 15195 bne.b fsub_ovfl_ena_sd # no 15196 15196 15197 fsub_ovfl_ena_cont: 15197 fsub_ovfl_ena_cont: 15198 mov.w (%sp),%d1 15198 mov.w (%sp),%d1 # fetch {sgn,exp} 15199 andi.w &0x8000,%d1 15199 andi.w &0x8000,%d1 # keep sign 15200 subi.l &0x6000,%d2 15200 subi.l &0x6000,%d2 # subtract new bias 15201 andi.w &0x7fff,%d2 15201 andi.w &0x7fff,%d2 # clear top bit 15202 or.w %d2,%d1 15202 or.w %d2,%d1 # concat sign,exp 15203 mov.w %d1,(%sp) 15203 mov.w %d1,(%sp) # insert new exponent 15204 15204 15205 fmovm.x (%sp)+,&0x40 15205 fmovm.x (%sp)+,&0x40 # return EXOP in fp1 15206 bra.b fsub_ovfl_dis 15206 bra.b fsub_ovfl_dis 15207 15207 15208 fsub_ovfl_ena_sd: 15208 fsub_ovfl_ena_sd: 15209 fmovm.x FP_SCR1(%a6),&0x80 15209 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 15210 15210 15211 mov.l L_SCR3(%a6),%d1 15211 mov.l L_SCR3(%a6),%d1 15212 andi.b &0x30,%d1 15212 andi.b &0x30,%d1 # clear rnd prec 15213 fmov.l %d1,%fpcr 15213 fmov.l %d1,%fpcr # set FPCR 15214 15214 15215 fsub.x FP_SCR0(%a6),%fp0 15215 fsub.x FP_SCR0(%a6),%fp0 # execute subtract 15216 15216 15217 fmov.l &0x0,%fpcr 15217 fmov.l &0x0,%fpcr # clear FPCR 15218 15218 15219 add.l &0xc,%sp 15219 add.l &0xc,%sp 15220 fmovm.x &0x01,-(%sp) 15220 fmovm.x &0x01,-(%sp) 15221 bra.b fsub_ovfl_ena_cont 15221 bra.b fsub_ovfl_ena_cont 15222 15222 15223 fsub_unfl: 15223 fsub_unfl: 15224 bset &unfl_bit,FPSR_EXCEP 15224 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 15225 15225 15226 add.l &0xc,%sp 15226 add.l &0xc,%sp 15227 15227 15228 fmovm.x FP_SCR1(%a6),&0x80 15228 fmovm.x FP_SCR1(%a6),&0x80 # load dst op 15229 15229 15230 fmov.l &rz_mode*0x10,%fpcr 15230 fmov.l &rz_mode*0x10,%fpcr # set FPCR 15231 fmov.l &0x0,%fpsr 15231 fmov.l &0x0,%fpsr # clear FPSR 15232 15232 15233 fsub.x FP_SCR0(%a6),%fp0 15233 fsub.x FP_SCR0(%a6),%fp0 # execute subtract 15234 15234 15235 fmov.l &0x0,%fpcr 15235 fmov.l &0x0,%fpcr # clear FPCR 15236 fmov.l %fpsr,%d1 15236 fmov.l %fpsr,%d1 # save status 15237 15237 15238 or.l %d1,USER_FPSR(%a6) 15238 or.l %d1,USER_FPSR(%a6) 15239 15239 15240 mov.b FPCR_ENABLE(%a6),%d1 15240 mov.b FPCR_ENABLE(%a6),%d1 15241 andi.b &0x0b,%d1 15241 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 15242 bne.b fsub_unfl_ena 15242 bne.b fsub_unfl_ena # yes 15243 15243 15244 fsub_unfl_dis: 15244 fsub_unfl_dis: 15245 fmovm.x &0x80,FP_SCR0(%a6) 15245 fmovm.x &0x80,FP_SCR0(%a6) # store out result 15246 15246 15247 lea FP_SCR0(%a6),%a0 15247 lea FP_SCR0(%a6),%a0 # pass: result addr 15248 mov.l L_SCR3(%a6),%d1 15248 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 15249 bsr.l unf_res 15249 bsr.l unf_res # calculate default result 15250 or.b %d0,FPSR_CC(%a6) 15250 or.b %d0,FPSR_CC(%a6) # 'Z' may have been set 15251 fmovm.x FP_SCR0(%a6),&0x80 15251 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 15252 mov.l (%sp)+,%d2 15252 mov.l (%sp)+,%d2 # restore d2 15253 rts 15253 rts 15254 15254 15255 fsub_unfl_ena: 15255 fsub_unfl_ena: 15256 fmovm.x FP_SCR1(%a6),&0x40 15256 fmovm.x FP_SCR1(%a6),&0x40 15257 15257 15258 mov.l L_SCR3(%a6),%d1 15258 mov.l L_SCR3(%a6),%d1 15259 andi.b &0xc0,%d1 15259 andi.b &0xc0,%d1 # is precision extended? 15260 bne.b fsub_unfl_ena_sd 15260 bne.b fsub_unfl_ena_sd # no 15261 15261 15262 fmov.l L_SCR3(%a6),%fpcr 15262 fmov.l L_SCR3(%a6),%fpcr # set FPCR 15263 15263 15264 fsub_unfl_ena_cont: 15264 fsub_unfl_ena_cont: 15265 fmov.l &0x0,%fpsr 15265 fmov.l &0x0,%fpsr # clear FPSR 15266 15266 15267 fsub.x FP_SCR0(%a6),%fp1 15267 fsub.x FP_SCR0(%a6),%fp1 # execute subtract 15268 15268 15269 fmov.l &0x0,%fpcr 15269 fmov.l &0x0,%fpcr # clear FPCR 15270 15270 15271 fmovm.x &0x40,FP_SCR0(%a6) 15271 fmovm.x &0x40,FP_SCR0(%a6) # store result to stack 15272 mov.w FP_SCR0_EX(%a6),%d1 15272 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 15273 mov.l %d1,%d2 15273 mov.l %d1,%d2 # make a copy 15274 andi.l &0x7fff,%d1 15274 andi.l &0x7fff,%d1 # strip sign 15275 andi.w &0x8000,%d2 15275 andi.w &0x8000,%d2 # keep old sign 15276 sub.l %d0,%d1 15276 sub.l %d0,%d1 # add scale factor 15277 addi.l &0x6000,%d1 15277 addi.l &0x6000,%d1 # subtract new bias 15278 andi.w &0x7fff,%d1 15278 andi.w &0x7fff,%d1 # clear top bit 15279 or.w %d2,%d1 15279 or.w %d2,%d1 # concat sgn,exp 15280 mov.w %d1,FP_SCR0_EX(%a6) 15280 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 15281 fmovm.x FP_SCR0(%a6),&0x40 15281 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 15282 bra.w fsub_unfl_dis 15282 bra.w fsub_unfl_dis 15283 15283 15284 fsub_unfl_ena_sd: 15284 fsub_unfl_ena_sd: 15285 mov.l L_SCR3(%a6),%d1 15285 mov.l L_SCR3(%a6),%d1 15286 andi.b &0x30,%d1 15286 andi.b &0x30,%d1 # clear rnd prec 15287 fmov.l %d1,%fpcr 15287 fmov.l %d1,%fpcr # set FPCR 15288 15288 15289 bra.b fsub_unfl_ena_cont 15289 bra.b fsub_unfl_ena_cont 15290 15290 15291 # 15291 # 15292 # result is equal to the smallest normalized 15292 # result is equal to the smallest normalized number in the selected precision 15293 # if the precision is extended, this result 15293 # if the precision is extended, this result could not have come from an 15294 # underflow that rounded up. 15294 # underflow that rounded up. 15295 # 15295 # 15296 fsub_may_unfl: 15296 fsub_may_unfl: 15297 mov.l L_SCR3(%a6),%d1 15297 mov.l L_SCR3(%a6),%d1 15298 andi.b &0xc0,%d1 15298 andi.b &0xc0,%d1 # fetch rnd prec 15299 beq.w fsub_normal 15299 beq.w fsub_normal # yes; no underflow occurred 15300 15300 15301 mov.l 0x4(%sp),%d1 15301 mov.l 0x4(%sp),%d1 15302 cmpi.l %d1,&0x80000000 15302 cmpi.l %d1,&0x80000000 # is hi(man) = 0x80000000? 15303 bne.w fsub_normal 15303 bne.w fsub_normal # no; no underflow occurred 15304 15304 15305 tst.l 0x8(%sp) 15305 tst.l 0x8(%sp) # is lo(man) = 0x0? 15306 bne.w fsub_normal 15306 bne.w fsub_normal # no; no underflow occurred 15307 15307 15308 btst &inex2_bit,FPSR_EXCE 15308 btst &inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set? 15309 beq.w fsub_normal 15309 beq.w fsub_normal # no; no underflow occurred 15310 15310 15311 # 15311 # 15312 # ok, so now the result has a exponent equal 15312 # ok, so now the result has a exponent equal to the smallest normalized 15313 # exponent for the selected precision. also, 15313 # exponent for the selected precision. also, the mantissa is equal to 15314 # 0x8000000000000000 and this mantissa is th 15314 # 0x8000000000000000 and this mantissa is the result of rounding non-zero 15315 # g,r,s. 15315 # g,r,s. 15316 # now, we must determine whether the pre-rou 15316 # now, we must determine whether the pre-rounded result was an underflow 15317 # rounded "up" or a normalized number rounde 15317 # rounded "up" or a normalized number rounded "down". 15318 # so, we do this be re-executing the add usi 15318 # so, we do this be re-executing the add using RZ as the rounding mode and 15319 # seeing if the new result is smaller or equ 15319 # seeing if the new result is smaller or equal to the current result. 15320 # 15320 # 15321 fmovm.x FP_SCR1(%a6),&0x40 15321 fmovm.x FP_SCR1(%a6),&0x40 # load dst op into fp1 15322 15322 15323 mov.l L_SCR3(%a6),%d1 15323 mov.l L_SCR3(%a6),%d1 15324 andi.b &0xc0,%d1 15324 andi.b &0xc0,%d1 # keep rnd prec 15325 ori.b &rz_mode*0x10,%d1 15325 ori.b &rz_mode*0x10,%d1 # insert rnd mode 15326 fmov.l %d1,%fpcr 15326 fmov.l %d1,%fpcr # set FPCR 15327 fmov.l &0x0,%fpsr 15327 fmov.l &0x0,%fpsr # clear FPSR 15328 15328 15329 fsub.x FP_SCR0(%a6),%fp1 15329 fsub.x FP_SCR0(%a6),%fp1 # execute subtract 15330 15330 15331 fmov.l &0x0,%fpcr 15331 fmov.l &0x0,%fpcr # clear FPCR 15332 15332 15333 fabs.x %fp0 15333 fabs.x %fp0 # compare absolute values 15334 fabs.x %fp1 15334 fabs.x %fp1 15335 fcmp.x %fp0,%fp1 15335 fcmp.x %fp0,%fp1 # is first result > second? 15336 15336 15337 fbgt.w fsub_unfl 15337 fbgt.w fsub_unfl # yes; it's an underflow 15338 bra.w fsub_normal 15338 bra.w fsub_normal # no; it's not an underflow 15339 15339 15340 ############################################ 15340 ########################################################################## 15341 15341 15342 # 15342 # 15343 # Sub: inputs are not both normalized; what 15343 # Sub: inputs are not both normalized; what are they? 15344 # 15344 # 15345 fsub_not_norm: 15345 fsub_not_norm: 15346 mov.w (tbl_fsub_op.b,%pc,% 15346 mov.w (tbl_fsub_op.b,%pc,%d1.w*2),%d1 15347 jmp (tbl_fsub_op.b,%pc,% 15347 jmp (tbl_fsub_op.b,%pc,%d1.w*1) 15348 15348 15349 swbeg &48 15349 swbeg &48 15350 tbl_fsub_op: 15350 tbl_fsub_op: 15351 short fsub_norm - tb 15351 short fsub_norm - tbl_fsub_op # NORM - NORM 15352 short fsub_zero_src - tb 15352 short fsub_zero_src - tbl_fsub_op # NORM - ZERO 15353 short fsub_inf_src - tb 15353 short fsub_inf_src - tbl_fsub_op # NORM - INF 15354 short fsub_res_qnan - tb 15354 short fsub_res_qnan - tbl_fsub_op # NORM - QNAN 15355 short fsub_norm - tb 15355 short fsub_norm - tbl_fsub_op # NORM - DENORM 15356 short fsub_res_snan - tb 15356 short fsub_res_snan - tbl_fsub_op # NORM - SNAN 15357 short tbl_fsub_op - tb 15357 short tbl_fsub_op - tbl_fsub_op # 15358 short tbl_fsub_op - tb 15358 short tbl_fsub_op - tbl_fsub_op # 15359 15359 15360 short fsub_zero_dst - tb 15360 short fsub_zero_dst - tbl_fsub_op # ZERO - NORM 15361 short fsub_zero_2 - tb 15361 short fsub_zero_2 - tbl_fsub_op # ZERO - ZERO 15362 short fsub_inf_src - tb 15362 short fsub_inf_src - tbl_fsub_op # ZERO - INF 15363 short fsub_res_qnan - tb 15363 short fsub_res_qnan - tbl_fsub_op # NORM - QNAN 15364 short fsub_zero_dst - tb 15364 short fsub_zero_dst - tbl_fsub_op # ZERO - DENORM 15365 short fsub_res_snan - tb 15365 short fsub_res_snan - tbl_fsub_op # NORM - SNAN 15366 short tbl_fsub_op - tb 15366 short tbl_fsub_op - tbl_fsub_op # 15367 short tbl_fsub_op - tb 15367 short tbl_fsub_op - tbl_fsub_op # 15368 15368 15369 short fsub_inf_dst - tb 15369 short fsub_inf_dst - tbl_fsub_op # INF - NORM 15370 short fsub_inf_dst - tb 15370 short fsub_inf_dst - tbl_fsub_op # INF - ZERO 15371 short fsub_inf_2 - tb 15371 short fsub_inf_2 - tbl_fsub_op # INF - INF 15372 short fsub_res_qnan - tb 15372 short fsub_res_qnan - tbl_fsub_op # NORM - QNAN 15373 short fsub_inf_dst - tb 15373 short fsub_inf_dst - tbl_fsub_op # INF - DENORM 15374 short fsub_res_snan - tb 15374 short fsub_res_snan - tbl_fsub_op # NORM - SNAN 15375 short tbl_fsub_op - tb 15375 short tbl_fsub_op - tbl_fsub_op # 15376 short tbl_fsub_op - tb 15376 short tbl_fsub_op - tbl_fsub_op # 15377 15377 15378 short fsub_res_qnan - tb 15378 short fsub_res_qnan - tbl_fsub_op # QNAN - NORM 15379 short fsub_res_qnan - tb 15379 short fsub_res_qnan - tbl_fsub_op # QNAN - ZERO 15380 short fsub_res_qnan - tb 15380 short fsub_res_qnan - tbl_fsub_op # QNAN - INF 15381 short fsub_res_qnan - tb 15381 short fsub_res_qnan - tbl_fsub_op # QNAN - QNAN 15382 short fsub_res_qnan - tb 15382 short fsub_res_qnan - tbl_fsub_op # QNAN - DENORM 15383 short fsub_res_snan - tb 15383 short fsub_res_snan - tbl_fsub_op # QNAN - SNAN 15384 short tbl_fsub_op - tb 15384 short tbl_fsub_op - tbl_fsub_op # 15385 short tbl_fsub_op - tb 15385 short tbl_fsub_op - tbl_fsub_op # 15386 15386 15387 short fsub_norm - tb 15387 short fsub_norm - tbl_fsub_op # DENORM - NORM 15388 short fsub_zero_src - tb 15388 short fsub_zero_src - tbl_fsub_op # DENORM - ZERO 15389 short fsub_inf_src - tb 15389 short fsub_inf_src - tbl_fsub_op # DENORM - INF 15390 short fsub_res_qnan - tb 15390 short fsub_res_qnan - tbl_fsub_op # NORM - QNAN 15391 short fsub_norm - tb 15391 short fsub_norm - tbl_fsub_op # DENORM - DENORM 15392 short fsub_res_snan - tb 15392 short fsub_res_snan - tbl_fsub_op # NORM - SNAN 15393 short tbl_fsub_op - tb 15393 short tbl_fsub_op - tbl_fsub_op # 15394 short tbl_fsub_op - tb 15394 short tbl_fsub_op - tbl_fsub_op # 15395 15395 15396 short fsub_res_snan - tb 15396 short fsub_res_snan - tbl_fsub_op # SNAN - NORM 15397 short fsub_res_snan - tb 15397 short fsub_res_snan - tbl_fsub_op # SNAN - ZERO 15398 short fsub_res_snan - tb 15398 short fsub_res_snan - tbl_fsub_op # SNAN - INF 15399 short fsub_res_snan - tb 15399 short fsub_res_snan - tbl_fsub_op # SNAN - QNAN 15400 short fsub_res_snan - tb 15400 short fsub_res_snan - tbl_fsub_op # SNAN - DENORM 15401 short fsub_res_snan - tb 15401 short fsub_res_snan - tbl_fsub_op # SNAN - SNAN 15402 short tbl_fsub_op - tb 15402 short tbl_fsub_op - tbl_fsub_op # 15403 short tbl_fsub_op - tb 15403 short tbl_fsub_op - tbl_fsub_op # 15404 15404 15405 fsub_res_qnan: 15405 fsub_res_qnan: 15406 bra.l res_qnan 15406 bra.l res_qnan 15407 fsub_res_snan: 15407 fsub_res_snan: 15408 bra.l res_snan 15408 bra.l res_snan 15409 15409 15410 # 15410 # 15411 # both operands are ZEROes 15411 # both operands are ZEROes 15412 # 15412 # 15413 fsub_zero_2: 15413 fsub_zero_2: 15414 mov.b SRC_EX(%a0),%d0 15414 mov.b SRC_EX(%a0),%d0 15415 mov.b DST_EX(%a1),%d1 15415 mov.b DST_EX(%a1),%d1 15416 eor.b %d1,%d0 15416 eor.b %d1,%d0 15417 bpl.b fsub_zero_2_chk_rm 15417 bpl.b fsub_zero_2_chk_rm 15418 15418 15419 # the signs are opposite, so, return a ZERO 15419 # the signs are opposite, so, return a ZERO w/ the sign of the dst ZERO 15420 tst.b %d0 15420 tst.b %d0 # is dst negative? 15421 bmi.b fsub_zero_2_rm 15421 bmi.b fsub_zero_2_rm # yes 15422 fmov.s &0x00000000,%fp0 15422 fmov.s &0x00000000,%fp0 # no; return +ZERO 15423 mov.b &z_bmask,FPSR_CC(%a6 15423 mov.b &z_bmask,FPSR_CC(%a6) # set Z 15424 rts 15424 rts 15425 15425 15426 # 15426 # 15427 # the ZEROes have the same signs: 15427 # the ZEROes have the same signs: 15428 # - Therefore, we return +ZERO if the roundi 15428 # - Therefore, we return +ZERO if the rounding mode is RN,RZ, or RP 15429 # - -ZERO is returned in the case of RM. 15429 # - -ZERO is returned in the case of RM. 15430 # 15430 # 15431 fsub_zero_2_chk_rm: 15431 fsub_zero_2_chk_rm: 15432 mov.b 3+L_SCR3(%a6),%d1 15432 mov.b 3+L_SCR3(%a6),%d1 15433 andi.b &0x30,%d1 15433 andi.b &0x30,%d1 # extract rnd mode 15434 cmpi.b %d1,&rm_mode*0x10 15434 cmpi.b %d1,&rm_mode*0x10 # is rnd mode = RM? 15435 beq.b fsub_zero_2_rm 15435 beq.b fsub_zero_2_rm # yes 15436 fmov.s &0x00000000,%fp0 15436 fmov.s &0x00000000,%fp0 # no; return +ZERO 15437 mov.b &z_bmask,FPSR_CC(%a6 15437 mov.b &z_bmask,FPSR_CC(%a6) # set Z 15438 rts 15438 rts 15439 15439 15440 fsub_zero_2_rm: 15440 fsub_zero_2_rm: 15441 fmov.s &0x80000000,%fp0 15441 fmov.s &0x80000000,%fp0 # return -ZERO 15442 mov.b &z_bmask+neg_bmask,F 15442 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set Z/NEG 15443 rts 15443 rts 15444 15444 15445 # 15445 # 15446 # one operand is a ZERO and the other is a D 15446 # one operand is a ZERO and the other is a DENORM or a NORM. 15447 # scale the DENORM or NORM and jump to the r 15447 # scale the DENORM or NORM and jump to the regular fsub routine. 15448 # 15448 # 15449 fsub_zero_dst: 15449 fsub_zero_dst: 15450 mov.w SRC_EX(%a0),FP_SCR0_ 15450 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 15451 mov.l SRC_HI(%a0),FP_SCR0_ 15451 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 15452 mov.l SRC_LO(%a0),FP_SCR0_ 15452 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 15453 bsr.l scale_to_zero_src 15453 bsr.l scale_to_zero_src # scale the operand 15454 clr.w FP_SCR1_EX(%a6) 15454 clr.w FP_SCR1_EX(%a6) 15455 clr.l FP_SCR1_HI(%a6) 15455 clr.l FP_SCR1_HI(%a6) 15456 clr.l FP_SCR1_LO(%a6) 15456 clr.l FP_SCR1_LO(%a6) 15457 bra.w fsub_zero_entry 15457 bra.w fsub_zero_entry # go execute fsub 15458 15458 15459 fsub_zero_src: 15459 fsub_zero_src: 15460 mov.w DST_EX(%a1),FP_SCR1_ 15460 mov.w DST_EX(%a1),FP_SCR1_EX(%a6) 15461 mov.l DST_HI(%a1),FP_SCR1_ 15461 mov.l DST_HI(%a1),FP_SCR1_HI(%a6) 15462 mov.l DST_LO(%a1),FP_SCR1_ 15462 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 15463 bsr.l scale_to_zero_dst 15463 bsr.l scale_to_zero_dst # scale the operand 15464 clr.w FP_SCR0_EX(%a6) 15464 clr.w FP_SCR0_EX(%a6) 15465 clr.l FP_SCR0_HI(%a6) 15465 clr.l FP_SCR0_HI(%a6) 15466 clr.l FP_SCR0_LO(%a6) 15466 clr.l FP_SCR0_LO(%a6) 15467 bra.w fsub_zero_entry 15467 bra.w fsub_zero_entry # go execute fsub 15468 15468 15469 # 15469 # 15470 # both operands are INFs. an OPERR will resu 15470 # both operands are INFs. an OPERR will result if the INFs have the 15471 # same signs. else, 15471 # same signs. else, 15472 # 15472 # 15473 fsub_inf_2: 15473 fsub_inf_2: 15474 mov.b SRC_EX(%a0),%d0 15474 mov.b SRC_EX(%a0),%d0 # exclusive or the signs 15475 mov.b DST_EX(%a1),%d1 15475 mov.b DST_EX(%a1),%d1 15476 eor.b %d1,%d0 15476 eor.b %d1,%d0 15477 bpl.l res_operr 15477 bpl.l res_operr # weed out (-INF)+(+INF) 15478 15478 15479 # ok, so it's not an OPERR. but we do have t 15479 # ok, so it's not an OPERR. but we do have to remember to return 15480 # the src INF since that's where the 881/882 15480 # the src INF since that's where the 881/882 gets the j-bit. 15481 15481 15482 fsub_inf_src: 15482 fsub_inf_src: 15483 fmovm.x SRC(%a0),&0x80 15483 fmovm.x SRC(%a0),&0x80 # return src INF 15484 fneg.x %fp0 15484 fneg.x %fp0 # invert sign 15485 fbge.w fsub_inf_done 15485 fbge.w fsub_inf_done # sign is now positive 15486 mov.b &neg_bmask+inf_bmask 15486 mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG 15487 rts 15487 rts 15488 15488 15489 fsub_inf_dst: 15489 fsub_inf_dst: 15490 fmovm.x DST(%a1),&0x80 15490 fmovm.x DST(%a1),&0x80 # return dst INF 15491 tst.b DST_EX(%a1) 15491 tst.b DST_EX(%a1) # is INF negative? 15492 bpl.b fsub_inf_done 15492 bpl.b fsub_inf_done # no 15493 mov.b &neg_bmask+inf_bmask 15493 mov.b &neg_bmask+inf_bmask,FPSR_CC(%a6) # set INF/NEG 15494 rts 15494 rts 15495 15495 15496 fsub_inf_done: 15496 fsub_inf_done: 15497 mov.b &inf_bmask,FPSR_CC(% 15497 mov.b &inf_bmask,FPSR_CC(%a6) # set INF 15498 rts 15498 rts 15499 15499 15500 ############################################ 15500 ######################################################################### 15501 # XDEF ************************************* 15501 # XDEF **************************************************************** # 15502 # fsqrt(): emulates the fsqrt instruct 15502 # fsqrt(): emulates the fsqrt instruction # 15503 # fssqrt(): emulates the fssqrt instru 15503 # fssqrt(): emulates the fssqrt instruction # 15504 # fdsqrt(): emulates the fdsqrt instru 15504 # fdsqrt(): emulates the fdsqrt instruction # 15505 # 15505 # # 15506 # XREF ************************************* 15506 # XREF **************************************************************** # 15507 # scale_sqrt() - scale the source oper 15507 # scale_sqrt() - scale the source operand # 15508 # unf_res() - return default underflow 15508 # unf_res() - return default underflow result # 15509 # ovf_res() - return default overflow 15509 # ovf_res() - return default overflow result # 15510 # res_qnan_1op() - return QNAN result 15510 # res_qnan_1op() - return QNAN result # 15511 # res_snan_1op() - return SNAN result 15511 # res_snan_1op() - return SNAN result # 15512 # 15512 # # 15513 # INPUT ************************************ 15513 # INPUT *************************************************************** # 15514 # a0 = pointer to extended precision s 15514 # a0 = pointer to extended precision source operand # 15515 # d0 rnd prec,mode 15515 # d0 rnd prec,mode # 15516 # 15516 # # 15517 # OUTPUT *********************************** 15517 # OUTPUT ************************************************************** # 15518 # fp0 = result 15518 # fp0 = result # 15519 # fp1 = EXOP (if exception occurred) 15519 # fp1 = EXOP (if exception occurred) # 15520 # 15520 # # 15521 # ALGORITHM ******************************** 15521 # ALGORITHM *********************************************************** # 15522 # Handle NANs, infinities, and zeroes 15522 # Handle NANs, infinities, and zeroes as special cases. Divide # 15523 # norms/denorms into ext/sgl/dbl precision. 15523 # norms/denorms into ext/sgl/dbl precision. # 15524 # For norms/denorms, scale the exponen 15524 # For norms/denorms, scale the exponents such that a sqrt # 15525 # instruction won't cause an exception. Use 15525 # instruction won't cause an exception. Use the regular fsqrt to # 15526 # compute a result. Check if the regular ope 15526 # compute a result. Check if the regular operands would have taken # 15527 # an exception. If so, return the default ov 15527 # an exception. If so, return the default overflow/underflow result # 15528 # and return the EXOP if exceptions are enab 15528 # and return the EXOP if exceptions are enabled. Else, scale the # 15529 # result operand to the proper exponent. 15529 # result operand to the proper exponent. # 15530 # 15530 # # 15531 ############################################ 15531 ######################################################################### 15532 15532 15533 global fssqrt 15533 global fssqrt 15534 fssqrt: 15534 fssqrt: 15535 andi.b &0x30,%d0 15535 andi.b &0x30,%d0 # clear rnd prec 15536 ori.b &s_mode*0x10,%d0 15536 ori.b &s_mode*0x10,%d0 # insert sgl precision 15537 bra.b fsqrt 15537 bra.b fsqrt 15538 15538 15539 global fdsqrt 15539 global fdsqrt 15540 fdsqrt: 15540 fdsqrt: 15541 andi.b &0x30,%d0 15541 andi.b &0x30,%d0 # clear rnd prec 15542 ori.b &d_mode*0x10,%d0 15542 ori.b &d_mode*0x10,%d0 # insert dbl precision 15543 15543 15544 global fsqrt 15544 global fsqrt 15545 fsqrt: 15545 fsqrt: 15546 mov.l %d0,L_SCR3(%a6) 15546 mov.l %d0,L_SCR3(%a6) # store rnd info 15547 clr.w %d1 15547 clr.w %d1 15548 mov.b STAG(%a6),%d1 15548 mov.b STAG(%a6),%d1 15549 bne.w fsqrt_not_norm 15549 bne.w fsqrt_not_norm # optimize on non-norm input 15550 15550 15551 # 15551 # 15552 # SQUARE ROOT: norms and denorms ONLY! 15552 # SQUARE ROOT: norms and denorms ONLY! 15553 # 15553 # 15554 fsqrt_norm: 15554 fsqrt_norm: 15555 tst.b SRC_EX(%a0) 15555 tst.b SRC_EX(%a0) # is operand negative? 15556 bmi.l res_operr 15556 bmi.l res_operr # yes 15557 15557 15558 andi.b &0xc0,%d0 15558 andi.b &0xc0,%d0 # is precision extended? 15559 bne.b fsqrt_not_ext 15559 bne.b fsqrt_not_ext # no; go handle sgl or dbl 15560 15560 15561 fmov.l L_SCR3(%a6),%fpcr 15561 fmov.l L_SCR3(%a6),%fpcr # set FPCR 15562 fmov.l &0x0,%fpsr 15562 fmov.l &0x0,%fpsr # clear FPSR 15563 15563 15564 fsqrt.x (%a0),%fp0 15564 fsqrt.x (%a0),%fp0 # execute square root 15565 15565 15566 fmov.l %fpsr,%d1 15566 fmov.l %fpsr,%d1 15567 or.l %d1,USER_FPSR(%a6) 15567 or.l %d1,USER_FPSR(%a6) # set N,INEX 15568 15568 15569 rts 15569 rts 15570 15570 15571 fsqrt_denorm: 15571 fsqrt_denorm: 15572 tst.b SRC_EX(%a0) 15572 tst.b SRC_EX(%a0) # is operand negative? 15573 bmi.l res_operr 15573 bmi.l res_operr # yes 15574 15574 15575 andi.b &0xc0,%d0 15575 andi.b &0xc0,%d0 # is precision extended? 15576 bne.b fsqrt_not_ext 15576 bne.b fsqrt_not_ext # no; go handle sgl or dbl 15577 15577 15578 mov.w SRC_EX(%a0),FP_SCR0_ 15578 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 15579 mov.l SRC_HI(%a0),FP_SCR0_ 15579 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 15580 mov.l SRC_LO(%a0),FP_SCR0_ 15580 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 15581 15581 15582 bsr.l scale_sqrt 15582 bsr.l scale_sqrt # calculate scale factor 15583 15583 15584 bra.w fsqrt_sd_normal 15584 bra.w fsqrt_sd_normal 15585 15585 15586 # 15586 # 15587 # operand is either single or double 15587 # operand is either single or double 15588 # 15588 # 15589 fsqrt_not_ext: 15589 fsqrt_not_ext: 15590 cmpi.b %d0,&s_mode*0x10 15590 cmpi.b %d0,&s_mode*0x10 # separate sgl/dbl prec 15591 bne.w fsqrt_dbl 15591 bne.w fsqrt_dbl 15592 15592 15593 # 15593 # 15594 # operand is to be rounded to single precisi 15594 # operand is to be rounded to single precision 15595 # 15595 # 15596 fsqrt_sgl: 15596 fsqrt_sgl: 15597 mov.w SRC_EX(%a0),FP_SCR0_ 15597 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 15598 mov.l SRC_HI(%a0),FP_SCR0_ 15598 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 15599 mov.l SRC_LO(%a0),FP_SCR0_ 15599 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 15600 15600 15601 bsr.l scale_sqrt 15601 bsr.l scale_sqrt # calculate scale factor 15602 15602 15603 cmpi.l %d0,&0x3fff-0x3f81 15603 cmpi.l %d0,&0x3fff-0x3f81 # will move in underflow? 15604 beq.w fsqrt_sd_may_unfl 15604 beq.w fsqrt_sd_may_unfl 15605 bgt.w fsqrt_sd_unfl 15605 bgt.w fsqrt_sd_unfl # yes; go handle underflow 15606 cmpi.l %d0,&0x3fff-0x407f 15606 cmpi.l %d0,&0x3fff-0x407f # will move in overflow? 15607 beq.w fsqrt_sd_may_ovfl 15607 beq.w fsqrt_sd_may_ovfl # maybe; go check 15608 blt.w fsqrt_sd_ovfl 15608 blt.w fsqrt_sd_ovfl # yes; go handle overflow 15609 15609 15610 # 15610 # 15611 # operand will NOT overflow or underflow whe 15611 # operand will NOT overflow or underflow when moved in to the fp reg file 15612 # 15612 # 15613 fsqrt_sd_normal: 15613 fsqrt_sd_normal: 15614 fmov.l &0x0,%fpsr 15614 fmov.l &0x0,%fpsr # clear FPSR 15615 fmov.l L_SCR3(%a6),%fpcr 15615 fmov.l L_SCR3(%a6),%fpcr # set FPCR 15616 15616 15617 fsqrt.x FP_SCR0(%a6),%fp0 15617 fsqrt.x FP_SCR0(%a6),%fp0 # perform absolute 15618 15618 15619 fmov.l %fpsr,%d1 15619 fmov.l %fpsr,%d1 # save FPSR 15620 fmov.l &0x0,%fpcr 15620 fmov.l &0x0,%fpcr # clear FPCR 15621 15621 15622 or.l %d1,USER_FPSR(%a6) 15622 or.l %d1,USER_FPSR(%a6) # save INEX2,N 15623 15623 15624 fsqrt_sd_normal_exit: 15624 fsqrt_sd_normal_exit: 15625 mov.l %d2,-(%sp) 15625 mov.l %d2,-(%sp) # save d2 15626 fmovm.x &0x80,FP_SCR0(%a6) 15626 fmovm.x &0x80,FP_SCR0(%a6) # store out result 15627 mov.w FP_SCR0_EX(%a6),%d1 15627 mov.w FP_SCR0_EX(%a6),%d1 # load sgn,exp 15628 mov.l %d1,%d2 15628 mov.l %d1,%d2 # make a copy 15629 andi.l &0x7fff,%d1 15629 andi.l &0x7fff,%d1 # strip sign 15630 sub.l %d0,%d1 15630 sub.l %d0,%d1 # add scale factor 15631 andi.w &0x8000,%d2 15631 andi.w &0x8000,%d2 # keep old sign 15632 or.w %d1,%d2 15632 or.w %d1,%d2 # concat old sign,new exp 15633 mov.w %d2,FP_SCR0_EX(%a6) 15633 mov.w %d2,FP_SCR0_EX(%a6) # insert new exponent 15634 mov.l (%sp)+,%d2 15634 mov.l (%sp)+,%d2 # restore d2 15635 fmovm.x FP_SCR0(%a6),&0x80 15635 fmovm.x FP_SCR0(%a6),&0x80 # return result in fp0 15636 rts 15636 rts 15637 15637 15638 # 15638 # 15639 # operand is to be rounded to double precisi 15639 # operand is to be rounded to double precision 15640 # 15640 # 15641 fsqrt_dbl: 15641 fsqrt_dbl: 15642 mov.w SRC_EX(%a0),FP_SCR0_ 15642 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 15643 mov.l SRC_HI(%a0),FP_SCR0_ 15643 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 15644 mov.l SRC_LO(%a0),FP_SCR0_ 15644 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 15645 15645 15646 bsr.l scale_sqrt 15646 bsr.l scale_sqrt # calculate scale factor 15647 15647 15648 cmpi.l %d0,&0x3fff-0x3c01 15648 cmpi.l %d0,&0x3fff-0x3c01 # will move in underflow? 15649 beq.w fsqrt_sd_may_unfl 15649 beq.w fsqrt_sd_may_unfl 15650 bgt.b fsqrt_sd_unfl 15650 bgt.b fsqrt_sd_unfl # yes; go handle underflow 15651 cmpi.l %d0,&0x3fff-0x43ff 15651 cmpi.l %d0,&0x3fff-0x43ff # will move in overflow? 15652 beq.w fsqrt_sd_may_ovfl 15652 beq.w fsqrt_sd_may_ovfl # maybe; go check 15653 blt.w fsqrt_sd_ovfl 15653 blt.w fsqrt_sd_ovfl # yes; go handle overflow 15654 bra.w fsqrt_sd_normal 15654 bra.w fsqrt_sd_normal # no; ho handle normalized op 15655 15655 15656 # we're on the line here and the distinguisi 15656 # we're on the line here and the distinguising characteristic is whether 15657 # the exponent is 3fff or 3ffe. if it's 3ffe 15657 # the exponent is 3fff or 3ffe. if it's 3ffe, then it's a safe number 15658 # elsewise fall through to underflow. 15658 # elsewise fall through to underflow. 15659 fsqrt_sd_may_unfl: 15659 fsqrt_sd_may_unfl: 15660 btst &0x0,1+FP_SCR0_EX(%a 15660 btst &0x0,1+FP_SCR0_EX(%a6) # is exponent 0x3fff? 15661 bne.w fsqrt_sd_normal 15661 bne.w fsqrt_sd_normal # yes, so no underflow 15662 15662 15663 # 15663 # 15664 # operand WILL underflow when moved in to th 15664 # operand WILL underflow when moved in to the fp register file 15665 # 15665 # 15666 fsqrt_sd_unfl: 15666 fsqrt_sd_unfl: 15667 bset &unfl_bit,FPSR_EXCEP 15667 bset &unfl_bit,FPSR_EXCEPT(%a6) # set unfl exc bit 15668 15668 15669 fmov.l &rz_mode*0x10,%fpcr 15669 fmov.l &rz_mode*0x10,%fpcr # set FPCR 15670 fmov.l &0x0,%fpsr 15670 fmov.l &0x0,%fpsr # clear FPSR 15671 15671 15672 fsqrt.x FP_SCR0(%a6),%fp0 15672 fsqrt.x FP_SCR0(%a6),%fp0 # execute square root 15673 15673 15674 fmov.l %fpsr,%d1 15674 fmov.l %fpsr,%d1 # save status 15675 fmov.l &0x0,%fpcr 15675 fmov.l &0x0,%fpcr # clear FPCR 15676 15676 15677 or.l %d1,USER_FPSR(%a6) 15677 or.l %d1,USER_FPSR(%a6) # save INEX2,N 15678 15678 15679 # if underflow or inexact is enabled, go cal 15679 # if underflow or inexact is enabled, go calculate EXOP first. 15680 mov.b FPCR_ENABLE(%a6),%d1 15680 mov.b FPCR_ENABLE(%a6),%d1 15681 andi.b &0x0b,%d1 15681 andi.b &0x0b,%d1 # is UNFL or INEX enabled? 15682 bne.b fsqrt_sd_unfl_ena 15682 bne.b fsqrt_sd_unfl_ena # yes 15683 15683 15684 fsqrt_sd_unfl_dis: 15684 fsqrt_sd_unfl_dis: 15685 fmovm.x &0x80,FP_SCR0(%a6) 15685 fmovm.x &0x80,FP_SCR0(%a6) # store out result 15686 15686 15687 lea FP_SCR0(%a6),%a0 15687 lea FP_SCR0(%a6),%a0 # pass: result addr 15688 mov.l L_SCR3(%a6),%d1 15688 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 15689 bsr.l unf_res 15689 bsr.l unf_res # calculate default result 15690 or.b %d0,FPSR_CC(%a6) 15690 or.b %d0,FPSR_CC(%a6) # set possible 'Z' ccode 15691 fmovm.x FP_SCR0(%a6),&0x80 15691 fmovm.x FP_SCR0(%a6),&0x80 # return default result in fp0 15692 rts 15692 rts 15693 15693 15694 # 15694 # 15695 # operand will underflow AND underflow is en 15695 # operand will underflow AND underflow is enabled. 15696 # Therefore, we must return the result round 15696 # Therefore, we must return the result rounded to extended precision. 15697 # 15697 # 15698 fsqrt_sd_unfl_ena: 15698 fsqrt_sd_unfl_ena: 15699 mov.l FP_SCR0_HI(%a6),FP_S 15699 mov.l FP_SCR0_HI(%a6),FP_SCR1_HI(%a6) 15700 mov.l FP_SCR0_LO(%a6),FP_S 15700 mov.l FP_SCR0_LO(%a6),FP_SCR1_LO(%a6) 15701 mov.w FP_SCR0_EX(%a6),%d1 15701 mov.w FP_SCR0_EX(%a6),%d1 # load current exponent 15702 15702 15703 mov.l %d2,-(%sp) 15703 mov.l %d2,-(%sp) # save d2 15704 mov.l %d1,%d2 15704 mov.l %d1,%d2 # make a copy 15705 andi.l &0x7fff,%d1 15705 andi.l &0x7fff,%d1 # strip sign 15706 andi.w &0x8000,%d2 15706 andi.w &0x8000,%d2 # keep old sign 15707 sub.l %d0,%d1 15707 sub.l %d0,%d1 # subtract scale factor 15708 addi.l &0x6000,%d1 15708 addi.l &0x6000,%d1 # add new bias 15709 andi.w &0x7fff,%d1 15709 andi.w &0x7fff,%d1 15710 or.w %d2,%d1 15710 or.w %d2,%d1 # concat new sign,new exp 15711 mov.w %d1,FP_SCR1_EX(%a6) 15711 mov.w %d1,FP_SCR1_EX(%a6) # insert new exp 15712 fmovm.x FP_SCR1(%a6),&0x40 15712 fmovm.x FP_SCR1(%a6),&0x40 # return EXOP in fp1 15713 mov.l (%sp)+,%d2 15713 mov.l (%sp)+,%d2 # restore d2 15714 bra.b fsqrt_sd_unfl_dis 15714 bra.b fsqrt_sd_unfl_dis 15715 15715 15716 # 15716 # 15717 # operand WILL overflow. 15717 # operand WILL overflow. 15718 # 15718 # 15719 fsqrt_sd_ovfl: 15719 fsqrt_sd_ovfl: 15720 fmov.l &0x0,%fpsr 15720 fmov.l &0x0,%fpsr # clear FPSR 15721 fmov.l L_SCR3(%a6),%fpcr 15721 fmov.l L_SCR3(%a6),%fpcr # set FPCR 15722 15722 15723 fsqrt.x FP_SCR0(%a6),%fp0 15723 fsqrt.x FP_SCR0(%a6),%fp0 # perform square root 15724 15724 15725 fmov.l &0x0,%fpcr 15725 fmov.l &0x0,%fpcr # clear FPCR 15726 fmov.l %fpsr,%d1 15726 fmov.l %fpsr,%d1 # save FPSR 15727 15727 15728 or.l %d1,USER_FPSR(%a6) 15728 or.l %d1,USER_FPSR(%a6) # save INEX2,N 15729 15729 15730 fsqrt_sd_ovfl_tst: 15730 fsqrt_sd_ovfl_tst: 15731 or.l &ovfl_inx_mask,USER_ 15731 or.l &ovfl_inx_mask,USER_FPSR(%a6) # set ovfl/aovfl/ainex 15732 15732 15733 mov.b FPCR_ENABLE(%a6),%d1 15733 mov.b FPCR_ENABLE(%a6),%d1 15734 andi.b &0x13,%d1 15734 andi.b &0x13,%d1 # is OVFL or INEX enabled? 15735 bne.b fsqrt_sd_ovfl_ena 15735 bne.b fsqrt_sd_ovfl_ena # yes 15736 15736 15737 # 15737 # 15738 # OVFL is not enabled; therefore, we must cr 15738 # OVFL is not enabled; therefore, we must create the default result by 15739 # calling ovf_res(). 15739 # calling ovf_res(). 15740 # 15740 # 15741 fsqrt_sd_ovfl_dis: 15741 fsqrt_sd_ovfl_dis: 15742 btst &neg_bit,FPSR_CC(%a6 15742 btst &neg_bit,FPSR_CC(%a6) # is result negative? 15743 sne %d1 15743 sne %d1 # set sign param accordingly 15744 mov.l L_SCR3(%a6),%d0 15744 mov.l L_SCR3(%a6),%d0 # pass: prec,mode 15745 bsr.l ovf_res 15745 bsr.l ovf_res # calculate default result 15746 or.b %d0,FPSR_CC(%a6) 15746 or.b %d0,FPSR_CC(%a6) # set INF,N if applicable 15747 fmovm.x (%a0),&0x80 15747 fmovm.x (%a0),&0x80 # return default result in fp0 15748 rts 15748 rts 15749 15749 15750 # 15750 # 15751 # OVFL is enabled. 15751 # OVFL is enabled. 15752 # the INEX2 bit has already been updated by 15752 # the INEX2 bit has already been updated by the round to the correct precision. 15753 # now, round to extended(and don't alter the 15753 # now, round to extended(and don't alter the FPSR). 15754 # 15754 # 15755 fsqrt_sd_ovfl_ena: 15755 fsqrt_sd_ovfl_ena: 15756 mov.l %d2,-(%sp) 15756 mov.l %d2,-(%sp) # save d2 15757 mov.w FP_SCR0_EX(%a6),%d1 15757 mov.w FP_SCR0_EX(%a6),%d1 # fetch {sgn,exp} 15758 mov.l %d1,%d2 15758 mov.l %d1,%d2 # make a copy 15759 andi.l &0x7fff,%d1 15759 andi.l &0x7fff,%d1 # strip sign 15760 andi.w &0x8000,%d2 15760 andi.w &0x8000,%d2 # keep old sign 15761 sub.l %d0,%d1 15761 sub.l %d0,%d1 # add scale factor 15762 subi.l &0x6000,%d1 15762 subi.l &0x6000,%d1 # subtract bias 15763 andi.w &0x7fff,%d1 15763 andi.w &0x7fff,%d1 15764 or.w %d2,%d1 15764 or.w %d2,%d1 # concat sign,exp 15765 mov.w %d1,FP_SCR0_EX(%a6) 15765 mov.w %d1,FP_SCR0_EX(%a6) # insert new exponent 15766 fmovm.x FP_SCR0(%a6),&0x40 15766 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 15767 mov.l (%sp)+,%d2 15767 mov.l (%sp)+,%d2 # restore d2 15768 bra.b fsqrt_sd_ovfl_dis 15768 bra.b fsqrt_sd_ovfl_dis 15769 15769 15770 # 15770 # 15771 # the move in MAY underflow. so... 15771 # the move in MAY underflow. so... 15772 # 15772 # 15773 fsqrt_sd_may_ovfl: 15773 fsqrt_sd_may_ovfl: 15774 btst &0x0,1+FP_SCR0_EX(%a 15774 btst &0x0,1+FP_SCR0_EX(%a6) # is exponent 0x3fff? 15775 bne.w fsqrt_sd_ovfl 15775 bne.w fsqrt_sd_ovfl # yes, so overflow 15776 15776 15777 fmov.l &0x0,%fpsr 15777 fmov.l &0x0,%fpsr # clear FPSR 15778 fmov.l L_SCR3(%a6),%fpcr 15778 fmov.l L_SCR3(%a6),%fpcr # set FPCR 15779 15779 15780 fsqrt.x FP_SCR0(%a6),%fp0 15780 fsqrt.x FP_SCR0(%a6),%fp0 # perform absolute 15781 15781 15782 fmov.l %fpsr,%d1 15782 fmov.l %fpsr,%d1 # save status 15783 fmov.l &0x0,%fpcr 15783 fmov.l &0x0,%fpcr # clear FPCR 15784 15784 15785 or.l %d1,USER_FPSR(%a6) 15785 or.l %d1,USER_FPSR(%a6) # save INEX2,N 15786 15786 15787 fmov.x %fp0,%fp1 15787 fmov.x %fp0,%fp1 # make a copy of result 15788 fcmp.b %fp1,&0x1 15788 fcmp.b %fp1,&0x1 # is |result| >= 1.b? 15789 fbge.w fsqrt_sd_ovfl_tst 15789 fbge.w fsqrt_sd_ovfl_tst # yes; overflow has occurred 15790 15790 15791 # no, it didn't overflow; we have correct re 15791 # no, it didn't overflow; we have correct result 15792 bra.w fsqrt_sd_normal_exit 15792 bra.w fsqrt_sd_normal_exit 15793 15793 15794 ############################################ 15794 ########################################################################## 15795 15795 15796 # 15796 # 15797 # input is not normalized; what is it? 15797 # input is not normalized; what is it? 15798 # 15798 # 15799 fsqrt_not_norm: 15799 fsqrt_not_norm: 15800 cmpi.b %d1,&DENORM 15800 cmpi.b %d1,&DENORM # weed out DENORM 15801 beq.w fsqrt_denorm 15801 beq.w fsqrt_denorm 15802 cmpi.b %d1,&ZERO 15802 cmpi.b %d1,&ZERO # weed out ZERO 15803 beq.b fsqrt_zero 15803 beq.b fsqrt_zero 15804 cmpi.b %d1,&INF 15804 cmpi.b %d1,&INF # weed out INF 15805 beq.b fsqrt_inf 15805 beq.b fsqrt_inf 15806 cmpi.b %d1,&SNAN 15806 cmpi.b %d1,&SNAN # weed out SNAN 15807 beq.l res_snan_1op 15807 beq.l res_snan_1op 15808 bra.l res_qnan_1op 15808 bra.l res_qnan_1op 15809 15809 15810 # 15810 # 15811 # fsqrt(+0) = +0 15811 # fsqrt(+0) = +0 15812 # fsqrt(-0) = -0 15812 # fsqrt(-0) = -0 15813 # fsqrt(+INF) = +INF 15813 # fsqrt(+INF) = +INF 15814 # fsqrt(-INF) = OPERR 15814 # fsqrt(-INF) = OPERR 15815 # 15815 # 15816 fsqrt_zero: 15816 fsqrt_zero: 15817 tst.b SRC_EX(%a0) 15817 tst.b SRC_EX(%a0) # is ZERO positive or negative? 15818 bmi.b fsqrt_zero_m 15818 bmi.b fsqrt_zero_m # negative 15819 fsqrt_zero_p: 15819 fsqrt_zero_p: 15820 fmov.s &0x00000000,%fp0 15820 fmov.s &0x00000000,%fp0 # return +ZERO 15821 mov.b &z_bmask,FPSR_CC(%a6 15821 mov.b &z_bmask,FPSR_CC(%a6) # set 'Z' ccode bit 15822 rts 15822 rts 15823 fsqrt_zero_m: 15823 fsqrt_zero_m: 15824 fmov.s &0x80000000,%fp0 15824 fmov.s &0x80000000,%fp0 # return -ZERO 15825 mov.b &z_bmask+neg_bmask,F 15825 mov.b &z_bmask+neg_bmask,FPSR_CC(%a6) # set 'Z','N' ccode bits 15826 rts 15826 rts 15827 15827 15828 fsqrt_inf: 15828 fsqrt_inf: 15829 tst.b SRC_EX(%a0) 15829 tst.b SRC_EX(%a0) # is INF positive or negative? 15830 bmi.l res_operr 15830 bmi.l res_operr # negative 15831 fsqrt_inf_p: 15831 fsqrt_inf_p: 15832 fmovm.x SRC(%a0),&0x80 15832 fmovm.x SRC(%a0),&0x80 # return +INF in fp0 15833 mov.b &inf_bmask,FPSR_CC(% 15833 mov.b &inf_bmask,FPSR_CC(%a6) # set 'I' ccode bit 15834 rts 15834 rts 15835 15835 15836 ############################################ 15836 ########################################################################## 15837 15837 15838 ############################################ 15838 ######################################################################### 15839 # XDEF ************************************* 15839 # XDEF **************************************************************** # 15840 # addsub_scaler2(): scale inputs to fa 15840 # addsub_scaler2(): scale inputs to fadd/fsub such that no # 15841 # OVFL/UNFL exceptio 15841 # OVFL/UNFL exceptions will result # 15842 # 15842 # # 15843 # XREF ************************************* 15843 # XREF **************************************************************** # 15844 # norm() - normalize mantissa after ad 15844 # norm() - normalize mantissa after adjusting exponent # 15845 # 15845 # # 15846 # INPUT ************************************ 15846 # INPUT *************************************************************** # 15847 # FP_SRC(a6) = fp op1(src) 15847 # FP_SRC(a6) = fp op1(src) # 15848 # FP_DST(a6) = fp op2(dst) 15848 # FP_DST(a6) = fp op2(dst) # 15849 # 15849 # # 15850 # OUTPUT *********************************** 15850 # OUTPUT ************************************************************** # 15851 # FP_SRC(a6) = fp op1 scaled(src) 15851 # FP_SRC(a6) = fp op1 scaled(src) # 15852 # FP_DST(a6) = fp op2 scaled(dst) 15852 # FP_DST(a6) = fp op2 scaled(dst) # 15853 # d0 = scale amount 15853 # d0 = scale amount # 15854 # 15854 # # 15855 # ALGORITHM ******************************** 15855 # ALGORITHM *********************************************************** # 15856 # If the DST exponent is > the SRC exp 15856 # If the DST exponent is > the SRC exponent, set the DST exponent # 15857 # equal to 0x3fff and scale the SRC exponent 15857 # equal to 0x3fff and scale the SRC exponent by the value that the # 15858 # DST exponent was scaled by. If the SRC exp 15858 # DST exponent was scaled by. If the SRC exponent is greater or equal, # 15859 # do the opposite. Return this scale factor 15859 # do the opposite. Return this scale factor in d0. # 15860 # If the two exponents differ by > the 15860 # If the two exponents differ by > the number of mantissa bits # 15861 # plus two, then set the smallest exponent t 15861 # plus two, then set the smallest exponent to a very small value as a # 15862 # quick shortcut. 15862 # quick shortcut. # 15863 # 15863 # # 15864 ############################################ 15864 ######################################################################### 15865 15865 15866 global addsub_scaler2 15866 global addsub_scaler2 15867 addsub_scaler2: 15867 addsub_scaler2: 15868 mov.l SRC_HI(%a0),FP_SCR0_ 15868 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 15869 mov.l DST_HI(%a1),FP_SCR1_ 15869 mov.l DST_HI(%a1),FP_SCR1_HI(%a6) 15870 mov.l SRC_LO(%a0),FP_SCR0_ 15870 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 15871 mov.l DST_LO(%a1),FP_SCR1_ 15871 mov.l DST_LO(%a1),FP_SCR1_LO(%a6) 15872 mov.w SRC_EX(%a0),%d0 15872 mov.w SRC_EX(%a0),%d0 15873 mov.w DST_EX(%a1),%d1 15873 mov.w DST_EX(%a1),%d1 15874 mov.w %d0,FP_SCR0_EX(%a6) 15874 mov.w %d0,FP_SCR0_EX(%a6) 15875 mov.w %d1,FP_SCR1_EX(%a6) 15875 mov.w %d1,FP_SCR1_EX(%a6) 15876 15876 15877 andi.w &0x7fff,%d0 15877 andi.w &0x7fff,%d0 15878 andi.w &0x7fff,%d1 15878 andi.w &0x7fff,%d1 15879 mov.w %d0,L_SCR1(%a6) 15879 mov.w %d0,L_SCR1(%a6) # store src exponent 15880 mov.w %d1,2+L_SCR1(%a6) 15880 mov.w %d1,2+L_SCR1(%a6) # store dst exponent 15881 15881 15882 cmp.w %d0, %d1 15882 cmp.w %d0, %d1 # is src exp >= dst exp? 15883 bge.l src_exp_ge2 15883 bge.l src_exp_ge2 15884 15884 15885 # dst exp is > src exp; scale dst to exp = 15885 # dst exp is > src exp; scale dst to exp = 0x3fff 15886 dst_exp_gt2: 15886 dst_exp_gt2: 15887 bsr.l scale_to_zero_dst 15887 bsr.l scale_to_zero_dst 15888 mov.l %d0,-(%sp) 15888 mov.l %d0,-(%sp) # save scale factor 15889 15889 15890 cmpi.b STAG(%a6),&DENORM 15890 cmpi.b STAG(%a6),&DENORM # is dst denormalized? 15891 bne.b cmpexp12 15891 bne.b cmpexp12 15892 15892 15893 lea FP_SCR0(%a6),%a0 15893 lea FP_SCR0(%a6),%a0 15894 bsr.l norm 15894 bsr.l norm # normalize the denorm; result is new exp 15895 neg.w %d0 15895 neg.w %d0 # new exp = -(shft val) 15896 mov.w %d0,L_SCR1(%a6) 15896 mov.w %d0,L_SCR1(%a6) # inset new exp 15897 15897 15898 cmpexp12: 15898 cmpexp12: 15899 mov.w 2+L_SCR1(%a6),%d0 15899 mov.w 2+L_SCR1(%a6),%d0 15900 subi.w &mantissalen+2,%d0 15900 subi.w &mantissalen+2,%d0 # subtract mantissalen+2 from larger exp 15901 15901 15902 cmp.w %d0,L_SCR1(%a6) 15902 cmp.w %d0,L_SCR1(%a6) # is difference >= len(mantissa)+2? 15903 bge.b quick_scale12 15903 bge.b quick_scale12 15904 15904 15905 mov.w L_SCR1(%a6),%d0 15905 mov.w L_SCR1(%a6),%d0 15906 add.w 0x2(%sp),%d0 15906 add.w 0x2(%sp),%d0 # scale src exponent by scale factor 15907 mov.w FP_SCR0_EX(%a6),%d1 15907 mov.w FP_SCR0_EX(%a6),%d1 15908 and.w &0x8000,%d1 15908 and.w &0x8000,%d1 15909 or.w %d1,%d0 15909 or.w %d1,%d0 # concat {sgn,new exp} 15910 mov.w %d0,FP_SCR0_EX(%a6) 15910 mov.w %d0,FP_SCR0_EX(%a6) # insert new dst exponent 15911 15911 15912 mov.l (%sp)+,%d0 15912 mov.l (%sp)+,%d0 # return SCALE factor 15913 rts 15913 rts 15914 15914 15915 quick_scale12: 15915 quick_scale12: 15916 andi.w &0x8000,FP_SCR0_EX(% 15916 andi.w &0x8000,FP_SCR0_EX(%a6) # zero src exponent 15917 bset &0x0,1+FP_SCR0_EX(%a 15917 bset &0x0,1+FP_SCR0_EX(%a6) # set exp = 1 15918 15918 15919 mov.l (%sp)+,%d0 15919 mov.l (%sp)+,%d0 # return SCALE factor 15920 rts 15920 rts 15921 15921 15922 # src exp is >= dst exp; scale src to exp = 15922 # src exp is >= dst exp; scale src to exp = 0x3fff 15923 src_exp_ge2: 15923 src_exp_ge2: 15924 bsr.l scale_to_zero_src 15924 bsr.l scale_to_zero_src 15925 mov.l %d0,-(%sp) 15925 mov.l %d0,-(%sp) # save scale factor 15926 15926 15927 cmpi.b DTAG(%a6),&DENORM 15927 cmpi.b DTAG(%a6),&DENORM # is dst denormalized? 15928 bne.b cmpexp22 15928 bne.b cmpexp22 15929 lea FP_SCR1(%a6),%a0 15929 lea FP_SCR1(%a6),%a0 15930 bsr.l norm 15930 bsr.l norm # normalize the denorm; result is new exp 15931 neg.w %d0 15931 neg.w %d0 # new exp = -(shft val) 15932 mov.w %d0,2+L_SCR1(%a6) 15932 mov.w %d0,2+L_SCR1(%a6) # inset new exp 15933 15933 15934 cmpexp22: 15934 cmpexp22: 15935 mov.w L_SCR1(%a6),%d0 15935 mov.w L_SCR1(%a6),%d0 15936 subi.w &mantissalen+2,%d0 15936 subi.w &mantissalen+2,%d0 # subtract mantissalen+2 from larger exp 15937 15937 15938 cmp.w %d0,2+L_SCR1(%a6) 15938 cmp.w %d0,2+L_SCR1(%a6) # is difference >= len(mantissa)+2? 15939 bge.b quick_scale22 15939 bge.b quick_scale22 15940 15940 15941 mov.w 2+L_SCR1(%a6),%d0 15941 mov.w 2+L_SCR1(%a6),%d0 15942 add.w 0x2(%sp),%d0 15942 add.w 0x2(%sp),%d0 # scale dst exponent by scale factor 15943 mov.w FP_SCR1_EX(%a6),%d1 15943 mov.w FP_SCR1_EX(%a6),%d1 15944 andi.w &0x8000,%d1 15944 andi.w &0x8000,%d1 15945 or.w %d1,%d0 15945 or.w %d1,%d0 # concat {sgn,new exp} 15946 mov.w %d0,FP_SCR1_EX(%a6) 15946 mov.w %d0,FP_SCR1_EX(%a6) # insert new dst exponent 15947 15947 15948 mov.l (%sp)+,%d0 15948 mov.l (%sp)+,%d0 # return SCALE factor 15949 rts 15949 rts 15950 15950 15951 quick_scale22: 15951 quick_scale22: 15952 andi.w &0x8000,FP_SCR1_EX(% 15952 andi.w &0x8000,FP_SCR1_EX(%a6) # zero dst exponent 15953 bset &0x0,1+FP_SCR1_EX(%a 15953 bset &0x0,1+FP_SCR1_EX(%a6) # set exp = 1 15954 15954 15955 mov.l (%sp)+,%d0 15955 mov.l (%sp)+,%d0 # return SCALE factor 15956 rts 15956 rts 15957 15957 15958 ############################################ 15958 ########################################################################## 15959 15959 15960 ############################################ 15960 ######################################################################### 15961 # XDEF ************************************* 15961 # XDEF **************************************************************** # 15962 # scale_to_zero_src(): scale the expon 15962 # scale_to_zero_src(): scale the exponent of extended precision # 15963 # value at FP_SCR 15963 # value at FP_SCR0(a6). # 15964 # 15964 # # 15965 # XREF ************************************* 15965 # XREF **************************************************************** # 15966 # norm() - normalize the mantissa if t 15966 # norm() - normalize the mantissa if the operand was a DENORM # 15967 # 15967 # # 15968 # INPUT ************************************ 15968 # INPUT *************************************************************** # 15969 # FP_SCR0(a6) = extended precision ope 15969 # FP_SCR0(a6) = extended precision operand to be scaled # 15970 # 15970 # # 15971 # OUTPUT *********************************** 15971 # OUTPUT ************************************************************** # 15972 # FP_SCR0(a6) = scaled extended precis 15972 # FP_SCR0(a6) = scaled extended precision operand # 15973 # d0 = scale value 15973 # d0 = scale value # 15974 # 15974 # # 15975 # ALGORITHM ******************************** 15975 # ALGORITHM *********************************************************** # 15976 # Set the exponent of the input operan 15976 # Set the exponent of the input operand to 0x3fff. Save the value # 15977 # of the difference between the original and 15977 # of the difference between the original and new exponent. Then, # 15978 # normalize the operand if it was a DENORM. 15978 # normalize the operand if it was a DENORM. Add this normalization # 15979 # value to the previous value. Return the re 15979 # value to the previous value. Return the result. # 15980 # 15980 # # 15981 ############################################ 15981 ######################################################################### 15982 15982 15983 global scale_to_zero_src 15983 global scale_to_zero_src 15984 scale_to_zero_src: 15984 scale_to_zero_src: 15985 mov.w FP_SCR0_EX(%a6),%d1 15985 mov.w FP_SCR0_EX(%a6),%d1 # extract operand's {sgn,exp} 15986 mov.w %d1,%d0 15986 mov.w %d1,%d0 # make a copy 15987 15987 15988 andi.l &0x7fff,%d1 15988 andi.l &0x7fff,%d1 # extract operand's exponent 15989 15989 15990 andi.w &0x8000,%d0 15990 andi.w &0x8000,%d0 # extract operand's sgn 15991 or.w &0x3fff,%d0 15991 or.w &0x3fff,%d0 # insert new operand's exponent(=0) 15992 15992 15993 mov.w %d0,FP_SCR0_EX(%a6) 15993 mov.w %d0,FP_SCR0_EX(%a6) # insert biased exponent 15994 15994 15995 cmpi.b STAG(%a6),&DENORM 15995 cmpi.b STAG(%a6),&DENORM # is operand normalized? 15996 beq.b stzs_denorm 15996 beq.b stzs_denorm # normalize the DENORM 15997 15997 15998 stzs_norm: 15998 stzs_norm: 15999 mov.l &0x3fff,%d0 15999 mov.l &0x3fff,%d0 16000 sub.l %d1,%d0 16000 sub.l %d1,%d0 # scale = BIAS + (-exp) 16001 16001 16002 rts 16002 rts 16003 16003 16004 stzs_denorm: 16004 stzs_denorm: 16005 lea FP_SCR0(%a6),%a0 16005 lea FP_SCR0(%a6),%a0 # pass ptr to src op 16006 bsr.l norm 16006 bsr.l norm # normalize denorm 16007 neg.l %d0 16007 neg.l %d0 # new exponent = -(shft val) 16008 mov.l %d0,%d1 16008 mov.l %d0,%d1 # prepare for op_norm call 16009 bra.b stzs_norm 16009 bra.b stzs_norm # finish scaling 16010 16010 16011 ### 16011 ### 16012 16012 16013 ############################################ 16013 ######################################################################### 16014 # XDEF ************************************* 16014 # XDEF **************************************************************** # 16015 # scale_sqrt(): scale the input operan 16015 # scale_sqrt(): scale the input operand exponent so a subsequent # 16016 # fsqrt operation won't 16016 # fsqrt operation won't take an exception. # 16017 # 16017 # # 16018 # XREF ************************************* 16018 # XREF **************************************************************** # 16019 # norm() - normalize the mantissa if t 16019 # norm() - normalize the mantissa if the operand was a DENORM # 16020 # 16020 # # 16021 # INPUT ************************************ 16021 # INPUT *************************************************************** # 16022 # FP_SCR0(a6) = extended precision ope 16022 # FP_SCR0(a6) = extended precision operand to be scaled # 16023 # 16023 # # 16024 # OUTPUT *********************************** 16024 # OUTPUT ************************************************************** # 16025 # FP_SCR0(a6) = scaled extended precis 16025 # FP_SCR0(a6) = scaled extended precision operand # 16026 # d0 = scale value 16026 # d0 = scale value # 16027 # 16027 # # 16028 # ALGORITHM ******************************** 16028 # ALGORITHM *********************************************************** # 16029 # If the input operand is a DENORM, no 16029 # If the input operand is a DENORM, normalize it. # 16030 # If the exponent of the input operand 16030 # If the exponent of the input operand is even, set the exponent # 16031 # to 0x3ffe and return a scale factor of "(e 16031 # to 0x3ffe and return a scale factor of "(exp-0x3ffe)/2". If the # 16032 # exponent of the input operand is off, set 16032 # exponent of the input operand is off, set the exponent to ox3fff and # 16033 # return a scale factor of "(exp-0x3fff)/2". 16033 # return a scale factor of "(exp-0x3fff)/2". # 16034 # 16034 # # 16035 ############################################ 16035 ######################################################################### 16036 16036 16037 global scale_sqrt 16037 global scale_sqrt 16038 scale_sqrt: 16038 scale_sqrt: 16039 cmpi.b STAG(%a6),&DENORM 16039 cmpi.b STAG(%a6),&DENORM # is operand normalized? 16040 beq.b ss_denorm 16040 beq.b ss_denorm # normalize the DENORM 16041 16041 16042 mov.w FP_SCR0_EX(%a6),%d1 16042 mov.w FP_SCR0_EX(%a6),%d1 # extract operand's {sgn,exp} 16043 andi.l &0x7fff,%d1 16043 andi.l &0x7fff,%d1 # extract operand's exponent 16044 16044 16045 andi.w &0x8000,FP_SCR0_EX(% 16045 andi.w &0x8000,FP_SCR0_EX(%a6) # extract operand's sgn 16046 16046 16047 btst &0x0,%d1 16047 btst &0x0,%d1 # is exp even or odd? 16048 beq.b ss_norm_even 16048 beq.b ss_norm_even 16049 16049 16050 ori.w &0x3fff,FP_SCR0_EX(% 16050 ori.w &0x3fff,FP_SCR0_EX(%a6) # insert new operand's exponent(=0) 16051 16051 16052 mov.l &0x3fff,%d0 16052 mov.l &0x3fff,%d0 16053 sub.l %d1,%d0 16053 sub.l %d1,%d0 # scale = BIAS + (-exp) 16054 asr.l &0x1,%d0 16054 asr.l &0x1,%d0 # divide scale factor by 2 16055 rts 16055 rts 16056 16056 16057 ss_norm_even: 16057 ss_norm_even: 16058 ori.w &0x3ffe,FP_SCR0_EX(% 16058 ori.w &0x3ffe,FP_SCR0_EX(%a6) # insert new operand's exponent(=0) 16059 16059 16060 mov.l &0x3ffe,%d0 16060 mov.l &0x3ffe,%d0 16061 sub.l %d1,%d0 16061 sub.l %d1,%d0 # scale = BIAS + (-exp) 16062 asr.l &0x1,%d0 16062 asr.l &0x1,%d0 # divide scale factor by 2 16063 rts 16063 rts 16064 16064 16065 ss_denorm: 16065 ss_denorm: 16066 lea FP_SCR0(%a6),%a0 16066 lea FP_SCR0(%a6),%a0 # pass ptr to src op 16067 bsr.l norm 16067 bsr.l norm # normalize denorm 16068 16068 16069 btst &0x0,%d0 16069 btst &0x0,%d0 # is exp even or odd? 16070 beq.b ss_denorm_even 16070 beq.b ss_denorm_even 16071 16071 16072 ori.w &0x3fff,FP_SCR0_EX(% 16072 ori.w &0x3fff,FP_SCR0_EX(%a6) # insert new operand's exponent(=0) 16073 16073 16074 add.l &0x3fff,%d0 16074 add.l &0x3fff,%d0 16075 asr.l &0x1,%d0 16075 asr.l &0x1,%d0 # divide scale factor by 2 16076 rts 16076 rts 16077 16077 16078 ss_denorm_even: 16078 ss_denorm_even: 16079 ori.w &0x3ffe,FP_SCR0_EX(% 16079 ori.w &0x3ffe,FP_SCR0_EX(%a6) # insert new operand's exponent(=0) 16080 16080 16081 add.l &0x3ffe,%d0 16081 add.l &0x3ffe,%d0 16082 asr.l &0x1,%d0 16082 asr.l &0x1,%d0 # divide scale factor by 2 16083 rts 16083 rts 16084 16084 16085 ### 16085 ### 16086 16086 16087 ############################################ 16087 ######################################################################### 16088 # XDEF ************************************* 16088 # XDEF **************************************************************** # 16089 # scale_to_zero_dst(): scale the expon 16089 # scale_to_zero_dst(): scale the exponent of extended precision # 16090 # value at FP_SCR 16090 # value at FP_SCR1(a6). # 16091 # 16091 # # 16092 # XREF ************************************* 16092 # XREF **************************************************************** # 16093 # norm() - normalize the mantissa if t 16093 # norm() - normalize the mantissa if the operand was a DENORM # 16094 # 16094 # # 16095 # INPUT ************************************ 16095 # INPUT *************************************************************** # 16096 # FP_SCR1(a6) = extended precision ope 16096 # FP_SCR1(a6) = extended precision operand to be scaled # 16097 # 16097 # # 16098 # OUTPUT *********************************** 16098 # OUTPUT ************************************************************** # 16099 # FP_SCR1(a6) = scaled extended precis 16099 # FP_SCR1(a6) = scaled extended precision operand # 16100 # d0 = scale value 16100 # d0 = scale value # 16101 # 16101 # # 16102 # ALGORITHM ******************************** 16102 # ALGORITHM *********************************************************** # 16103 # Set the exponent of the input operan 16103 # Set the exponent of the input operand to 0x3fff. Save the value # 16104 # of the difference between the original and 16104 # of the difference between the original and new exponent. Then, # 16105 # normalize the operand if it was a DENORM. 16105 # normalize the operand if it was a DENORM. Add this normalization # 16106 # value to the previous value. Return the re 16106 # value to the previous value. Return the result. # 16107 # 16107 # # 16108 ############################################ 16108 ######################################################################### 16109 16109 16110 global scale_to_zero_dst 16110 global scale_to_zero_dst 16111 scale_to_zero_dst: 16111 scale_to_zero_dst: 16112 mov.w FP_SCR1_EX(%a6),%d1 16112 mov.w FP_SCR1_EX(%a6),%d1 # extract operand's {sgn,exp} 16113 mov.w %d1,%d0 16113 mov.w %d1,%d0 # make a copy 16114 16114 16115 andi.l &0x7fff,%d1 16115 andi.l &0x7fff,%d1 # extract operand's exponent 16116 16116 16117 andi.w &0x8000,%d0 16117 andi.w &0x8000,%d0 # extract operand's sgn 16118 or.w &0x3fff,%d0 16118 or.w &0x3fff,%d0 # insert new operand's exponent(=0) 16119 16119 16120 mov.w %d0,FP_SCR1_EX(%a6) 16120 mov.w %d0,FP_SCR1_EX(%a6) # insert biased exponent 16121 16121 16122 cmpi.b DTAG(%a6),&DENORM 16122 cmpi.b DTAG(%a6),&DENORM # is operand normalized? 16123 beq.b stzd_denorm 16123 beq.b stzd_denorm # normalize the DENORM 16124 16124 16125 stzd_norm: 16125 stzd_norm: 16126 mov.l &0x3fff,%d0 16126 mov.l &0x3fff,%d0 16127 sub.l %d1,%d0 16127 sub.l %d1,%d0 # scale = BIAS + (-exp) 16128 rts 16128 rts 16129 16129 16130 stzd_denorm: 16130 stzd_denorm: 16131 lea FP_SCR1(%a6),%a0 16131 lea FP_SCR1(%a6),%a0 # pass ptr to dst op 16132 bsr.l norm 16132 bsr.l norm # normalize denorm 16133 neg.l %d0 16133 neg.l %d0 # new exponent = -(shft val) 16134 mov.l %d0,%d1 16134 mov.l %d0,%d1 # prepare for op_norm call 16135 bra.b stzd_norm 16135 bra.b stzd_norm # finish scaling 16136 16136 16137 ############################################ 16137 ########################################################################## 16138 16138 16139 ############################################ 16139 ######################################################################### 16140 # XDEF ************************************* 16140 # XDEF **************************************************************** # 16141 # res_qnan(): return default result w/ 16141 # res_qnan(): return default result w/ QNAN operand for dyadic # 16142 # res_snan(): return default result w/ 16142 # res_snan(): return default result w/ SNAN operand for dyadic # 16143 # res_qnan_1op(): return dflt result w 16143 # res_qnan_1op(): return dflt result w/ QNAN operand for monadic # 16144 # res_snan_1op(): return dflt result w 16144 # res_snan_1op(): return dflt result w/ SNAN operand for monadic # 16145 # 16145 # # 16146 # XREF ************************************* 16146 # XREF **************************************************************** # 16147 # None 16147 # None # 16148 # 16148 # # 16149 # INPUT ************************************ 16149 # INPUT *************************************************************** # 16150 # FP_SRC(a6) = pointer to extended pre 16150 # FP_SRC(a6) = pointer to extended precision src operand # 16151 # FP_DST(a6) = pointer to extended pre 16151 # FP_DST(a6) = pointer to extended precision dst operand # 16152 # 16152 # # 16153 # OUTPUT *********************************** 16153 # OUTPUT ************************************************************** # 16154 # fp0 = default result 16154 # fp0 = default result # 16155 # 16155 # # 16156 # ALGORITHM ******************************** 16156 # ALGORITHM *********************************************************** # 16157 # If either operand (but not both oper 16157 # If either operand (but not both operands) of an operation is a # 16158 # nonsignalling NAN, then that NAN is return 16158 # nonsignalling NAN, then that NAN is returned as the result. If both # 16159 # operands are nonsignalling NANs, then the 16159 # operands are nonsignalling NANs, then the destination operand # 16160 # nonsignalling NAN is returned as the resul 16160 # nonsignalling NAN is returned as the result. # 16161 # If either operand to an operation is 16161 # If either operand to an operation is a signalling NAN (SNAN), # 16162 # then, the SNAN bit is set in the FPSR EXC 16162 # then, the SNAN bit is set in the FPSR EXC byte. If the SNAN trap # 16163 # enable bit is set in the FPCR, then the tr 16163 # enable bit is set in the FPCR, then the trap is taken and the # 16164 # destination is not modified. If the SNAN t 16164 # destination is not modified. If the SNAN trap enable bit is not set, # 16165 # then the SNAN is converted to a nonsignall 16165 # then the SNAN is converted to a nonsignalling NAN (by setting the # 16166 # SNAN bit in the operand to one), and the o 16166 # SNAN bit in the operand to one), and the operation continues as # 16167 # described in the preceding paragraph, for 16167 # described in the preceding paragraph, for nonsignalling NANs. # 16168 # Make sure the appropriate FPSR bits 16168 # Make sure the appropriate FPSR bits are set before exiting. # 16169 # 16169 # # 16170 ############################################ 16170 ######################################################################### 16171 16171 16172 global res_qnan 16172 global res_qnan 16173 global res_snan 16173 global res_snan 16174 res_qnan: 16174 res_qnan: 16175 res_snan: 16175 res_snan: 16176 cmp.b DTAG(%a6), &SNAN 16176 cmp.b DTAG(%a6), &SNAN # is the dst an SNAN? 16177 beq.b dst_snan2 16177 beq.b dst_snan2 16178 cmp.b DTAG(%a6), &QNAN 16178 cmp.b DTAG(%a6), &QNAN # is the dst a QNAN? 16179 beq.b dst_qnan2 16179 beq.b dst_qnan2 16180 src_nan: 16180 src_nan: 16181 cmp.b STAG(%a6), &QNAN 16181 cmp.b STAG(%a6), &QNAN 16182 beq.b src_qnan2 16182 beq.b src_qnan2 16183 global res_snan_1op 16183 global res_snan_1op 16184 res_snan_1op: 16184 res_snan_1op: 16185 src_snan2: 16185 src_snan2: 16186 bset &0x6, FP_SRC_HI(%a6) 16186 bset &0x6, FP_SRC_HI(%a6) # set SNAN bit 16187 or.l &nan_mask+aiop_mask+ 16187 or.l &nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6) 16188 lea FP_SRC(%a6), %a0 16188 lea FP_SRC(%a6), %a0 16189 bra.b nan_comp 16189 bra.b nan_comp 16190 global res_qnan_1op 16190 global res_qnan_1op 16191 res_qnan_1op: 16191 res_qnan_1op: 16192 src_qnan2: 16192 src_qnan2: 16193 or.l &nan_mask, USER_FPSR 16193 or.l &nan_mask, USER_FPSR(%a6) 16194 lea FP_SRC(%a6), %a0 16194 lea FP_SRC(%a6), %a0 16195 bra.b nan_comp 16195 bra.b nan_comp 16196 dst_snan2: 16196 dst_snan2: 16197 or.l &nan_mask+aiop_mask+ 16197 or.l &nan_mask+aiop_mask+snan_mask, USER_FPSR(%a6) 16198 bset &0x6, FP_DST_HI(%a6) 16198 bset &0x6, FP_DST_HI(%a6) # set SNAN bit 16199 lea FP_DST(%a6), %a0 16199 lea FP_DST(%a6), %a0 16200 bra.b nan_comp 16200 bra.b nan_comp 16201 dst_qnan2: 16201 dst_qnan2: 16202 lea FP_DST(%a6), %a0 16202 lea FP_DST(%a6), %a0 16203 cmp.b STAG(%a6), &SNAN 16203 cmp.b STAG(%a6), &SNAN 16204 bne nan_done 16204 bne nan_done 16205 or.l &aiop_mask+snan_mask 16205 or.l &aiop_mask+snan_mask, USER_FPSR(%a6) 16206 nan_done: 16206 nan_done: 16207 or.l &nan_mask, USER_FPSR 16207 or.l &nan_mask, USER_FPSR(%a6) 16208 nan_comp: 16208 nan_comp: 16209 btst &0x7, FTEMP_EX(%a0) 16209 btst &0x7, FTEMP_EX(%a0) # is NAN neg? 16210 beq.b nan_not_neg 16210 beq.b nan_not_neg 16211 or.l &neg_mask, USER_FPSR 16211 or.l &neg_mask, USER_FPSR(%a6) 16212 nan_not_neg: 16212 nan_not_neg: 16213 fmovm.x (%a0), &0x80 16213 fmovm.x (%a0), &0x80 16214 rts 16214 rts 16215 16215 16216 ############################################ 16216 ######################################################################### 16217 # XDEF ************************************* 16217 # XDEF **************************************************************** # 16218 # res_operr(): return default result d 16218 # res_operr(): return default result during operand error # 16219 # 16219 # # 16220 # XREF ************************************* 16220 # XREF **************************************************************** # 16221 # None 16221 # None # 16222 # 16222 # # 16223 # INPUT ************************************ 16223 # INPUT *************************************************************** # 16224 # None 16224 # None # 16225 # 16225 # # 16226 # OUTPUT *********************************** 16226 # OUTPUT ************************************************************** # 16227 # fp0 = default operand error result 16227 # fp0 = default operand error result # 16228 # 16228 # # 16229 # ALGORITHM ******************************** 16229 # ALGORITHM *********************************************************** # 16230 # An nonsignalling NAN is returned as 16230 # An nonsignalling NAN is returned as the default result when # 16231 # an operand error occurs for the following 16231 # an operand error occurs for the following cases: # 16232 # 16232 # # 16233 # Multiply: (Infinity x Zero) 16233 # Multiply: (Infinity x Zero) # 16234 # Divide : (Zero / Zero) || (Infinity 16234 # Divide : (Zero / Zero) || (Infinity / Infinity) # 16235 # 16235 # # 16236 ############################################ 16236 ######################################################################### 16237 16237 16238 global res_operr 16238 global res_operr 16239 res_operr: 16239 res_operr: 16240 or.l &nan_mask+operr_mask 16240 or.l &nan_mask+operr_mask+aiop_mask, USER_FPSR(%a6) 16241 fmovm.x nan_return(%pc), &0x 16241 fmovm.x nan_return(%pc), &0x80 16242 rts 16242 rts 16243 16243 16244 nan_return: 16244 nan_return: 16245 long 0x7fff0000, 0xffffff 16245 long 0x7fff0000, 0xffffffff, 0xffffffff 16246 16246 16247 ############################################ 16247 ######################################################################### 16248 # fdbcc(): routine to emulate the fdbcc inst 16248 # fdbcc(): routine to emulate the fdbcc instruction # 16249 # 16249 # # 16250 # XDEF ************************************* 16250 # XDEF **************************************************************** # 16251 # _fdbcc() 16251 # _fdbcc() # 16252 # 16252 # # 16253 # XREF ************************************* 16253 # XREF **************************************************************** # 16254 # fetch_dreg() - fetch Dn value 16254 # fetch_dreg() - fetch Dn value # 16255 # store_dreg_l() - store updated Dn va 16255 # store_dreg_l() - store updated Dn value # 16256 # 16256 # # 16257 # INPUT ************************************ 16257 # INPUT *************************************************************** # 16258 # d0 = displacement 16258 # d0 = displacement # 16259 # 16259 # # 16260 # OUTPUT *********************************** 16260 # OUTPUT ************************************************************** # 16261 # none 16261 # none # 16262 # 16262 # # 16263 # ALGORITHM ******************************** 16263 # ALGORITHM *********************************************************** # 16264 # This routine checks which conditiona 16264 # This routine checks which conditional predicate is specified by # 16265 # the stacked fdbcc instruction opcode and t 16265 # the stacked fdbcc instruction opcode and then branches to a routine # 16266 # for that predicate. The corresponding fbcc 16266 # for that predicate. The corresponding fbcc instruction is then used # 16267 # to see whether the condition (specified by 16267 # to see whether the condition (specified by the stacked FPSR) is true # 16268 # or false. 16268 # or false. # 16269 # If a BSUN exception should be indica 16269 # If a BSUN exception should be indicated, the BSUN and ABSUN # 16270 # bits are set in the stacked FPSR. If the B 16270 # bits are set in the stacked FPSR. If the BSUN exception is enabled, # 16271 # the fbsun_flg is set in the SPCOND_FLG loc 16271 # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an # 16272 # enabled BSUN should not be flagged and the 16272 # enabled BSUN should not be flagged and the predicate is true, then # 16273 # Dn is fetched and decremented by one. If D 16273 # Dn is fetched and decremented by one. If Dn is not equal to -1, add # 16274 # the displacement value to the stacked PC s 16274 # the displacement value to the stacked PC so that when an "rte" is # 16275 # finally executed, the branch occurs. 16275 # finally executed, the branch occurs. # 16276 # 16276 # # 16277 ############################################ 16277 ######################################################################### 16278 global _fdbcc 16278 global _fdbcc 16279 _fdbcc: 16279 _fdbcc: 16280 mov.l %d0,L_SCR1(%a6) 16280 mov.l %d0,L_SCR1(%a6) # save displacement 16281 16281 16282 mov.w EXC_CMDREG(%a6),%d0 16282 mov.w EXC_CMDREG(%a6),%d0 # fetch predicate 16283 16283 16284 clr.l %d1 16284 clr.l %d1 # clear scratch reg 16285 mov.b FPSR_CC(%a6),%d1 16285 mov.b FPSR_CC(%a6),%d1 # fetch fp ccodes 16286 ror.l &0x8,%d1 16286 ror.l &0x8,%d1 # rotate to top byte 16287 fmov.l %d1,%fpsr 16287 fmov.l %d1,%fpsr # insert into FPSR 16288 16288 16289 mov.w (tbl_fdbcc.b,%pc,%d0 16289 mov.w (tbl_fdbcc.b,%pc,%d0.w*2),%d1 # load table 16290 jmp (tbl_fdbcc.b,%pc,%d1 16290 jmp (tbl_fdbcc.b,%pc,%d1.w) # jump to fdbcc routine 16291 16291 16292 tbl_fdbcc: 16292 tbl_fdbcc: 16293 short fdbcc_f - 16293 short fdbcc_f - tbl_fdbcc # 00 16294 short fdbcc_eq - 16294 short fdbcc_eq - tbl_fdbcc # 01 16295 short fdbcc_ogt - 16295 short fdbcc_ogt - tbl_fdbcc # 02 16296 short fdbcc_oge - 16296 short fdbcc_oge - tbl_fdbcc # 03 16297 short fdbcc_olt - 16297 short fdbcc_olt - tbl_fdbcc # 04 16298 short fdbcc_ole - 16298 short fdbcc_ole - tbl_fdbcc # 05 16299 short fdbcc_ogl - 16299 short fdbcc_ogl - tbl_fdbcc # 06 16300 short fdbcc_or - 16300 short fdbcc_or - tbl_fdbcc # 07 16301 short fdbcc_un - 16301 short fdbcc_un - tbl_fdbcc # 08 16302 short fdbcc_ueq - 16302 short fdbcc_ueq - tbl_fdbcc # 09 16303 short fdbcc_ugt - 16303 short fdbcc_ugt - tbl_fdbcc # 10 16304 short fdbcc_uge - 16304 short fdbcc_uge - tbl_fdbcc # 11 16305 short fdbcc_ult - 16305 short fdbcc_ult - tbl_fdbcc # 12 16306 short fdbcc_ule - 16306 short fdbcc_ule - tbl_fdbcc # 13 16307 short fdbcc_neq - 16307 short fdbcc_neq - tbl_fdbcc # 14 16308 short fdbcc_t - 16308 short fdbcc_t - tbl_fdbcc # 15 16309 short fdbcc_sf - 16309 short fdbcc_sf - tbl_fdbcc # 16 16310 short fdbcc_seq - 16310 short fdbcc_seq - tbl_fdbcc # 17 16311 short fdbcc_gt - 16311 short fdbcc_gt - tbl_fdbcc # 18 16312 short fdbcc_ge - 16312 short fdbcc_ge - tbl_fdbcc # 19 16313 short fdbcc_lt - 16313 short fdbcc_lt - tbl_fdbcc # 20 16314 short fdbcc_le - 16314 short fdbcc_le - tbl_fdbcc # 21 16315 short fdbcc_gl - 16315 short fdbcc_gl - tbl_fdbcc # 22 16316 short fdbcc_gle - 16316 short fdbcc_gle - tbl_fdbcc # 23 16317 short fdbcc_ngle - 16317 short fdbcc_ngle - tbl_fdbcc # 24 16318 short fdbcc_ngl - 16318 short fdbcc_ngl - tbl_fdbcc # 25 16319 short fdbcc_nle - 16319 short fdbcc_nle - tbl_fdbcc # 26 16320 short fdbcc_nlt - 16320 short fdbcc_nlt - tbl_fdbcc # 27 16321 short fdbcc_nge - 16321 short fdbcc_nge - tbl_fdbcc # 28 16322 short fdbcc_ngt - 16322 short fdbcc_ngt - tbl_fdbcc # 29 16323 short fdbcc_sneq - 16323 short fdbcc_sneq - tbl_fdbcc # 30 16324 short fdbcc_st - 16324 short fdbcc_st - tbl_fdbcc # 31 16325 16325 16326 ############################################ 16326 ######################################################################### 16327 # 16327 # # 16328 # IEEE Nonaware tests 16328 # IEEE Nonaware tests # 16329 # 16329 # # 16330 # For the IEEE nonaware tests, only the fals 16330 # For the IEEE nonaware tests, only the false branch changes the # 16331 # counter. However, the true branch may set 16331 # counter. However, the true branch may set bsun so we check to see # 16332 # if the NAN bit is set, in which case BSUN 16332 # if the NAN bit is set, in which case BSUN and AIOP will be set. # 16333 # 16333 # # 16334 # The cases EQ and NE are shared by the Awar 16334 # The cases EQ and NE are shared by the Aware and Nonaware groups # 16335 # and are incapable of setting the BSUN exce 16335 # and are incapable of setting the BSUN exception bit. # 16336 # 16336 # # 16337 # Typically, only one of the two possible br 16337 # Typically, only one of the two possible branch directions could # 16338 # have the NAN bit set. 16338 # have the NAN bit set. # 16339 # (This is assuming the mutual exclusiveness 16339 # (This is assuming the mutual exclusiveness of FPSR cc bit groupings # 16340 # is preserved.) 16340 # is preserved.) # 16341 # 16341 # # 16342 ############################################ 16342 ######################################################################### 16343 16343 16344 # 16344 # 16345 # equal: 16345 # equal: 16346 # 16346 # 16347 # Z 16347 # Z 16348 # 16348 # 16349 fdbcc_eq: 16349 fdbcc_eq: 16350 fbeq.w fdbcc_eq_yes 16350 fbeq.w fdbcc_eq_yes # equal? 16351 fdbcc_eq_no: 16351 fdbcc_eq_no: 16352 bra.w fdbcc_false 16352 bra.w fdbcc_false # no; go handle counter 16353 fdbcc_eq_yes: 16353 fdbcc_eq_yes: 16354 rts 16354 rts 16355 16355 16356 # 16356 # 16357 # not equal: 16357 # not equal: 16358 # _ 16358 # _ 16359 # Z 16359 # Z 16360 # 16360 # 16361 fdbcc_neq: 16361 fdbcc_neq: 16362 fbneq.w fdbcc_neq_yes 16362 fbneq.w fdbcc_neq_yes # not equal? 16363 fdbcc_neq_no: 16363 fdbcc_neq_no: 16364 bra.w fdbcc_false 16364 bra.w fdbcc_false # no; go handle counter 16365 fdbcc_neq_yes: 16365 fdbcc_neq_yes: 16366 rts 16366 rts 16367 16367 16368 # 16368 # 16369 # greater than: 16369 # greater than: 16370 # _______ 16370 # _______ 16371 # NANvZvN 16371 # NANvZvN 16372 # 16372 # 16373 fdbcc_gt: 16373 fdbcc_gt: 16374 fbgt.w fdbcc_gt_yes 16374 fbgt.w fdbcc_gt_yes # greater than? 16375 btst &nan_bit, FPSR_CC(%a 16375 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16376 beq.w fdbcc_false 16376 beq.w fdbcc_false # no;go handle counter 16377 ori.l &bsun_mask+aiop_mask 16377 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16378 btst &bsun_bit, FPCR_ENAB 16378 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16379 bne.w fdbcc_bsun 16379 bne.w fdbcc_bsun # yes; we have an exception 16380 bra.w fdbcc_false 16380 bra.w fdbcc_false # no; go handle counter 16381 fdbcc_gt_yes: 16381 fdbcc_gt_yes: 16382 rts 16382 rts # do nothing 16383 16383 16384 # 16384 # 16385 # not greater than: 16385 # not greater than: 16386 # 16386 # 16387 # NANvZvN 16387 # NANvZvN 16388 # 16388 # 16389 fdbcc_ngt: 16389 fdbcc_ngt: 16390 fbngt.w fdbcc_ngt_yes 16390 fbngt.w fdbcc_ngt_yes # not greater than? 16391 fdbcc_ngt_no: 16391 fdbcc_ngt_no: 16392 bra.w fdbcc_false 16392 bra.w fdbcc_false # no; go handle counter 16393 fdbcc_ngt_yes: 16393 fdbcc_ngt_yes: 16394 btst &nan_bit, FPSR_CC(%a 16394 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16395 beq.b fdbcc_ngt_done 16395 beq.b fdbcc_ngt_done # no;go finish 16396 ori.l &bsun_mask+aiop_mask 16396 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16397 btst &bsun_bit, FPCR_ENAB 16397 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16398 bne.w fdbcc_bsun 16398 bne.w fdbcc_bsun # yes; we have an exception 16399 fdbcc_ngt_done: 16399 fdbcc_ngt_done: 16400 rts 16400 rts # no; do nothing 16401 16401 16402 # 16402 # 16403 # greater than or equal: 16403 # greater than or equal: 16404 # _____ 16404 # _____ 16405 # Zv(NANvN) 16405 # Zv(NANvN) 16406 # 16406 # 16407 fdbcc_ge: 16407 fdbcc_ge: 16408 fbge.w fdbcc_ge_yes 16408 fbge.w fdbcc_ge_yes # greater than or equal? 16409 fdbcc_ge_no: 16409 fdbcc_ge_no: 16410 btst &nan_bit, FPSR_CC(%a 16410 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16411 beq.w fdbcc_false 16411 beq.w fdbcc_false # no;go handle counter 16412 ori.l &bsun_mask+aiop_mask 16412 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16413 btst &bsun_bit, FPCR_ENAB 16413 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16414 bne.w fdbcc_bsun 16414 bne.w fdbcc_bsun # yes; we have an exception 16415 bra.w fdbcc_false 16415 bra.w fdbcc_false # no; go handle counter 16416 fdbcc_ge_yes: 16416 fdbcc_ge_yes: 16417 btst &nan_bit, FPSR_CC(%a 16417 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16418 beq.b fdbcc_ge_yes_done 16418 beq.b fdbcc_ge_yes_done # no;go do nothing 16419 ori.l &bsun_mask+aiop_mask 16419 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16420 btst &bsun_bit, FPCR_ENAB 16420 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16421 bne.w fdbcc_bsun 16421 bne.w fdbcc_bsun # yes; we have an exception 16422 fdbcc_ge_yes_done: 16422 fdbcc_ge_yes_done: 16423 rts 16423 rts # do nothing 16424 16424 16425 # 16425 # 16426 # not (greater than or equal): 16426 # not (greater than or equal): 16427 # _ 16427 # _ 16428 # NANv(N^Z) 16428 # NANv(N^Z) 16429 # 16429 # 16430 fdbcc_nge: 16430 fdbcc_nge: 16431 fbnge.w fdbcc_nge_yes 16431 fbnge.w fdbcc_nge_yes # not (greater than or equal)? 16432 fdbcc_nge_no: 16432 fdbcc_nge_no: 16433 bra.w fdbcc_false 16433 bra.w fdbcc_false # no; go handle counter 16434 fdbcc_nge_yes: 16434 fdbcc_nge_yes: 16435 btst &nan_bit, FPSR_CC(%a 16435 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16436 beq.b fdbcc_nge_done 16436 beq.b fdbcc_nge_done # no;go finish 16437 ori.l &bsun_mask+aiop_mask 16437 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16438 btst &bsun_bit, FPCR_ENAB 16438 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16439 bne.w fdbcc_bsun 16439 bne.w fdbcc_bsun # yes; we have an exception 16440 fdbcc_nge_done: 16440 fdbcc_nge_done: 16441 rts 16441 rts # no; do nothing 16442 16442 16443 # 16443 # 16444 # less than: 16444 # less than: 16445 # _____ 16445 # _____ 16446 # N^(NANvZ) 16446 # N^(NANvZ) 16447 # 16447 # 16448 fdbcc_lt: 16448 fdbcc_lt: 16449 fblt.w fdbcc_lt_yes 16449 fblt.w fdbcc_lt_yes # less than? 16450 fdbcc_lt_no: 16450 fdbcc_lt_no: 16451 btst &nan_bit, FPSR_CC(%a 16451 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16452 beq.w fdbcc_false 16452 beq.w fdbcc_false # no; go handle counter 16453 ori.l &bsun_mask+aiop_mask 16453 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16454 btst &bsun_bit, FPCR_ENAB 16454 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16455 bne.w fdbcc_bsun 16455 bne.w fdbcc_bsun # yes; we have an exception 16456 bra.w fdbcc_false 16456 bra.w fdbcc_false # no; go handle counter 16457 fdbcc_lt_yes: 16457 fdbcc_lt_yes: 16458 rts 16458 rts # do nothing 16459 16459 16460 # 16460 # 16461 # not less than: 16461 # not less than: 16462 # _ 16462 # _ 16463 # NANv(ZvN) 16463 # NANv(ZvN) 16464 # 16464 # 16465 fdbcc_nlt: 16465 fdbcc_nlt: 16466 fbnlt.w fdbcc_nlt_yes 16466 fbnlt.w fdbcc_nlt_yes # not less than? 16467 fdbcc_nlt_no: 16467 fdbcc_nlt_no: 16468 bra.w fdbcc_false 16468 bra.w fdbcc_false # no; go handle counter 16469 fdbcc_nlt_yes: 16469 fdbcc_nlt_yes: 16470 btst &nan_bit, FPSR_CC(%a 16470 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16471 beq.b fdbcc_nlt_done 16471 beq.b fdbcc_nlt_done # no;go finish 16472 ori.l &bsun_mask+aiop_mask 16472 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16473 btst &bsun_bit, FPCR_ENAB 16473 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16474 bne.w fdbcc_bsun 16474 bne.w fdbcc_bsun # yes; we have an exception 16475 fdbcc_nlt_done: 16475 fdbcc_nlt_done: 16476 rts 16476 rts # no; do nothing 16477 16477 16478 # 16478 # 16479 # less than or equal: 16479 # less than or equal: 16480 # ___ 16480 # ___ 16481 # Zv(N^NAN) 16481 # Zv(N^NAN) 16482 # 16482 # 16483 fdbcc_le: 16483 fdbcc_le: 16484 fble.w fdbcc_le_yes 16484 fble.w fdbcc_le_yes # less than or equal? 16485 fdbcc_le_no: 16485 fdbcc_le_no: 16486 btst &nan_bit, FPSR_CC(%a 16486 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16487 beq.w fdbcc_false 16487 beq.w fdbcc_false # no; go handle counter 16488 ori.l &bsun_mask+aiop_mask 16488 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16489 btst &bsun_bit, FPCR_ENAB 16489 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16490 bne.w fdbcc_bsun 16490 bne.w fdbcc_bsun # yes; we have an exception 16491 bra.w fdbcc_false 16491 bra.w fdbcc_false # no; go handle counter 16492 fdbcc_le_yes: 16492 fdbcc_le_yes: 16493 btst &nan_bit, FPSR_CC(%a 16493 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16494 beq.b fdbcc_le_yes_done 16494 beq.b fdbcc_le_yes_done # no; go do nothing 16495 ori.l &bsun_mask+aiop_mask 16495 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16496 btst &bsun_bit, FPCR_ENAB 16496 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16497 bne.w fdbcc_bsun 16497 bne.w fdbcc_bsun # yes; we have an exception 16498 fdbcc_le_yes_done: 16498 fdbcc_le_yes_done: 16499 rts 16499 rts # do nothing 16500 16500 16501 # 16501 # 16502 # not (less than or equal): 16502 # not (less than or equal): 16503 # ___ 16503 # ___ 16504 # NANv(NvZ) 16504 # NANv(NvZ) 16505 # 16505 # 16506 fdbcc_nle: 16506 fdbcc_nle: 16507 fbnle.w fdbcc_nle_yes 16507 fbnle.w fdbcc_nle_yes # not (less than or equal)? 16508 fdbcc_nle_no: 16508 fdbcc_nle_no: 16509 bra.w fdbcc_false 16509 bra.w fdbcc_false # no; go handle counter 16510 fdbcc_nle_yes: 16510 fdbcc_nle_yes: 16511 btst &nan_bit, FPSR_CC(%a 16511 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16512 beq.w fdbcc_nle_done 16512 beq.w fdbcc_nle_done # no; go finish 16513 ori.l &bsun_mask+aiop_mask 16513 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16514 btst &bsun_bit, FPCR_ENAB 16514 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16515 bne.w fdbcc_bsun 16515 bne.w fdbcc_bsun # yes; we have an exception 16516 fdbcc_nle_done: 16516 fdbcc_nle_done: 16517 rts 16517 rts # no; do nothing 16518 16518 16519 # 16519 # 16520 # greater or less than: 16520 # greater or less than: 16521 # _____ 16521 # _____ 16522 # NANvZ 16522 # NANvZ 16523 # 16523 # 16524 fdbcc_gl: 16524 fdbcc_gl: 16525 fbgl.w fdbcc_gl_yes 16525 fbgl.w fdbcc_gl_yes # greater or less than? 16526 fdbcc_gl_no: 16526 fdbcc_gl_no: 16527 btst &nan_bit, FPSR_CC(%a 16527 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16528 beq.w fdbcc_false 16528 beq.w fdbcc_false # no; handle counter 16529 ori.l &bsun_mask+aiop_mask 16529 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16530 btst &bsun_bit, FPCR_ENAB 16530 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16531 bne.w fdbcc_bsun 16531 bne.w fdbcc_bsun # yes; we have an exception 16532 bra.w fdbcc_false 16532 bra.w fdbcc_false # no; go handle counter 16533 fdbcc_gl_yes: 16533 fdbcc_gl_yes: 16534 rts 16534 rts # do nothing 16535 16535 16536 # 16536 # 16537 # not (greater or less than): 16537 # not (greater or less than): 16538 # 16538 # 16539 # NANvZ 16539 # NANvZ 16540 # 16540 # 16541 fdbcc_ngl: 16541 fdbcc_ngl: 16542 fbngl.w fdbcc_ngl_yes 16542 fbngl.w fdbcc_ngl_yes # not (greater or less than)? 16543 fdbcc_ngl_no: 16543 fdbcc_ngl_no: 16544 bra.w fdbcc_false 16544 bra.w fdbcc_false # no; go handle counter 16545 fdbcc_ngl_yes: 16545 fdbcc_ngl_yes: 16546 btst &nan_bit, FPSR_CC(%a 16546 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16547 beq.b fdbcc_ngl_done 16547 beq.b fdbcc_ngl_done # no; go finish 16548 ori.l &bsun_mask+aiop_mask 16548 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16549 btst &bsun_bit, FPCR_ENAB 16549 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16550 bne.w fdbcc_bsun 16550 bne.w fdbcc_bsun # yes; we have an exception 16551 fdbcc_ngl_done: 16551 fdbcc_ngl_done: 16552 rts 16552 rts # no; do nothing 16553 16553 16554 # 16554 # 16555 # greater, less, or equal: 16555 # greater, less, or equal: 16556 # ___ 16556 # ___ 16557 # NAN 16557 # NAN 16558 # 16558 # 16559 fdbcc_gle: 16559 fdbcc_gle: 16560 fbgle.w fdbcc_gle_yes 16560 fbgle.w fdbcc_gle_yes # greater, less, or equal? 16561 fdbcc_gle_no: 16561 fdbcc_gle_no: 16562 ori.l &bsun_mask+aiop_mask 16562 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16563 btst &bsun_bit, FPCR_ENAB 16563 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16564 bne.w fdbcc_bsun 16564 bne.w fdbcc_bsun # yes; we have an exception 16565 bra.w fdbcc_false 16565 bra.w fdbcc_false # no; go handle counter 16566 fdbcc_gle_yes: 16566 fdbcc_gle_yes: 16567 rts 16567 rts # do nothing 16568 16568 16569 # 16569 # 16570 # not (greater, less, or equal): 16570 # not (greater, less, or equal): 16571 # 16571 # 16572 # NAN 16572 # NAN 16573 # 16573 # 16574 fdbcc_ngle: 16574 fdbcc_ngle: 16575 fbngle.w fdbcc_ngle_yes 16575 fbngle.w fdbcc_ngle_yes # not (greater, less, or equal)? 16576 fdbcc_ngle_no: 16576 fdbcc_ngle_no: 16577 bra.w fdbcc_false 16577 bra.w fdbcc_false # no; go handle counter 16578 fdbcc_ngle_yes: 16578 fdbcc_ngle_yes: 16579 ori.l &bsun_mask+aiop_mask 16579 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16580 btst &bsun_bit, FPCR_ENAB 16580 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16581 bne.w fdbcc_bsun 16581 bne.w fdbcc_bsun # yes; we have an exception 16582 rts 16582 rts # no; do nothing 16583 16583 16584 ############################################ 16584 ######################################################################### 16585 # 16585 # # 16586 # Miscellaneous tests 16586 # Miscellaneous tests # 16587 # 16587 # # 16588 # For the IEEE miscellaneous tests, all but 16588 # For the IEEE miscellaneous tests, all but fdbf and fdbt can set bsun. # 16589 # 16589 # # 16590 ############################################ 16590 ######################################################################### 16591 16591 16592 # 16592 # 16593 # false: 16593 # false: 16594 # 16594 # 16595 # False 16595 # False 16596 # 16596 # 16597 fdbcc_f: 16597 fdbcc_f: # no bsun possible 16598 bra.w fdbcc_false 16598 bra.w fdbcc_false # go handle counter 16599 16599 16600 # 16600 # 16601 # true: 16601 # true: 16602 # 16602 # 16603 # True 16603 # True 16604 # 16604 # 16605 fdbcc_t: 16605 fdbcc_t: # no bsun possible 16606 rts 16606 rts # do nothing 16607 16607 16608 # 16608 # 16609 # signalling false: 16609 # signalling false: 16610 # 16610 # 16611 # False 16611 # False 16612 # 16612 # 16613 fdbcc_sf: 16613 fdbcc_sf: 16614 btst &nan_bit, FPSR_CC(%a 16614 btst &nan_bit, FPSR_CC(%a6) # is NAN set? 16615 beq.w fdbcc_false 16615 beq.w fdbcc_false # no;go handle counter 16616 ori.l &bsun_mask+aiop_mask 16616 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16617 btst &bsun_bit, FPCR_ENAB 16617 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16618 bne.w fdbcc_bsun 16618 bne.w fdbcc_bsun # yes; we have an exception 16619 bra.w fdbcc_false 16619 bra.w fdbcc_false # go handle counter 16620 16620 16621 # 16621 # 16622 # signalling true: 16622 # signalling true: 16623 # 16623 # 16624 # True 16624 # True 16625 # 16625 # 16626 fdbcc_st: 16626 fdbcc_st: 16627 btst &nan_bit, FPSR_CC(%a 16627 btst &nan_bit, FPSR_CC(%a6) # is NAN set? 16628 beq.b fdbcc_st_done 16628 beq.b fdbcc_st_done # no;go finish 16629 ori.l &bsun_mask+aiop_mask 16629 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16630 btst &bsun_bit, FPCR_ENAB 16630 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16631 bne.w fdbcc_bsun 16631 bne.w fdbcc_bsun # yes; we have an exception 16632 fdbcc_st_done: 16632 fdbcc_st_done: 16633 rts 16633 rts 16634 16634 16635 # 16635 # 16636 # signalling equal: 16636 # signalling equal: 16637 # 16637 # 16638 # Z 16638 # Z 16639 # 16639 # 16640 fdbcc_seq: 16640 fdbcc_seq: 16641 fbseq.w fdbcc_seq_yes 16641 fbseq.w fdbcc_seq_yes # signalling equal? 16642 fdbcc_seq_no: 16642 fdbcc_seq_no: 16643 btst &nan_bit, FPSR_CC(%a 16643 btst &nan_bit, FPSR_CC(%a6) # is NAN set? 16644 beq.w fdbcc_false 16644 beq.w fdbcc_false # no;go handle counter 16645 ori.l &bsun_mask+aiop_mask 16645 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16646 btst &bsun_bit, FPCR_ENAB 16646 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16647 bne.w fdbcc_bsun 16647 bne.w fdbcc_bsun # yes; we have an exception 16648 bra.w fdbcc_false 16648 bra.w fdbcc_false # go handle counter 16649 fdbcc_seq_yes: 16649 fdbcc_seq_yes: 16650 btst &nan_bit, FPSR_CC(%a 16650 btst &nan_bit, FPSR_CC(%a6) # is NAN set? 16651 beq.b fdbcc_seq_yes_done 16651 beq.b fdbcc_seq_yes_done # no;go do nothing 16652 ori.l &bsun_mask+aiop_mask 16652 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16653 btst &bsun_bit, FPCR_ENAB 16653 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16654 bne.w fdbcc_bsun 16654 bne.w fdbcc_bsun # yes; we have an exception 16655 fdbcc_seq_yes_done: 16655 fdbcc_seq_yes_done: 16656 rts 16656 rts # yes; do nothing 16657 16657 16658 # 16658 # 16659 # signalling not equal: 16659 # signalling not equal: 16660 # _ 16660 # _ 16661 # Z 16661 # Z 16662 # 16662 # 16663 fdbcc_sneq: 16663 fdbcc_sneq: 16664 fbsneq.w fdbcc_sneq_yes 16664 fbsneq.w fdbcc_sneq_yes # signalling not equal? 16665 fdbcc_sneq_no: 16665 fdbcc_sneq_no: 16666 btst &nan_bit, FPSR_CC(%a 16666 btst &nan_bit, FPSR_CC(%a6) # is NAN set? 16667 beq.w fdbcc_false 16667 beq.w fdbcc_false # no;go handle counter 16668 ori.l &bsun_mask+aiop_mask 16668 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16669 btst &bsun_bit, FPCR_ENAB 16669 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16670 bne.w fdbcc_bsun 16670 bne.w fdbcc_bsun # yes; we have an exception 16671 bra.w fdbcc_false 16671 bra.w fdbcc_false # go handle counter 16672 fdbcc_sneq_yes: 16672 fdbcc_sneq_yes: 16673 btst &nan_bit, FPSR_CC(%a 16673 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 16674 beq.w fdbcc_sneq_done 16674 beq.w fdbcc_sneq_done # no;go finish 16675 ori.l &bsun_mask+aiop_mask 16675 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 16676 btst &bsun_bit, FPCR_ENAB 16676 btst &bsun_bit, FPCR_ENABLE(%a6) # is BSUN enabled? 16677 bne.w fdbcc_bsun 16677 bne.w fdbcc_bsun # yes; we have an exception 16678 fdbcc_sneq_done: 16678 fdbcc_sneq_done: 16679 rts 16679 rts 16680 16680 16681 ############################################ 16681 ######################################################################### 16682 # 16682 # # 16683 # IEEE Aware tests 16683 # IEEE Aware tests # 16684 # 16684 # # 16685 # For the IEEE aware tests, action is only t 16685 # For the IEEE aware tests, action is only taken if the result is false.# 16686 # Therefore, the opposite branch type is use 16686 # Therefore, the opposite branch type is used to jump to the decrement # 16687 # routine. 16687 # routine. # 16688 # The BSUN exception will not be set for any 16688 # The BSUN exception will not be set for any of these tests. # 16689 # 16689 # # 16690 ############################################ 16690 ######################################################################### 16691 16691 16692 # 16692 # 16693 # ordered greater than: 16693 # ordered greater than: 16694 # _______ 16694 # _______ 16695 # NANvZvN 16695 # NANvZvN 16696 # 16696 # 16697 fdbcc_ogt: 16697 fdbcc_ogt: 16698 fbogt.w fdbcc_ogt_yes 16698 fbogt.w fdbcc_ogt_yes # ordered greater than? 16699 fdbcc_ogt_no: 16699 fdbcc_ogt_no: 16700 bra.w fdbcc_false 16700 bra.w fdbcc_false # no; go handle counter 16701 fdbcc_ogt_yes: 16701 fdbcc_ogt_yes: 16702 rts 16702 rts # yes; do nothing 16703 16703 16704 # 16704 # 16705 # unordered or less or equal: 16705 # unordered or less or equal: 16706 # _______ 16706 # _______ 16707 # NANvZvN 16707 # NANvZvN 16708 # 16708 # 16709 fdbcc_ule: 16709 fdbcc_ule: 16710 fbule.w fdbcc_ule_yes 16710 fbule.w fdbcc_ule_yes # unordered or less or equal? 16711 fdbcc_ule_no: 16711 fdbcc_ule_no: 16712 bra.w fdbcc_false 16712 bra.w fdbcc_false # no; go handle counter 16713 fdbcc_ule_yes: 16713 fdbcc_ule_yes: 16714 rts 16714 rts # yes; do nothing 16715 16715 16716 # 16716 # 16717 # ordered greater than or equal: 16717 # ordered greater than or equal: 16718 # _____ 16718 # _____ 16719 # Zv(NANvN) 16719 # Zv(NANvN) 16720 # 16720 # 16721 fdbcc_oge: 16721 fdbcc_oge: 16722 fboge.w fdbcc_oge_yes 16722 fboge.w fdbcc_oge_yes # ordered greater than or equal? 16723 fdbcc_oge_no: 16723 fdbcc_oge_no: 16724 bra.w fdbcc_false 16724 bra.w fdbcc_false # no; go handle counter 16725 fdbcc_oge_yes: 16725 fdbcc_oge_yes: 16726 rts 16726 rts # yes; do nothing 16727 16727 16728 # 16728 # 16729 # unordered or less than: 16729 # unordered or less than: 16730 # _ 16730 # _ 16731 # NANv(N^Z) 16731 # NANv(N^Z) 16732 # 16732 # 16733 fdbcc_ult: 16733 fdbcc_ult: 16734 fbult.w fdbcc_ult_yes 16734 fbult.w fdbcc_ult_yes # unordered or less than? 16735 fdbcc_ult_no: 16735 fdbcc_ult_no: 16736 bra.w fdbcc_false 16736 bra.w fdbcc_false # no; go handle counter 16737 fdbcc_ult_yes: 16737 fdbcc_ult_yes: 16738 rts 16738 rts # yes; do nothing 16739 16739 16740 # 16740 # 16741 # ordered less than: 16741 # ordered less than: 16742 # _____ 16742 # _____ 16743 # N^(NANvZ) 16743 # N^(NANvZ) 16744 # 16744 # 16745 fdbcc_olt: 16745 fdbcc_olt: 16746 fbolt.w fdbcc_olt_yes 16746 fbolt.w fdbcc_olt_yes # ordered less than? 16747 fdbcc_olt_no: 16747 fdbcc_olt_no: 16748 bra.w fdbcc_false 16748 bra.w fdbcc_false # no; go handle counter 16749 fdbcc_olt_yes: 16749 fdbcc_olt_yes: 16750 rts 16750 rts # yes; do nothing 16751 16751 16752 # 16752 # 16753 # unordered or greater or equal: 16753 # unordered or greater or equal: 16754 # 16754 # 16755 # NANvZvN 16755 # NANvZvN 16756 # 16756 # 16757 fdbcc_uge: 16757 fdbcc_uge: 16758 fbuge.w fdbcc_uge_yes 16758 fbuge.w fdbcc_uge_yes # unordered or greater than? 16759 fdbcc_uge_no: 16759 fdbcc_uge_no: 16760 bra.w fdbcc_false 16760 bra.w fdbcc_false # no; go handle counter 16761 fdbcc_uge_yes: 16761 fdbcc_uge_yes: 16762 rts 16762 rts # yes; do nothing 16763 16763 16764 # 16764 # 16765 # ordered less than or equal: 16765 # ordered less than or equal: 16766 # ___ 16766 # ___ 16767 # Zv(N^NAN) 16767 # Zv(N^NAN) 16768 # 16768 # 16769 fdbcc_ole: 16769 fdbcc_ole: 16770 fbole.w fdbcc_ole_yes 16770 fbole.w fdbcc_ole_yes # ordered greater or less than? 16771 fdbcc_ole_no: 16771 fdbcc_ole_no: 16772 bra.w fdbcc_false 16772 bra.w fdbcc_false # no; go handle counter 16773 fdbcc_ole_yes: 16773 fdbcc_ole_yes: 16774 rts 16774 rts # yes; do nothing 16775 16775 16776 # 16776 # 16777 # unordered or greater than: 16777 # unordered or greater than: 16778 # ___ 16778 # ___ 16779 # NANv(NvZ) 16779 # NANv(NvZ) 16780 # 16780 # 16781 fdbcc_ugt: 16781 fdbcc_ugt: 16782 fbugt.w fdbcc_ugt_yes 16782 fbugt.w fdbcc_ugt_yes # unordered or greater than? 16783 fdbcc_ugt_no: 16783 fdbcc_ugt_no: 16784 bra.w fdbcc_false 16784 bra.w fdbcc_false # no; go handle counter 16785 fdbcc_ugt_yes: 16785 fdbcc_ugt_yes: 16786 rts 16786 rts # yes; do nothing 16787 16787 16788 # 16788 # 16789 # ordered greater or less than: 16789 # ordered greater or less than: 16790 # _____ 16790 # _____ 16791 # NANvZ 16791 # NANvZ 16792 # 16792 # 16793 fdbcc_ogl: 16793 fdbcc_ogl: 16794 fbogl.w fdbcc_ogl_yes 16794 fbogl.w fdbcc_ogl_yes # ordered greater or less than? 16795 fdbcc_ogl_no: 16795 fdbcc_ogl_no: 16796 bra.w fdbcc_false 16796 bra.w fdbcc_false # no; go handle counter 16797 fdbcc_ogl_yes: 16797 fdbcc_ogl_yes: 16798 rts 16798 rts # yes; do nothing 16799 16799 16800 # 16800 # 16801 # unordered or equal: 16801 # unordered or equal: 16802 # 16802 # 16803 # NANvZ 16803 # NANvZ 16804 # 16804 # 16805 fdbcc_ueq: 16805 fdbcc_ueq: 16806 fbueq.w fdbcc_ueq_yes 16806 fbueq.w fdbcc_ueq_yes # unordered or equal? 16807 fdbcc_ueq_no: 16807 fdbcc_ueq_no: 16808 bra.w fdbcc_false 16808 bra.w fdbcc_false # no; go handle counter 16809 fdbcc_ueq_yes: 16809 fdbcc_ueq_yes: 16810 rts 16810 rts # yes; do nothing 16811 16811 16812 # 16812 # 16813 # ordered: 16813 # ordered: 16814 # ___ 16814 # ___ 16815 # NAN 16815 # NAN 16816 # 16816 # 16817 fdbcc_or: 16817 fdbcc_or: 16818 fbor.w fdbcc_or_yes 16818 fbor.w fdbcc_or_yes # ordered? 16819 fdbcc_or_no: 16819 fdbcc_or_no: 16820 bra.w fdbcc_false 16820 bra.w fdbcc_false # no; go handle counter 16821 fdbcc_or_yes: 16821 fdbcc_or_yes: 16822 rts 16822 rts # yes; do nothing 16823 16823 16824 # 16824 # 16825 # unordered: 16825 # unordered: 16826 # 16826 # 16827 # NAN 16827 # NAN 16828 # 16828 # 16829 fdbcc_un: 16829 fdbcc_un: 16830 fbun.w fdbcc_un_yes 16830 fbun.w fdbcc_un_yes # unordered? 16831 fdbcc_un_no: 16831 fdbcc_un_no: 16832 bra.w fdbcc_false 16832 bra.w fdbcc_false # no; go handle counter 16833 fdbcc_un_yes: 16833 fdbcc_un_yes: 16834 rts 16834 rts # yes; do nothing 16835 16835 16836 ############################################ 16836 ####################################################################### 16837 16837 16838 # 16838 # 16839 # the bsun exception bit was not set. 16839 # the bsun exception bit was not set. 16840 # 16840 # 16841 # (1) subtract 1 from the count register 16841 # (1) subtract 1 from the count register 16842 # (2) if (cr == -1) then 16842 # (2) if (cr == -1) then 16843 # pc = pc of next instruction 16843 # pc = pc of next instruction 16844 # else 16844 # else 16845 # pc += sign_ext(16-bit displacement) 16845 # pc += sign_ext(16-bit displacement) 16846 # 16846 # 16847 fdbcc_false: 16847 fdbcc_false: 16848 mov.b 1+EXC_OPWORD(%a6), % 16848 mov.b 1+EXC_OPWORD(%a6), %d1 # fetch lo opword 16849 andi.w &0x7, %d1 16849 andi.w &0x7, %d1 # extract count register 16850 16850 16851 bsr.l fetch_dreg 16851 bsr.l fetch_dreg # fetch count value 16852 # make sure that d0 isn't corrupted between 16852 # make sure that d0 isn't corrupted between calls... 16853 16853 16854 subq.w &0x1, %d0 16854 subq.w &0x1, %d0 # Dn - 1 -> Dn 16855 16855 16856 bsr.l store_dreg_l 16856 bsr.l store_dreg_l # store new count value 16857 16857 16858 cmpi.w %d0, &-0x1 16858 cmpi.w %d0, &-0x1 # is (Dn == -1)? 16859 bne.b fdbcc_false_cont 16859 bne.b fdbcc_false_cont # no; 16860 rts 16860 rts 16861 16861 16862 fdbcc_false_cont: 16862 fdbcc_false_cont: 16863 mov.l L_SCR1(%a6),%d0 16863 mov.l L_SCR1(%a6),%d0 # fetch displacement 16864 add.l USER_FPIAR(%a6),%d0 16864 add.l USER_FPIAR(%a6),%d0 # add instruction PC 16865 addq.l &0x4,%d0 16865 addq.l &0x4,%d0 # add instruction length 16866 mov.l %d0,EXC_PC(%a6) 16866 mov.l %d0,EXC_PC(%a6) # set new PC 16867 rts 16867 rts 16868 16868 16869 # the emulation routine set bsun and BSUN wa 16869 # the emulation routine set bsun and BSUN was enabled. have to 16870 # fix stack and jump to the bsun handler. 16870 # fix stack and jump to the bsun handler. 16871 # let the caller of this routine shift the s 16871 # let the caller of this routine shift the stack frame up to 16872 # eliminate the effective address field. 16872 # eliminate the effective address field. 16873 fdbcc_bsun: 16873 fdbcc_bsun: 16874 mov.b &fbsun_flg,SPCOND_FL 16874 mov.b &fbsun_flg,SPCOND_FLG(%a6) 16875 rts 16875 rts 16876 16876 16877 ############################################ 16877 ######################################################################### 16878 # ftrapcc(): routine to emulate the ftrapcc 16878 # ftrapcc(): routine to emulate the ftrapcc instruction # 16879 # 16879 # # 16880 # XDEF ************************************* 16880 # XDEF **************************************************************** # 16881 # _ftrapcc() 16881 # _ftrapcc() # 16882 # 16882 # # 16883 # XREF ************************************* 16883 # XREF **************************************************************** # 16884 # none 16884 # none # 16885 # 16885 # # 16886 # INPUT ************************************ 16886 # INPUT *************************************************************** # 16887 # none 16887 # none # 16888 # 16888 # # 16889 # OUTPUT *********************************** 16889 # OUTPUT ************************************************************** # 16890 # none 16890 # none # 16891 # 16891 # # 16892 # ALGORITHM ******************************** 16892 # ALGORITHM *********************************************************** # 16893 # This routine checks which conditiona 16893 # This routine checks which conditional predicate is specified by # 16894 # the stacked ftrapcc instruction opcode and 16894 # the stacked ftrapcc instruction opcode and then branches to a routine # 16895 # for that predicate. The corresponding fbcc 16895 # for that predicate. The corresponding fbcc instruction is then used # 16896 # to see whether the condition (specified by 16896 # to see whether the condition (specified by the stacked FPSR) is true # 16897 # or false. 16897 # or false. # 16898 # If a BSUN exception should be indica 16898 # If a BSUN exception should be indicated, the BSUN and ABSUN # 16899 # bits are set in the stacked FPSR. If the B 16899 # bits are set in the stacked FPSR. If the BSUN exception is enabled, # 16900 # the fbsun_flg is set in the SPCOND_FLG loc 16900 # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an # 16901 # enabled BSUN should not be flagged and the 16901 # enabled BSUN should not be flagged and the predicate is true, then # 16902 # the ftrapcc_flg is set in the SPCOND_FLG l 16902 # the ftrapcc_flg is set in the SPCOND_FLG location. These special # 16903 # flags indicate to the calling routine to e 16903 # flags indicate to the calling routine to emulate the exceptional # 16904 # condition. 16904 # condition. # 16905 # 16905 # # 16906 ############################################ 16906 ######################################################################### 16907 16907 16908 global _ftrapcc 16908 global _ftrapcc 16909 _ftrapcc: 16909 _ftrapcc: 16910 mov.w EXC_CMDREG(%a6),%d0 16910 mov.w EXC_CMDREG(%a6),%d0 # fetch predicate 16911 16911 16912 clr.l %d1 16912 clr.l %d1 # clear scratch reg 16913 mov.b FPSR_CC(%a6),%d1 16913 mov.b FPSR_CC(%a6),%d1 # fetch fp ccodes 16914 ror.l &0x8,%d1 16914 ror.l &0x8,%d1 # rotate to top byte 16915 fmov.l %d1,%fpsr 16915 fmov.l %d1,%fpsr # insert into FPSR 16916 16916 16917 mov.w (tbl_ftrapcc.b,%pc,% 16917 mov.w (tbl_ftrapcc.b,%pc,%d0.w*2), %d1 # load table 16918 jmp (tbl_ftrapcc.b,%pc,% 16918 jmp (tbl_ftrapcc.b,%pc,%d1.w) # jump to ftrapcc routine 16919 16919 16920 tbl_ftrapcc: 16920 tbl_ftrapcc: 16921 short ftrapcc_f - 16921 short ftrapcc_f - tbl_ftrapcc # 00 16922 short ftrapcc_eq - 16922 short ftrapcc_eq - tbl_ftrapcc # 01 16923 short ftrapcc_ogt - 16923 short ftrapcc_ogt - tbl_ftrapcc # 02 16924 short ftrapcc_oge - 16924 short ftrapcc_oge - tbl_ftrapcc # 03 16925 short ftrapcc_olt - 16925 short ftrapcc_olt - tbl_ftrapcc # 04 16926 short ftrapcc_ole - 16926 short ftrapcc_ole - tbl_ftrapcc # 05 16927 short ftrapcc_ogl - 16927 short ftrapcc_ogl - tbl_ftrapcc # 06 16928 short ftrapcc_or - 16928 short ftrapcc_or - tbl_ftrapcc # 07 16929 short ftrapcc_un - 16929 short ftrapcc_un - tbl_ftrapcc # 08 16930 short ftrapcc_ueq - 16930 short ftrapcc_ueq - tbl_ftrapcc # 09 16931 short ftrapcc_ugt - 16931 short ftrapcc_ugt - tbl_ftrapcc # 10 16932 short ftrapcc_uge - 16932 short ftrapcc_uge - tbl_ftrapcc # 11 16933 short ftrapcc_ult - 16933 short ftrapcc_ult - tbl_ftrapcc # 12 16934 short ftrapcc_ule - 16934 short ftrapcc_ule - tbl_ftrapcc # 13 16935 short ftrapcc_neq - 16935 short ftrapcc_neq - tbl_ftrapcc # 14 16936 short ftrapcc_t - 16936 short ftrapcc_t - tbl_ftrapcc # 15 16937 short ftrapcc_sf - 16937 short ftrapcc_sf - tbl_ftrapcc # 16 16938 short ftrapcc_seq - 16938 short ftrapcc_seq - tbl_ftrapcc # 17 16939 short ftrapcc_gt - 16939 short ftrapcc_gt - tbl_ftrapcc # 18 16940 short ftrapcc_ge - 16940 short ftrapcc_ge - tbl_ftrapcc # 19 16941 short ftrapcc_lt - 16941 short ftrapcc_lt - tbl_ftrapcc # 20 16942 short ftrapcc_le - 16942 short ftrapcc_le - tbl_ftrapcc # 21 16943 short ftrapcc_gl - 16943 short ftrapcc_gl - tbl_ftrapcc # 22 16944 short ftrapcc_gle - 16944 short ftrapcc_gle - tbl_ftrapcc # 23 16945 short ftrapcc_ngle - 16945 short ftrapcc_ngle - tbl_ftrapcc # 24 16946 short ftrapcc_ngl - 16946 short ftrapcc_ngl - tbl_ftrapcc # 25 16947 short ftrapcc_nle - 16947 short ftrapcc_nle - tbl_ftrapcc # 26 16948 short ftrapcc_nlt - 16948 short ftrapcc_nlt - tbl_ftrapcc # 27 16949 short ftrapcc_nge - 16949 short ftrapcc_nge - tbl_ftrapcc # 28 16950 short ftrapcc_ngt - 16950 short ftrapcc_ngt - tbl_ftrapcc # 29 16951 short ftrapcc_sneq - 16951 short ftrapcc_sneq - tbl_ftrapcc # 30 16952 short ftrapcc_st - 16952 short ftrapcc_st - tbl_ftrapcc # 31 16953 16953 16954 ############################################ 16954 ######################################################################### 16955 # 16955 # # 16956 # IEEE Nonaware tests 16956 # IEEE Nonaware tests # 16957 # 16957 # # 16958 # For the IEEE nonaware tests, we set the re 16958 # For the IEEE nonaware tests, we set the result based on the # 16959 # floating point condition codes. In additio 16959 # floating point condition codes. In addition, we check to see # 16960 # if the NAN bit is set, in which case BSUN 16960 # if the NAN bit is set, in which case BSUN and AIOP will be set. # 16961 # 16961 # # 16962 # The cases EQ and NE are shared by the Awar 16962 # The cases EQ and NE are shared by the Aware and Nonaware groups # 16963 # and are incapable of setting the BSUN exce 16963 # and are incapable of setting the BSUN exception bit. # 16964 # 16964 # # 16965 # Typically, only one of the two possible br 16965 # Typically, only one of the two possible branch directions could # 16966 # have the NAN bit set. 16966 # have the NAN bit set. # 16967 # 16967 # # 16968 ############################################ 16968 ######################################################################### 16969 16969 16970 # 16970 # 16971 # equal: 16971 # equal: 16972 # 16972 # 16973 # Z 16973 # Z 16974 # 16974 # 16975 ftrapcc_eq: 16975 ftrapcc_eq: 16976 fbeq.w ftrapcc_trap 16976 fbeq.w ftrapcc_trap # equal? 16977 ftrapcc_eq_no: 16977 ftrapcc_eq_no: 16978 rts 16978 rts # do nothing 16979 16979 16980 # 16980 # 16981 # not equal: 16981 # not equal: 16982 # _ 16982 # _ 16983 # Z 16983 # Z 16984 # 16984 # 16985 ftrapcc_neq: 16985 ftrapcc_neq: 16986 fbneq.w ftrapcc_trap 16986 fbneq.w ftrapcc_trap # not equal? 16987 ftrapcc_neq_no: 16987 ftrapcc_neq_no: 16988 rts 16988 rts # do nothing 16989 16989 16990 # 16990 # 16991 # greater than: 16991 # greater than: 16992 # _______ 16992 # _______ 16993 # NANvZvN 16993 # NANvZvN 16994 # 16994 # 16995 ftrapcc_gt: 16995 ftrapcc_gt: 16996 fbgt.w ftrapcc_trap 16996 fbgt.w ftrapcc_trap # greater than? 16997 ftrapcc_gt_no: 16997 ftrapcc_gt_no: 16998 btst &nan_bit, FPSR_CC(%a 16998 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 16999 beq.b ftrapcc_gt_done 16999 beq.b ftrapcc_gt_done # no 17000 ori.l &bsun_mask+aiop_mask 17000 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17001 btst &bsun_bit, FPCR_ENAB 17001 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17002 bne.w ftrapcc_bsun 17002 bne.w ftrapcc_bsun # yes 17003 ftrapcc_gt_done: 17003 ftrapcc_gt_done: 17004 rts 17004 rts # no; do nothing 17005 17005 17006 # 17006 # 17007 # not greater than: 17007 # not greater than: 17008 # 17008 # 17009 # NANvZvN 17009 # NANvZvN 17010 # 17010 # 17011 ftrapcc_ngt: 17011 ftrapcc_ngt: 17012 fbngt.w ftrapcc_ngt_yes 17012 fbngt.w ftrapcc_ngt_yes # not greater than? 17013 ftrapcc_ngt_no: 17013 ftrapcc_ngt_no: 17014 rts 17014 rts # do nothing 17015 ftrapcc_ngt_yes: 17015 ftrapcc_ngt_yes: 17016 btst &nan_bit, FPSR_CC(%a 17016 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17017 beq.w ftrapcc_trap 17017 beq.w ftrapcc_trap # no; go take trap 17018 ori.l &bsun_mask+aiop_mask 17018 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17019 btst &bsun_bit, FPCR_ENAB 17019 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17020 bne.w ftrapcc_bsun 17020 bne.w ftrapcc_bsun # yes 17021 bra.w ftrapcc_trap 17021 bra.w ftrapcc_trap # no; go take trap 17022 17022 17023 # 17023 # 17024 # greater than or equal: 17024 # greater than or equal: 17025 # _____ 17025 # _____ 17026 # Zv(NANvN) 17026 # Zv(NANvN) 17027 # 17027 # 17028 ftrapcc_ge: 17028 ftrapcc_ge: 17029 fbge.w ftrapcc_ge_yes 17029 fbge.w ftrapcc_ge_yes # greater than or equal? 17030 ftrapcc_ge_no: 17030 ftrapcc_ge_no: 17031 btst &nan_bit, FPSR_CC(%a 17031 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17032 beq.b ftrapcc_ge_done 17032 beq.b ftrapcc_ge_done # no; go finish 17033 ori.l &bsun_mask+aiop_mask 17033 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17034 btst &bsun_bit, FPCR_ENAB 17034 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17035 bne.w ftrapcc_bsun 17035 bne.w ftrapcc_bsun # yes 17036 ftrapcc_ge_done: 17036 ftrapcc_ge_done: 17037 rts 17037 rts # no; do nothing 17038 ftrapcc_ge_yes: 17038 ftrapcc_ge_yes: 17039 btst &nan_bit, FPSR_CC(%a 17039 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17040 beq.w ftrapcc_trap 17040 beq.w ftrapcc_trap # no; go take trap 17041 ori.l &bsun_mask+aiop_mask 17041 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17042 btst &bsun_bit, FPCR_ENAB 17042 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17043 bne.w ftrapcc_bsun 17043 bne.w ftrapcc_bsun # yes 17044 bra.w ftrapcc_trap 17044 bra.w ftrapcc_trap # no; go take trap 17045 17045 17046 # 17046 # 17047 # not (greater than or equal): 17047 # not (greater than or equal): 17048 # _ 17048 # _ 17049 # NANv(N^Z) 17049 # NANv(N^Z) 17050 # 17050 # 17051 ftrapcc_nge: 17051 ftrapcc_nge: 17052 fbnge.w ftrapcc_nge_yes 17052 fbnge.w ftrapcc_nge_yes # not (greater than or equal)? 17053 ftrapcc_nge_no: 17053 ftrapcc_nge_no: 17054 rts 17054 rts # do nothing 17055 ftrapcc_nge_yes: 17055 ftrapcc_nge_yes: 17056 btst &nan_bit, FPSR_CC(%a 17056 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17057 beq.w ftrapcc_trap 17057 beq.w ftrapcc_trap # no; go take trap 17058 ori.l &bsun_mask+aiop_mask 17058 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17059 btst &bsun_bit, FPCR_ENAB 17059 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17060 bne.w ftrapcc_bsun 17060 bne.w ftrapcc_bsun # yes 17061 bra.w ftrapcc_trap 17061 bra.w ftrapcc_trap # no; go take trap 17062 17062 17063 # 17063 # 17064 # less than: 17064 # less than: 17065 # _____ 17065 # _____ 17066 # N^(NANvZ) 17066 # N^(NANvZ) 17067 # 17067 # 17068 ftrapcc_lt: 17068 ftrapcc_lt: 17069 fblt.w ftrapcc_trap 17069 fblt.w ftrapcc_trap # less than? 17070 ftrapcc_lt_no: 17070 ftrapcc_lt_no: 17071 btst &nan_bit, FPSR_CC(%a 17071 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17072 beq.b ftrapcc_lt_done 17072 beq.b ftrapcc_lt_done # no; go finish 17073 ori.l &bsun_mask+aiop_mask 17073 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17074 btst &bsun_bit, FPCR_ENAB 17074 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17075 bne.w ftrapcc_bsun 17075 bne.w ftrapcc_bsun # yes 17076 ftrapcc_lt_done: 17076 ftrapcc_lt_done: 17077 rts 17077 rts # no; do nothing 17078 17078 17079 # 17079 # 17080 # not less than: 17080 # not less than: 17081 # _ 17081 # _ 17082 # NANv(ZvN) 17082 # NANv(ZvN) 17083 # 17083 # 17084 ftrapcc_nlt: 17084 ftrapcc_nlt: 17085 fbnlt.w ftrapcc_nlt_yes 17085 fbnlt.w ftrapcc_nlt_yes # not less than? 17086 ftrapcc_nlt_no: 17086 ftrapcc_nlt_no: 17087 rts 17087 rts # do nothing 17088 ftrapcc_nlt_yes: 17088 ftrapcc_nlt_yes: 17089 btst &nan_bit, FPSR_CC(%a 17089 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17090 beq.w ftrapcc_trap 17090 beq.w ftrapcc_trap # no; go take trap 17091 ori.l &bsun_mask+aiop_mask 17091 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17092 btst &bsun_bit, FPCR_ENAB 17092 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17093 bne.w ftrapcc_bsun 17093 bne.w ftrapcc_bsun # yes 17094 bra.w ftrapcc_trap 17094 bra.w ftrapcc_trap # no; go take trap 17095 17095 17096 # 17096 # 17097 # less than or equal: 17097 # less than or equal: 17098 # ___ 17098 # ___ 17099 # Zv(N^NAN) 17099 # Zv(N^NAN) 17100 # 17100 # 17101 ftrapcc_le: 17101 ftrapcc_le: 17102 fble.w ftrapcc_le_yes 17102 fble.w ftrapcc_le_yes # less than or equal? 17103 ftrapcc_le_no: 17103 ftrapcc_le_no: 17104 btst &nan_bit, FPSR_CC(%a 17104 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17105 beq.b ftrapcc_le_done 17105 beq.b ftrapcc_le_done # no; go finish 17106 ori.l &bsun_mask+aiop_mask 17106 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17107 btst &bsun_bit, FPCR_ENAB 17107 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17108 bne.w ftrapcc_bsun 17108 bne.w ftrapcc_bsun # yes 17109 ftrapcc_le_done: 17109 ftrapcc_le_done: 17110 rts 17110 rts # no; do nothing 17111 ftrapcc_le_yes: 17111 ftrapcc_le_yes: 17112 btst &nan_bit, FPSR_CC(%a 17112 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17113 beq.w ftrapcc_trap 17113 beq.w ftrapcc_trap # no; go take trap 17114 ori.l &bsun_mask+aiop_mask 17114 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17115 btst &bsun_bit, FPCR_ENAB 17115 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17116 bne.w ftrapcc_bsun 17116 bne.w ftrapcc_bsun # yes 17117 bra.w ftrapcc_trap 17117 bra.w ftrapcc_trap # no; go take trap 17118 17118 17119 # 17119 # 17120 # not (less than or equal): 17120 # not (less than or equal): 17121 # ___ 17121 # ___ 17122 # NANv(NvZ) 17122 # NANv(NvZ) 17123 # 17123 # 17124 ftrapcc_nle: 17124 ftrapcc_nle: 17125 fbnle.w ftrapcc_nle_yes 17125 fbnle.w ftrapcc_nle_yes # not (less than or equal)? 17126 ftrapcc_nle_no: 17126 ftrapcc_nle_no: 17127 rts 17127 rts # do nothing 17128 ftrapcc_nle_yes: 17128 ftrapcc_nle_yes: 17129 btst &nan_bit, FPSR_CC(%a 17129 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17130 beq.w ftrapcc_trap 17130 beq.w ftrapcc_trap # no; go take trap 17131 ori.l &bsun_mask+aiop_mask 17131 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17132 btst &bsun_bit, FPCR_ENAB 17132 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17133 bne.w ftrapcc_bsun 17133 bne.w ftrapcc_bsun # yes 17134 bra.w ftrapcc_trap 17134 bra.w ftrapcc_trap # no; go take trap 17135 17135 17136 # 17136 # 17137 # greater or less than: 17137 # greater or less than: 17138 # _____ 17138 # _____ 17139 # NANvZ 17139 # NANvZ 17140 # 17140 # 17141 ftrapcc_gl: 17141 ftrapcc_gl: 17142 fbgl.w ftrapcc_trap 17142 fbgl.w ftrapcc_trap # greater or less than? 17143 ftrapcc_gl_no: 17143 ftrapcc_gl_no: 17144 btst &nan_bit, FPSR_CC(%a 17144 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17145 beq.b ftrapcc_gl_done 17145 beq.b ftrapcc_gl_done # no; go finish 17146 ori.l &bsun_mask+aiop_mask 17146 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17147 btst &bsun_bit, FPCR_ENAB 17147 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17148 bne.w ftrapcc_bsun 17148 bne.w ftrapcc_bsun # yes 17149 ftrapcc_gl_done: 17149 ftrapcc_gl_done: 17150 rts 17150 rts # no; do nothing 17151 17151 17152 # 17152 # 17153 # not (greater or less than): 17153 # not (greater or less than): 17154 # 17154 # 17155 # NANvZ 17155 # NANvZ 17156 # 17156 # 17157 ftrapcc_ngl: 17157 ftrapcc_ngl: 17158 fbngl.w ftrapcc_ngl_yes 17158 fbngl.w ftrapcc_ngl_yes # not (greater or less than)? 17159 ftrapcc_ngl_no: 17159 ftrapcc_ngl_no: 17160 rts 17160 rts # do nothing 17161 ftrapcc_ngl_yes: 17161 ftrapcc_ngl_yes: 17162 btst &nan_bit, FPSR_CC(%a 17162 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17163 beq.w ftrapcc_trap 17163 beq.w ftrapcc_trap # no; go take trap 17164 ori.l &bsun_mask+aiop_mask 17164 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17165 btst &bsun_bit, FPCR_ENAB 17165 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17166 bne.w ftrapcc_bsun 17166 bne.w ftrapcc_bsun # yes 17167 bra.w ftrapcc_trap 17167 bra.w ftrapcc_trap # no; go take trap 17168 17168 17169 # 17169 # 17170 # greater, less, or equal: 17170 # greater, less, or equal: 17171 # ___ 17171 # ___ 17172 # NAN 17172 # NAN 17173 # 17173 # 17174 ftrapcc_gle: 17174 ftrapcc_gle: 17175 fbgle.w ftrapcc_trap 17175 fbgle.w ftrapcc_trap # greater, less, or equal? 17176 ftrapcc_gle_no: 17176 ftrapcc_gle_no: 17177 ori.l &bsun_mask+aiop_mask 17177 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17178 btst &bsun_bit, FPCR_ENAB 17178 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17179 bne.w ftrapcc_bsun 17179 bne.w ftrapcc_bsun # yes 17180 rts 17180 rts # no; do nothing 17181 17181 17182 # 17182 # 17183 # not (greater, less, or equal): 17183 # not (greater, less, or equal): 17184 # 17184 # 17185 # NAN 17185 # NAN 17186 # 17186 # 17187 ftrapcc_ngle: 17187 ftrapcc_ngle: 17188 fbngle.w ftrapcc_ngle_yes 17188 fbngle.w ftrapcc_ngle_yes # not (greater, less, or equal)? 17189 ftrapcc_ngle_no: 17189 ftrapcc_ngle_no: 17190 rts 17190 rts # do nothing 17191 ftrapcc_ngle_yes: 17191 ftrapcc_ngle_yes: 17192 ori.l &bsun_mask+aiop_mask 17192 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17193 btst &bsun_bit, FPCR_ENAB 17193 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17194 bne.w ftrapcc_bsun 17194 bne.w ftrapcc_bsun # yes 17195 bra.w ftrapcc_trap 17195 bra.w ftrapcc_trap # no; go take trap 17196 17196 17197 ############################################ 17197 ######################################################################### 17198 # 17198 # # 17199 # Miscellaneous tests 17199 # Miscellaneous tests # 17200 # 17200 # # 17201 # For the IEEE aware tests, we only have to 17201 # For the IEEE aware tests, we only have to set the result based on the # 17202 # floating point condition codes. The BSUN e 17202 # floating point condition codes. The BSUN exception will not be # 17203 # set for any of these tests. 17203 # set for any of these tests. # 17204 # 17204 # # 17205 ############################################ 17205 ######################################################################### 17206 17206 17207 # 17207 # 17208 # false: 17208 # false: 17209 # 17209 # 17210 # False 17210 # False 17211 # 17211 # 17212 ftrapcc_f: 17212 ftrapcc_f: 17213 rts 17213 rts # do nothing 17214 17214 17215 # 17215 # 17216 # true: 17216 # true: 17217 # 17217 # 17218 # True 17218 # True 17219 # 17219 # 17220 ftrapcc_t: 17220 ftrapcc_t: 17221 bra.w ftrapcc_trap 17221 bra.w ftrapcc_trap # go take trap 17222 17222 17223 # 17223 # 17224 # signalling false: 17224 # signalling false: 17225 # 17225 # 17226 # False 17226 # False 17227 # 17227 # 17228 ftrapcc_sf: 17228 ftrapcc_sf: 17229 btst &nan_bit, FPSR_CC(%a 17229 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17230 beq.b ftrapcc_sf_done 17230 beq.b ftrapcc_sf_done # no; go finish 17231 ori.l &bsun_mask+aiop_mask 17231 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17232 btst &bsun_bit, FPCR_ENAB 17232 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17233 bne.w ftrapcc_bsun 17233 bne.w ftrapcc_bsun # yes 17234 ftrapcc_sf_done: 17234 ftrapcc_sf_done: 17235 rts 17235 rts # no; do nothing 17236 17236 17237 # 17237 # 17238 # signalling true: 17238 # signalling true: 17239 # 17239 # 17240 # True 17240 # True 17241 # 17241 # 17242 ftrapcc_st: 17242 ftrapcc_st: 17243 btst &nan_bit, FPSR_CC(%a 17243 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17244 beq.w ftrapcc_trap 17244 beq.w ftrapcc_trap # no; go take trap 17245 ori.l &bsun_mask+aiop_mask 17245 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17246 btst &bsun_bit, FPCR_ENAB 17246 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17247 bne.w ftrapcc_bsun 17247 bne.w ftrapcc_bsun # yes 17248 bra.w ftrapcc_trap 17248 bra.w ftrapcc_trap # no; go take trap 17249 17249 17250 # 17250 # 17251 # signalling equal: 17251 # signalling equal: 17252 # 17252 # 17253 # Z 17253 # Z 17254 # 17254 # 17255 ftrapcc_seq: 17255 ftrapcc_seq: 17256 fbseq.w ftrapcc_seq_yes 17256 fbseq.w ftrapcc_seq_yes # signalling equal? 17257 ftrapcc_seq_no: 17257 ftrapcc_seq_no: 17258 btst &nan_bit, FPSR_CC(%a 17258 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17259 beq.w ftrapcc_seq_done 17259 beq.w ftrapcc_seq_done # no; go finish 17260 ori.l &bsun_mask+aiop_mask 17260 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17261 btst &bsun_bit, FPCR_ENAB 17261 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17262 bne.w ftrapcc_bsun 17262 bne.w ftrapcc_bsun # yes 17263 ftrapcc_seq_done: 17263 ftrapcc_seq_done: 17264 rts 17264 rts # no; do nothing 17265 ftrapcc_seq_yes: 17265 ftrapcc_seq_yes: 17266 btst &nan_bit, FPSR_CC(%a 17266 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17267 beq.w ftrapcc_trap 17267 beq.w ftrapcc_trap # no; go take trap 17268 ori.l &bsun_mask+aiop_mask 17268 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17269 btst &bsun_bit, FPCR_ENAB 17269 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17270 bne.w ftrapcc_bsun 17270 bne.w ftrapcc_bsun # yes 17271 bra.w ftrapcc_trap 17271 bra.w ftrapcc_trap # no; go take trap 17272 17272 17273 # 17273 # 17274 # signalling not equal: 17274 # signalling not equal: 17275 # _ 17275 # _ 17276 # Z 17276 # Z 17277 # 17277 # 17278 ftrapcc_sneq: 17278 ftrapcc_sneq: 17279 fbsneq.w ftrapcc_sneq_yes 17279 fbsneq.w ftrapcc_sneq_yes # signalling equal? 17280 ftrapcc_sneq_no: 17280 ftrapcc_sneq_no: 17281 btst &nan_bit, FPSR_CC(%a 17281 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17282 beq.w ftrapcc_sneq_no_done 17282 beq.w ftrapcc_sneq_no_done # no; go finish 17283 ori.l &bsun_mask+aiop_mask 17283 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17284 btst &bsun_bit, FPCR_ENAB 17284 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17285 bne.w ftrapcc_bsun 17285 bne.w ftrapcc_bsun # yes 17286 ftrapcc_sneq_no_done: 17286 ftrapcc_sneq_no_done: 17287 rts 17287 rts # do nothing 17288 ftrapcc_sneq_yes: 17288 ftrapcc_sneq_yes: 17289 btst &nan_bit, FPSR_CC(%a 17289 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17290 beq.w ftrapcc_trap 17290 beq.w ftrapcc_trap # no; go take trap 17291 ori.l &bsun_mask+aiop_mask 17291 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17292 btst &bsun_bit, FPCR_ENAB 17292 btst &bsun_bit, FPCR_ENABLE(%a6) # was BSUN set? 17293 bne.w ftrapcc_bsun 17293 bne.w ftrapcc_bsun # yes 17294 bra.w ftrapcc_trap 17294 bra.w ftrapcc_trap # no; go take trap 17295 17295 17296 ############################################ 17296 ######################################################################### 17297 # 17297 # # 17298 # IEEE Aware tests 17298 # IEEE Aware tests # 17299 # 17299 # # 17300 # For the IEEE aware tests, we only have to 17300 # For the IEEE aware tests, we only have to set the result based on the # 17301 # floating point condition codes. The BSUN e 17301 # floating point condition codes. The BSUN exception will not be # 17302 # set for any of these tests. 17302 # set for any of these tests. # 17303 # 17303 # # 17304 ############################################ 17304 ######################################################################### 17305 17305 17306 # 17306 # 17307 # ordered greater than: 17307 # ordered greater than: 17308 # _______ 17308 # _______ 17309 # NANvZvN 17309 # NANvZvN 17310 # 17310 # 17311 ftrapcc_ogt: 17311 ftrapcc_ogt: 17312 fbogt.w ftrapcc_trap 17312 fbogt.w ftrapcc_trap # ordered greater than? 17313 ftrapcc_ogt_no: 17313 ftrapcc_ogt_no: 17314 rts 17314 rts # do nothing 17315 17315 17316 # 17316 # 17317 # unordered or less or equal: 17317 # unordered or less or equal: 17318 # _______ 17318 # _______ 17319 # NANvZvN 17319 # NANvZvN 17320 # 17320 # 17321 ftrapcc_ule: 17321 ftrapcc_ule: 17322 fbule.w ftrapcc_trap 17322 fbule.w ftrapcc_trap # unordered or less or equal? 17323 ftrapcc_ule_no: 17323 ftrapcc_ule_no: 17324 rts 17324 rts # do nothing 17325 17325 17326 # 17326 # 17327 # ordered greater than or equal: 17327 # ordered greater than or equal: 17328 # _____ 17328 # _____ 17329 # Zv(NANvN) 17329 # Zv(NANvN) 17330 # 17330 # 17331 ftrapcc_oge: 17331 ftrapcc_oge: 17332 fboge.w ftrapcc_trap 17332 fboge.w ftrapcc_trap # ordered greater than or equal? 17333 ftrapcc_oge_no: 17333 ftrapcc_oge_no: 17334 rts 17334 rts # do nothing 17335 17335 17336 # 17336 # 17337 # unordered or less than: 17337 # unordered or less than: 17338 # _ 17338 # _ 17339 # NANv(N^Z) 17339 # NANv(N^Z) 17340 # 17340 # 17341 ftrapcc_ult: 17341 ftrapcc_ult: 17342 fbult.w ftrapcc_trap 17342 fbult.w ftrapcc_trap # unordered or less than? 17343 ftrapcc_ult_no: 17343 ftrapcc_ult_no: 17344 rts 17344 rts # do nothing 17345 17345 17346 # 17346 # 17347 # ordered less than: 17347 # ordered less than: 17348 # _____ 17348 # _____ 17349 # N^(NANvZ) 17349 # N^(NANvZ) 17350 # 17350 # 17351 ftrapcc_olt: 17351 ftrapcc_olt: 17352 fbolt.w ftrapcc_trap 17352 fbolt.w ftrapcc_trap # ordered less than? 17353 ftrapcc_olt_no: 17353 ftrapcc_olt_no: 17354 rts 17354 rts # do nothing 17355 17355 17356 # 17356 # 17357 # unordered or greater or equal: 17357 # unordered or greater or equal: 17358 # 17358 # 17359 # NANvZvN 17359 # NANvZvN 17360 # 17360 # 17361 ftrapcc_uge: 17361 ftrapcc_uge: 17362 fbuge.w ftrapcc_trap 17362 fbuge.w ftrapcc_trap # unordered or greater than? 17363 ftrapcc_uge_no: 17363 ftrapcc_uge_no: 17364 rts 17364 rts # do nothing 17365 17365 17366 # 17366 # 17367 # ordered less than or equal: 17367 # ordered less than or equal: 17368 # ___ 17368 # ___ 17369 # Zv(N^NAN) 17369 # Zv(N^NAN) 17370 # 17370 # 17371 ftrapcc_ole: 17371 ftrapcc_ole: 17372 fbole.w ftrapcc_trap 17372 fbole.w ftrapcc_trap # ordered greater or less than? 17373 ftrapcc_ole_no: 17373 ftrapcc_ole_no: 17374 rts 17374 rts # do nothing 17375 17375 17376 # 17376 # 17377 # unordered or greater than: 17377 # unordered or greater than: 17378 # ___ 17378 # ___ 17379 # NANv(NvZ) 17379 # NANv(NvZ) 17380 # 17380 # 17381 ftrapcc_ugt: 17381 ftrapcc_ugt: 17382 fbugt.w ftrapcc_trap 17382 fbugt.w ftrapcc_trap # unordered or greater than? 17383 ftrapcc_ugt_no: 17383 ftrapcc_ugt_no: 17384 rts 17384 rts # do nothing 17385 17385 17386 # 17386 # 17387 # ordered greater or less than: 17387 # ordered greater or less than: 17388 # _____ 17388 # _____ 17389 # NANvZ 17389 # NANvZ 17390 # 17390 # 17391 ftrapcc_ogl: 17391 ftrapcc_ogl: 17392 fbogl.w ftrapcc_trap 17392 fbogl.w ftrapcc_trap # ordered greater or less than? 17393 ftrapcc_ogl_no: 17393 ftrapcc_ogl_no: 17394 rts 17394 rts # do nothing 17395 17395 17396 # 17396 # 17397 # unordered or equal: 17397 # unordered or equal: 17398 # 17398 # 17399 # NANvZ 17399 # NANvZ 17400 # 17400 # 17401 ftrapcc_ueq: 17401 ftrapcc_ueq: 17402 fbueq.w ftrapcc_trap 17402 fbueq.w ftrapcc_trap # unordered or equal? 17403 ftrapcc_ueq_no: 17403 ftrapcc_ueq_no: 17404 rts 17404 rts # do nothing 17405 17405 17406 # 17406 # 17407 # ordered: 17407 # ordered: 17408 # ___ 17408 # ___ 17409 # NAN 17409 # NAN 17410 # 17410 # 17411 ftrapcc_or: 17411 ftrapcc_or: 17412 fbor.w ftrapcc_trap 17412 fbor.w ftrapcc_trap # ordered? 17413 ftrapcc_or_no: 17413 ftrapcc_or_no: 17414 rts 17414 rts # do nothing 17415 17415 17416 # 17416 # 17417 # unordered: 17417 # unordered: 17418 # 17418 # 17419 # NAN 17419 # NAN 17420 # 17420 # 17421 ftrapcc_un: 17421 ftrapcc_un: 17422 fbun.w ftrapcc_trap 17422 fbun.w ftrapcc_trap # unordered? 17423 ftrapcc_un_no: 17423 ftrapcc_un_no: 17424 rts 17424 rts # do nothing 17425 17425 17426 ############################################ 17426 ####################################################################### 17427 17427 17428 # the bsun exception bit was not set. 17428 # the bsun exception bit was not set. 17429 # we will need to jump to the ftrapcc vector 17429 # we will need to jump to the ftrapcc vector. the stack frame 17430 # is the same size as that of the fp unimp i 17430 # is the same size as that of the fp unimp instruction. the 17431 # only difference is that the <ea> field sho 17431 # only difference is that the <ea> field should hold the PC 17432 # of the ftrapcc instruction and the vector 17432 # of the ftrapcc instruction and the vector offset field 17433 # should denote the ftrapcc trap. 17433 # should denote the ftrapcc trap. 17434 ftrapcc_trap: 17434 ftrapcc_trap: 17435 mov.b &ftrapcc_flg,SPCOND_ 17435 mov.b &ftrapcc_flg,SPCOND_FLG(%a6) 17436 rts 17436 rts 17437 17437 17438 # the emulation routine set bsun and BSUN wa 17438 # the emulation routine set bsun and BSUN was enabled. have to 17439 # fix stack and jump to the bsun handler. 17439 # fix stack and jump to the bsun handler. 17440 # let the caller of this routine shift the s 17440 # let the caller of this routine shift the stack frame up to 17441 # eliminate the effective address field. 17441 # eliminate the effective address field. 17442 ftrapcc_bsun: 17442 ftrapcc_bsun: 17443 mov.b &fbsun_flg,SPCOND_FL 17443 mov.b &fbsun_flg,SPCOND_FLG(%a6) 17444 rts 17444 rts 17445 17445 17446 ############################################ 17446 ######################################################################### 17447 # fscc(): routine to emulate the fscc instru 17447 # fscc(): routine to emulate the fscc instruction # 17448 # 17448 # # 17449 # XDEF ************************************* 17449 # XDEF **************************************************************** # 17450 # _fscc() 17450 # _fscc() # 17451 # 17451 # # 17452 # XREF ************************************* 17452 # XREF **************************************************************** # 17453 # store_dreg_b() - store result to dat 17453 # store_dreg_b() - store result to data register file # 17454 # dec_areg() - decrement an areg for - 17454 # dec_areg() - decrement an areg for -(an) mode # 17455 # inc_areg() - increment an areg for ( 17455 # inc_areg() - increment an areg for (an)+ mode # 17456 # _dmem_write_byte() - store result to 17456 # _dmem_write_byte() - store result to memory # 17457 # 17457 # # 17458 # INPUT ************************************ 17458 # INPUT *************************************************************** # 17459 # none 17459 # none # 17460 # 17460 # # 17461 # OUTPUT *********************************** 17461 # OUTPUT ************************************************************** # 17462 # none 17462 # none # 17463 # 17463 # # 17464 # ALGORITHM ******************************** 17464 # ALGORITHM *********************************************************** # 17465 # This routine checks which conditiona 17465 # This routine checks which conditional predicate is specified by # 17466 # the stacked fscc instruction opcode and th 17466 # the stacked fscc instruction opcode and then branches to a routine # 17467 # for that predicate. The corresponding fbcc 17467 # for that predicate. The corresponding fbcc instruction is then used # 17468 # to see whether the condition (specified by 17468 # to see whether the condition (specified by the stacked FPSR) is true # 17469 # or false. 17469 # or false. # 17470 # If a BSUN exception should be indica 17470 # If a BSUN exception should be indicated, the BSUN and ABSUN # 17471 # bits are set in the stacked FPSR. If the B 17471 # bits are set in the stacked FPSR. If the BSUN exception is enabled, # 17472 # the fbsun_flg is set in the SPCOND_FLG loc 17472 # the fbsun_flg is set in the SPCOND_FLG location on the stack. If an # 17473 # enabled BSUN should not be flagged and the 17473 # enabled BSUN should not be flagged and the predicate is true, then # 17474 # the result is stored to the data register 17474 # the result is stored to the data register file or memory # 17475 # 17475 # # 17476 ############################################ 17476 ######################################################################### 17477 17477 17478 global _fscc 17478 global _fscc 17479 _fscc: 17479 _fscc: 17480 mov.w EXC_CMDREG(%a6),%d0 17480 mov.w EXC_CMDREG(%a6),%d0 # fetch predicate 17481 17481 17482 clr.l %d1 17482 clr.l %d1 # clear scratch reg 17483 mov.b FPSR_CC(%a6),%d1 17483 mov.b FPSR_CC(%a6),%d1 # fetch fp ccodes 17484 ror.l &0x8,%d1 17484 ror.l &0x8,%d1 # rotate to top byte 17485 fmov.l %d1,%fpsr 17485 fmov.l %d1,%fpsr # insert into FPSR 17486 17486 17487 mov.w (tbl_fscc.b,%pc,%d0. 17487 mov.w (tbl_fscc.b,%pc,%d0.w*2),%d1 # load table 17488 jmp (tbl_fscc.b,%pc,%d1. 17488 jmp (tbl_fscc.b,%pc,%d1.w) # jump to fscc routine 17489 17489 17490 tbl_fscc: 17490 tbl_fscc: 17491 short fscc_f - 17491 short fscc_f - tbl_fscc # 00 17492 short fscc_eq - 17492 short fscc_eq - tbl_fscc # 01 17493 short fscc_ogt - 17493 short fscc_ogt - tbl_fscc # 02 17494 short fscc_oge - 17494 short fscc_oge - tbl_fscc # 03 17495 short fscc_olt - 17495 short fscc_olt - tbl_fscc # 04 17496 short fscc_ole - 17496 short fscc_ole - tbl_fscc # 05 17497 short fscc_ogl - 17497 short fscc_ogl - tbl_fscc # 06 17498 short fscc_or - 17498 short fscc_or - tbl_fscc # 07 17499 short fscc_un - 17499 short fscc_un - tbl_fscc # 08 17500 short fscc_ueq - 17500 short fscc_ueq - tbl_fscc # 09 17501 short fscc_ugt - 17501 short fscc_ugt - tbl_fscc # 10 17502 short fscc_uge - 17502 short fscc_uge - tbl_fscc # 11 17503 short fscc_ult - 17503 short fscc_ult - tbl_fscc # 12 17504 short fscc_ule - 17504 short fscc_ule - tbl_fscc # 13 17505 short fscc_neq - 17505 short fscc_neq - tbl_fscc # 14 17506 short fscc_t - 17506 short fscc_t - tbl_fscc # 15 17507 short fscc_sf - 17507 short fscc_sf - tbl_fscc # 16 17508 short fscc_seq - 17508 short fscc_seq - tbl_fscc # 17 17509 short fscc_gt - 17509 short fscc_gt - tbl_fscc # 18 17510 short fscc_ge - 17510 short fscc_ge - tbl_fscc # 19 17511 short fscc_lt - 17511 short fscc_lt - tbl_fscc # 20 17512 short fscc_le - 17512 short fscc_le - tbl_fscc # 21 17513 short fscc_gl - 17513 short fscc_gl - tbl_fscc # 22 17514 short fscc_gle - 17514 short fscc_gle - tbl_fscc # 23 17515 short fscc_ngle - 17515 short fscc_ngle - tbl_fscc # 24 17516 short fscc_ngl - 17516 short fscc_ngl - tbl_fscc # 25 17517 short fscc_nle - 17517 short fscc_nle - tbl_fscc # 26 17518 short fscc_nlt - 17518 short fscc_nlt - tbl_fscc # 27 17519 short fscc_nge - 17519 short fscc_nge - tbl_fscc # 28 17520 short fscc_ngt - 17520 short fscc_ngt - tbl_fscc # 29 17521 short fscc_sneq - 17521 short fscc_sneq - tbl_fscc # 30 17522 short fscc_st - 17522 short fscc_st - tbl_fscc # 31 17523 17523 17524 ############################################ 17524 ######################################################################### 17525 # 17525 # # 17526 # IEEE Nonaware tests 17526 # IEEE Nonaware tests # 17527 # 17527 # # 17528 # For the IEEE nonaware tests, we set the re 17528 # For the IEEE nonaware tests, we set the result based on the # 17529 # floating point condition codes. In additio 17529 # floating point condition codes. In addition, we check to see # 17530 # if the NAN bit is set, in which case BSUN 17530 # if the NAN bit is set, in which case BSUN and AIOP will be set. # 17531 # 17531 # # 17532 # The cases EQ and NE are shared by the Awar 17532 # The cases EQ and NE are shared by the Aware and Nonaware groups # 17533 # and are incapable of setting the BSUN exce 17533 # and are incapable of setting the BSUN exception bit. # 17534 # 17534 # # 17535 # Typically, only one of the two possible br 17535 # Typically, only one of the two possible branch directions could # 17536 # have the NAN bit set. 17536 # have the NAN bit set. # 17537 # 17537 # # 17538 ############################################ 17538 ######################################################################### 17539 17539 17540 # 17540 # 17541 # equal: 17541 # equal: 17542 # 17542 # 17543 # Z 17543 # Z 17544 # 17544 # 17545 fscc_eq: 17545 fscc_eq: 17546 fbeq.w fscc_eq_yes 17546 fbeq.w fscc_eq_yes # equal? 17547 fscc_eq_no: 17547 fscc_eq_no: 17548 clr.b %d0 17548 clr.b %d0 # set false 17549 bra.w fscc_done 17549 bra.w fscc_done # go finish 17550 fscc_eq_yes: 17550 fscc_eq_yes: 17551 st %d0 17551 st %d0 # set true 17552 bra.w fscc_done 17552 bra.w fscc_done # go finish 17553 17553 17554 # 17554 # 17555 # not equal: 17555 # not equal: 17556 # _ 17556 # _ 17557 # Z 17557 # Z 17558 # 17558 # 17559 fscc_neq: 17559 fscc_neq: 17560 fbneq.w fscc_neq_yes 17560 fbneq.w fscc_neq_yes # not equal? 17561 fscc_neq_no: 17561 fscc_neq_no: 17562 clr.b %d0 17562 clr.b %d0 # set false 17563 bra.w fscc_done 17563 bra.w fscc_done # go finish 17564 fscc_neq_yes: 17564 fscc_neq_yes: 17565 st %d0 17565 st %d0 # set true 17566 bra.w fscc_done 17566 bra.w fscc_done # go finish 17567 17567 17568 # 17568 # 17569 # greater than: 17569 # greater than: 17570 # _______ 17570 # _______ 17571 # NANvZvN 17571 # NANvZvN 17572 # 17572 # 17573 fscc_gt: 17573 fscc_gt: 17574 fbgt.w fscc_gt_yes 17574 fbgt.w fscc_gt_yes # greater than? 17575 fscc_gt_no: 17575 fscc_gt_no: 17576 clr.b %d0 17576 clr.b %d0 # set false 17577 btst &nan_bit, FPSR_CC(%a 17577 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17578 beq.w fscc_done 17578 beq.w fscc_done # no;go finish 17579 ori.l &bsun_mask+aiop_mask 17579 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17580 bra.w fscc_chk_bsun 17580 bra.w fscc_chk_bsun # go finish 17581 fscc_gt_yes: 17581 fscc_gt_yes: 17582 st %d0 17582 st %d0 # set true 17583 bra.w fscc_done 17583 bra.w fscc_done # go finish 17584 17584 17585 # 17585 # 17586 # not greater than: 17586 # not greater than: 17587 # 17587 # 17588 # NANvZvN 17588 # NANvZvN 17589 # 17589 # 17590 fscc_ngt: 17590 fscc_ngt: 17591 fbngt.w fscc_ngt_yes 17591 fbngt.w fscc_ngt_yes # not greater than? 17592 fscc_ngt_no: 17592 fscc_ngt_no: 17593 clr.b %d0 17593 clr.b %d0 # set false 17594 bra.w fscc_done 17594 bra.w fscc_done # go finish 17595 fscc_ngt_yes: 17595 fscc_ngt_yes: 17596 st %d0 17596 st %d0 # set true 17597 btst &nan_bit, FPSR_CC(%a 17597 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17598 beq.w fscc_done 17598 beq.w fscc_done # no;go finish 17599 ori.l &bsun_mask+aiop_mask 17599 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17600 bra.w fscc_chk_bsun 17600 bra.w fscc_chk_bsun # go finish 17601 17601 17602 # 17602 # 17603 # greater than or equal: 17603 # greater than or equal: 17604 # _____ 17604 # _____ 17605 # Zv(NANvN) 17605 # Zv(NANvN) 17606 # 17606 # 17607 fscc_ge: 17607 fscc_ge: 17608 fbge.w fscc_ge_yes 17608 fbge.w fscc_ge_yes # greater than or equal? 17609 fscc_ge_no: 17609 fscc_ge_no: 17610 clr.b %d0 17610 clr.b %d0 # set false 17611 btst &nan_bit, FPSR_CC(%a 17611 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17612 beq.w fscc_done 17612 beq.w fscc_done # no;go finish 17613 ori.l &bsun_mask+aiop_mask 17613 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17614 bra.w fscc_chk_bsun 17614 bra.w fscc_chk_bsun # go finish 17615 fscc_ge_yes: 17615 fscc_ge_yes: 17616 st %d0 17616 st %d0 # set true 17617 btst &nan_bit, FPSR_CC(%a 17617 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17618 beq.w fscc_done 17618 beq.w fscc_done # no;go finish 17619 ori.l &bsun_mask+aiop_mask 17619 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17620 bra.w fscc_chk_bsun 17620 bra.w fscc_chk_bsun # go finish 17621 17621 17622 # 17622 # 17623 # not (greater than or equal): 17623 # not (greater than or equal): 17624 # _ 17624 # _ 17625 # NANv(N^Z) 17625 # NANv(N^Z) 17626 # 17626 # 17627 fscc_nge: 17627 fscc_nge: 17628 fbnge.w fscc_nge_yes 17628 fbnge.w fscc_nge_yes # not (greater than or equal)? 17629 fscc_nge_no: 17629 fscc_nge_no: 17630 clr.b %d0 17630 clr.b %d0 # set false 17631 bra.w fscc_done 17631 bra.w fscc_done # go finish 17632 fscc_nge_yes: 17632 fscc_nge_yes: 17633 st %d0 17633 st %d0 # set true 17634 btst &nan_bit, FPSR_CC(%a 17634 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17635 beq.w fscc_done 17635 beq.w fscc_done # no;go finish 17636 ori.l &bsun_mask+aiop_mask 17636 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17637 bra.w fscc_chk_bsun 17637 bra.w fscc_chk_bsun # go finish 17638 17638 17639 # 17639 # 17640 # less than: 17640 # less than: 17641 # _____ 17641 # _____ 17642 # N^(NANvZ) 17642 # N^(NANvZ) 17643 # 17643 # 17644 fscc_lt: 17644 fscc_lt: 17645 fblt.w fscc_lt_yes 17645 fblt.w fscc_lt_yes # less than? 17646 fscc_lt_no: 17646 fscc_lt_no: 17647 clr.b %d0 17647 clr.b %d0 # set false 17648 btst &nan_bit, FPSR_CC(%a 17648 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17649 beq.w fscc_done 17649 beq.w fscc_done # no;go finish 17650 ori.l &bsun_mask+aiop_mask 17650 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17651 bra.w fscc_chk_bsun 17651 bra.w fscc_chk_bsun # go finish 17652 fscc_lt_yes: 17652 fscc_lt_yes: 17653 st %d0 17653 st %d0 # set true 17654 bra.w fscc_done 17654 bra.w fscc_done # go finish 17655 17655 17656 # 17656 # 17657 # not less than: 17657 # not less than: 17658 # _ 17658 # _ 17659 # NANv(ZvN) 17659 # NANv(ZvN) 17660 # 17660 # 17661 fscc_nlt: 17661 fscc_nlt: 17662 fbnlt.w fscc_nlt_yes 17662 fbnlt.w fscc_nlt_yes # not less than? 17663 fscc_nlt_no: 17663 fscc_nlt_no: 17664 clr.b %d0 17664 clr.b %d0 # set false 17665 bra.w fscc_done 17665 bra.w fscc_done # go finish 17666 fscc_nlt_yes: 17666 fscc_nlt_yes: 17667 st %d0 17667 st %d0 # set true 17668 btst &nan_bit, FPSR_CC(%a 17668 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17669 beq.w fscc_done 17669 beq.w fscc_done # no;go finish 17670 ori.l &bsun_mask+aiop_mask 17670 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17671 bra.w fscc_chk_bsun 17671 bra.w fscc_chk_bsun # go finish 17672 17672 17673 # 17673 # 17674 # less than or equal: 17674 # less than or equal: 17675 # ___ 17675 # ___ 17676 # Zv(N^NAN) 17676 # Zv(N^NAN) 17677 # 17677 # 17678 fscc_le: 17678 fscc_le: 17679 fble.w fscc_le_yes 17679 fble.w fscc_le_yes # less than or equal? 17680 fscc_le_no: 17680 fscc_le_no: 17681 clr.b %d0 17681 clr.b %d0 # set false 17682 btst &nan_bit, FPSR_CC(%a 17682 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17683 beq.w fscc_done 17683 beq.w fscc_done # no;go finish 17684 ori.l &bsun_mask+aiop_mask 17684 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17685 bra.w fscc_chk_bsun 17685 bra.w fscc_chk_bsun # go finish 17686 fscc_le_yes: 17686 fscc_le_yes: 17687 st %d0 17687 st %d0 # set true 17688 btst &nan_bit, FPSR_CC(%a 17688 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17689 beq.w fscc_done 17689 beq.w fscc_done # no;go finish 17690 ori.l &bsun_mask+aiop_mask 17690 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17691 bra.w fscc_chk_bsun 17691 bra.w fscc_chk_bsun # go finish 17692 17692 17693 # 17693 # 17694 # not (less than or equal): 17694 # not (less than or equal): 17695 # ___ 17695 # ___ 17696 # NANv(NvZ) 17696 # NANv(NvZ) 17697 # 17697 # 17698 fscc_nle: 17698 fscc_nle: 17699 fbnle.w fscc_nle_yes 17699 fbnle.w fscc_nle_yes # not (less than or equal)? 17700 fscc_nle_no: 17700 fscc_nle_no: 17701 clr.b %d0 17701 clr.b %d0 # set false 17702 bra.w fscc_done 17702 bra.w fscc_done # go finish 17703 fscc_nle_yes: 17703 fscc_nle_yes: 17704 st %d0 17704 st %d0 # set true 17705 btst &nan_bit, FPSR_CC(%a 17705 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17706 beq.w fscc_done 17706 beq.w fscc_done # no;go finish 17707 ori.l &bsun_mask+aiop_mask 17707 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17708 bra.w fscc_chk_bsun 17708 bra.w fscc_chk_bsun # go finish 17709 17709 17710 # 17710 # 17711 # greater or less than: 17711 # greater or less than: 17712 # _____ 17712 # _____ 17713 # NANvZ 17713 # NANvZ 17714 # 17714 # 17715 fscc_gl: 17715 fscc_gl: 17716 fbgl.w fscc_gl_yes 17716 fbgl.w fscc_gl_yes # greater or less than? 17717 fscc_gl_no: 17717 fscc_gl_no: 17718 clr.b %d0 17718 clr.b %d0 # set false 17719 btst &nan_bit, FPSR_CC(%a 17719 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17720 beq.w fscc_done 17720 beq.w fscc_done # no;go finish 17721 ori.l &bsun_mask+aiop_mask 17721 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17722 bra.w fscc_chk_bsun 17722 bra.w fscc_chk_bsun # go finish 17723 fscc_gl_yes: 17723 fscc_gl_yes: 17724 st %d0 17724 st %d0 # set true 17725 bra.w fscc_done 17725 bra.w fscc_done # go finish 17726 17726 17727 # 17727 # 17728 # not (greater or less than): 17728 # not (greater or less than): 17729 # 17729 # 17730 # NANvZ 17730 # NANvZ 17731 # 17731 # 17732 fscc_ngl: 17732 fscc_ngl: 17733 fbngl.w fscc_ngl_yes 17733 fbngl.w fscc_ngl_yes # not (greater or less than)? 17734 fscc_ngl_no: 17734 fscc_ngl_no: 17735 clr.b %d0 17735 clr.b %d0 # set false 17736 bra.w fscc_done 17736 bra.w fscc_done # go finish 17737 fscc_ngl_yes: 17737 fscc_ngl_yes: 17738 st %d0 17738 st %d0 # set true 17739 btst &nan_bit, FPSR_CC(%a 17739 btst &nan_bit, FPSR_CC(%a6) # is NAN set in cc? 17740 beq.w fscc_done 17740 beq.w fscc_done # no;go finish 17741 ori.l &bsun_mask+aiop_mask 17741 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17742 bra.w fscc_chk_bsun 17742 bra.w fscc_chk_bsun # go finish 17743 17743 17744 # 17744 # 17745 # greater, less, or equal: 17745 # greater, less, or equal: 17746 # ___ 17746 # ___ 17747 # NAN 17747 # NAN 17748 # 17748 # 17749 fscc_gle: 17749 fscc_gle: 17750 fbgle.w fscc_gle_yes 17750 fbgle.w fscc_gle_yes # greater, less, or equal? 17751 fscc_gle_no: 17751 fscc_gle_no: 17752 clr.b %d0 17752 clr.b %d0 # set false 17753 ori.l &bsun_mask+aiop_mask 17753 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17754 bra.w fscc_chk_bsun 17754 bra.w fscc_chk_bsun # go finish 17755 fscc_gle_yes: 17755 fscc_gle_yes: 17756 st %d0 17756 st %d0 # set true 17757 bra.w fscc_done 17757 bra.w fscc_done # go finish 17758 17758 17759 # 17759 # 17760 # not (greater, less, or equal): 17760 # not (greater, less, or equal): 17761 # 17761 # 17762 # NAN 17762 # NAN 17763 # 17763 # 17764 fscc_ngle: 17764 fscc_ngle: 17765 fbngle.w fscc_ngle_ye 17765 fbngle.w fscc_ngle_yes # not (greater, less, or equal)? 17766 fscc_ngle_no: 17766 fscc_ngle_no: 17767 clr.b %d0 17767 clr.b %d0 # set false 17768 bra.w fscc_done 17768 bra.w fscc_done # go finish 17769 fscc_ngle_yes: 17769 fscc_ngle_yes: 17770 st %d0 17770 st %d0 # set true 17771 ori.l &bsun_mask+aiop_mask 17771 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17772 bra.w fscc_chk_bsun 17772 bra.w fscc_chk_bsun # go finish 17773 17773 17774 ############################################ 17774 ######################################################################### 17775 # 17775 # # 17776 # Miscellaneous tests 17776 # Miscellaneous tests # 17777 # 17777 # # 17778 # For the IEEE aware tests, we only have to 17778 # For the IEEE aware tests, we only have to set the result based on the # 17779 # floating point condition codes. The BSUN e 17779 # floating point condition codes. The BSUN exception will not be # 17780 # set for any of these tests. 17780 # set for any of these tests. # 17781 # 17781 # # 17782 ############################################ 17782 ######################################################################### 17783 17783 17784 # 17784 # 17785 # false: 17785 # false: 17786 # 17786 # 17787 # False 17787 # False 17788 # 17788 # 17789 fscc_f: 17789 fscc_f: 17790 clr.b %d0 17790 clr.b %d0 # set false 17791 bra.w fscc_done 17791 bra.w fscc_done # go finish 17792 17792 17793 # 17793 # 17794 # true: 17794 # true: 17795 # 17795 # 17796 # True 17796 # True 17797 # 17797 # 17798 fscc_t: 17798 fscc_t: 17799 st %d0 17799 st %d0 # set true 17800 bra.w fscc_done 17800 bra.w fscc_done # go finish 17801 17801 17802 # 17802 # 17803 # signalling false: 17803 # signalling false: 17804 # 17804 # 17805 # False 17805 # False 17806 # 17806 # 17807 fscc_sf: 17807 fscc_sf: 17808 clr.b %d0 17808 clr.b %d0 # set false 17809 btst &nan_bit, FPSR_CC(%a 17809 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17810 beq.w fscc_done 17810 beq.w fscc_done # no;go finish 17811 ori.l &bsun_mask+aiop_mask 17811 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17812 bra.w fscc_chk_bsun 17812 bra.w fscc_chk_bsun # go finish 17813 17813 17814 # 17814 # 17815 # signalling true: 17815 # signalling true: 17816 # 17816 # 17817 # True 17817 # True 17818 # 17818 # 17819 fscc_st: 17819 fscc_st: 17820 st %d0 17820 st %d0 # set false 17821 btst &nan_bit, FPSR_CC(%a 17821 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17822 beq.w fscc_done 17822 beq.w fscc_done # no;go finish 17823 ori.l &bsun_mask+aiop_mask 17823 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17824 bra.w fscc_chk_bsun 17824 bra.w fscc_chk_bsun # go finish 17825 17825 17826 # 17826 # 17827 # signalling equal: 17827 # signalling equal: 17828 # 17828 # 17829 # Z 17829 # Z 17830 # 17830 # 17831 fscc_seq: 17831 fscc_seq: 17832 fbseq.w fscc_seq_yes 17832 fbseq.w fscc_seq_yes # signalling equal? 17833 fscc_seq_no: 17833 fscc_seq_no: 17834 clr.b %d0 17834 clr.b %d0 # set false 17835 btst &nan_bit, FPSR_CC(%a 17835 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17836 beq.w fscc_done 17836 beq.w fscc_done # no;go finish 17837 ori.l &bsun_mask+aiop_mask 17837 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17838 bra.w fscc_chk_bsun 17838 bra.w fscc_chk_bsun # go finish 17839 fscc_seq_yes: 17839 fscc_seq_yes: 17840 st %d0 17840 st %d0 # set true 17841 btst &nan_bit, FPSR_CC(%a 17841 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17842 beq.w fscc_done 17842 beq.w fscc_done # no;go finish 17843 ori.l &bsun_mask+aiop_mask 17843 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17844 bra.w fscc_chk_bsun 17844 bra.w fscc_chk_bsun # go finish 17845 17845 17846 # 17846 # 17847 # signalling not equal: 17847 # signalling not equal: 17848 # _ 17848 # _ 17849 # Z 17849 # Z 17850 # 17850 # 17851 fscc_sneq: 17851 fscc_sneq: 17852 fbsneq.w fscc_sneq_yes 17852 fbsneq.w fscc_sneq_yes # signalling equal? 17853 fscc_sneq_no: 17853 fscc_sneq_no: 17854 clr.b %d0 17854 clr.b %d0 # set false 17855 btst &nan_bit, FPSR_CC(%a 17855 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17856 beq.w fscc_done 17856 beq.w fscc_done # no;go finish 17857 ori.l &bsun_mask+aiop_mask 17857 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17858 bra.w fscc_chk_bsun 17858 bra.w fscc_chk_bsun # go finish 17859 fscc_sneq_yes: 17859 fscc_sneq_yes: 17860 st %d0 17860 st %d0 # set true 17861 btst &nan_bit, FPSR_CC(%a 17861 btst &nan_bit, FPSR_CC(%a6) # set BSUN exc bit 17862 beq.w fscc_done 17862 beq.w fscc_done # no;go finish 17863 ori.l &bsun_mask+aiop_mask 17863 ori.l &bsun_mask+aiop_mask, USER_FPSR(%a6) # set BSUN exc bit 17864 bra.w fscc_chk_bsun 17864 bra.w fscc_chk_bsun # go finish 17865 17865 17866 ############################################ 17866 ######################################################################### 17867 # 17867 # # 17868 # IEEE Aware tests 17868 # IEEE Aware tests # 17869 # 17869 # # 17870 # For the IEEE aware tests, we only have to 17870 # For the IEEE aware tests, we only have to set the result based on the # 17871 # floating point condition codes. The BSUN e 17871 # floating point condition codes. The BSUN exception will not be # 17872 # set for any of these tests. 17872 # set for any of these tests. # 17873 # 17873 # # 17874 ############################################ 17874 ######################################################################### 17875 17875 17876 # 17876 # 17877 # ordered greater than: 17877 # ordered greater than: 17878 # _______ 17878 # _______ 17879 # NANvZvN 17879 # NANvZvN 17880 # 17880 # 17881 fscc_ogt: 17881 fscc_ogt: 17882 fbogt.w fscc_ogt_yes 17882 fbogt.w fscc_ogt_yes # ordered greater than? 17883 fscc_ogt_no: 17883 fscc_ogt_no: 17884 clr.b %d0 17884 clr.b %d0 # set false 17885 bra.w fscc_done 17885 bra.w fscc_done # go finish 17886 fscc_ogt_yes: 17886 fscc_ogt_yes: 17887 st %d0 17887 st %d0 # set true 17888 bra.w fscc_done 17888 bra.w fscc_done # go finish 17889 17889 17890 # 17890 # 17891 # unordered or less or equal: 17891 # unordered or less or equal: 17892 # _______ 17892 # _______ 17893 # NANvZvN 17893 # NANvZvN 17894 # 17894 # 17895 fscc_ule: 17895 fscc_ule: 17896 fbule.w fscc_ule_yes 17896 fbule.w fscc_ule_yes # unordered or less or equal? 17897 fscc_ule_no: 17897 fscc_ule_no: 17898 clr.b %d0 17898 clr.b %d0 # set false 17899 bra.w fscc_done 17899 bra.w fscc_done # go finish 17900 fscc_ule_yes: 17900 fscc_ule_yes: 17901 st %d0 17901 st %d0 # set true 17902 bra.w fscc_done 17902 bra.w fscc_done # go finish 17903 17903 17904 # 17904 # 17905 # ordered greater than or equal: 17905 # ordered greater than or equal: 17906 # _____ 17906 # _____ 17907 # Zv(NANvN) 17907 # Zv(NANvN) 17908 # 17908 # 17909 fscc_oge: 17909 fscc_oge: 17910 fboge.w fscc_oge_yes 17910 fboge.w fscc_oge_yes # ordered greater than or equal? 17911 fscc_oge_no: 17911 fscc_oge_no: 17912 clr.b %d0 17912 clr.b %d0 # set false 17913 bra.w fscc_done 17913 bra.w fscc_done # go finish 17914 fscc_oge_yes: 17914 fscc_oge_yes: 17915 st %d0 17915 st %d0 # set true 17916 bra.w fscc_done 17916 bra.w fscc_done # go finish 17917 17917 17918 # 17918 # 17919 # unordered or less than: 17919 # unordered or less than: 17920 # _ 17920 # _ 17921 # NANv(N^Z) 17921 # NANv(N^Z) 17922 # 17922 # 17923 fscc_ult: 17923 fscc_ult: 17924 fbult.w fscc_ult_yes 17924 fbult.w fscc_ult_yes # unordered or less than? 17925 fscc_ult_no: 17925 fscc_ult_no: 17926 clr.b %d0 17926 clr.b %d0 # set false 17927 bra.w fscc_done 17927 bra.w fscc_done # go finish 17928 fscc_ult_yes: 17928 fscc_ult_yes: 17929 st %d0 17929 st %d0 # set true 17930 bra.w fscc_done 17930 bra.w fscc_done # go finish 17931 17931 17932 # 17932 # 17933 # ordered less than: 17933 # ordered less than: 17934 # _____ 17934 # _____ 17935 # N^(NANvZ) 17935 # N^(NANvZ) 17936 # 17936 # 17937 fscc_olt: 17937 fscc_olt: 17938 fbolt.w fscc_olt_yes 17938 fbolt.w fscc_olt_yes # ordered less than? 17939 fscc_olt_no: 17939 fscc_olt_no: 17940 clr.b %d0 17940 clr.b %d0 # set false 17941 bra.w fscc_done 17941 bra.w fscc_done # go finish 17942 fscc_olt_yes: 17942 fscc_olt_yes: 17943 st %d0 17943 st %d0 # set true 17944 bra.w fscc_done 17944 bra.w fscc_done # go finish 17945 17945 17946 # 17946 # 17947 # unordered or greater or equal: 17947 # unordered or greater or equal: 17948 # 17948 # 17949 # NANvZvN 17949 # NANvZvN 17950 # 17950 # 17951 fscc_uge: 17951 fscc_uge: 17952 fbuge.w fscc_uge_yes 17952 fbuge.w fscc_uge_yes # unordered or greater than? 17953 fscc_uge_no: 17953 fscc_uge_no: 17954 clr.b %d0 17954 clr.b %d0 # set false 17955 bra.w fscc_done 17955 bra.w fscc_done # go finish 17956 fscc_uge_yes: 17956 fscc_uge_yes: 17957 st %d0 17957 st %d0 # set true 17958 bra.w fscc_done 17958 bra.w fscc_done # go finish 17959 17959 17960 # 17960 # 17961 # ordered less than or equal: 17961 # ordered less than or equal: 17962 # ___ 17962 # ___ 17963 # Zv(N^NAN) 17963 # Zv(N^NAN) 17964 # 17964 # 17965 fscc_ole: 17965 fscc_ole: 17966 fbole.w fscc_ole_yes 17966 fbole.w fscc_ole_yes # ordered greater or less than? 17967 fscc_ole_no: 17967 fscc_ole_no: 17968 clr.b %d0 17968 clr.b %d0 # set false 17969 bra.w fscc_done 17969 bra.w fscc_done # go finish 17970 fscc_ole_yes: 17970 fscc_ole_yes: 17971 st %d0 17971 st %d0 # set true 17972 bra.w fscc_done 17972 bra.w fscc_done # go finish 17973 17973 17974 # 17974 # 17975 # unordered or greater than: 17975 # unordered or greater than: 17976 # ___ 17976 # ___ 17977 # NANv(NvZ) 17977 # NANv(NvZ) 17978 # 17978 # 17979 fscc_ugt: 17979 fscc_ugt: 17980 fbugt.w fscc_ugt_yes 17980 fbugt.w fscc_ugt_yes # unordered or greater than? 17981 fscc_ugt_no: 17981 fscc_ugt_no: 17982 clr.b %d0 17982 clr.b %d0 # set false 17983 bra.w fscc_done 17983 bra.w fscc_done # go finish 17984 fscc_ugt_yes: 17984 fscc_ugt_yes: 17985 st %d0 17985 st %d0 # set true 17986 bra.w fscc_done 17986 bra.w fscc_done # go finish 17987 17987 17988 # 17988 # 17989 # ordered greater or less than: 17989 # ordered greater or less than: 17990 # _____ 17990 # _____ 17991 # NANvZ 17991 # NANvZ 17992 # 17992 # 17993 fscc_ogl: 17993 fscc_ogl: 17994 fbogl.w fscc_ogl_yes 17994 fbogl.w fscc_ogl_yes # ordered greater or less than? 17995 fscc_ogl_no: 17995 fscc_ogl_no: 17996 clr.b %d0 17996 clr.b %d0 # set false 17997 bra.w fscc_done 17997 bra.w fscc_done # go finish 17998 fscc_ogl_yes: 17998 fscc_ogl_yes: 17999 st %d0 17999 st %d0 # set true 18000 bra.w fscc_done 18000 bra.w fscc_done # go finish 18001 18001 18002 # 18002 # 18003 # unordered or equal: 18003 # unordered or equal: 18004 # 18004 # 18005 # NANvZ 18005 # NANvZ 18006 # 18006 # 18007 fscc_ueq: 18007 fscc_ueq: 18008 fbueq.w fscc_ueq_yes 18008 fbueq.w fscc_ueq_yes # unordered or equal? 18009 fscc_ueq_no: 18009 fscc_ueq_no: 18010 clr.b %d0 18010 clr.b %d0 # set false 18011 bra.w fscc_done 18011 bra.w fscc_done # go finish 18012 fscc_ueq_yes: 18012 fscc_ueq_yes: 18013 st %d0 18013 st %d0 # set true 18014 bra.w fscc_done 18014 bra.w fscc_done # go finish 18015 18015 18016 # 18016 # 18017 # ordered: 18017 # ordered: 18018 # ___ 18018 # ___ 18019 # NAN 18019 # NAN 18020 # 18020 # 18021 fscc_or: 18021 fscc_or: 18022 fbor.w fscc_or_yes 18022 fbor.w fscc_or_yes # ordered? 18023 fscc_or_no: 18023 fscc_or_no: 18024 clr.b %d0 18024 clr.b %d0 # set false 18025 bra.w fscc_done 18025 bra.w fscc_done # go finish 18026 fscc_or_yes: 18026 fscc_or_yes: 18027 st %d0 18027 st %d0 # set true 18028 bra.w fscc_done 18028 bra.w fscc_done # go finish 18029 18029 18030 # 18030 # 18031 # unordered: 18031 # unordered: 18032 # 18032 # 18033 # NAN 18033 # NAN 18034 # 18034 # 18035 fscc_un: 18035 fscc_un: 18036 fbun.w fscc_un_yes 18036 fbun.w fscc_un_yes # unordered? 18037 fscc_un_no: 18037 fscc_un_no: 18038 clr.b %d0 18038 clr.b %d0 # set false 18039 bra.w fscc_done 18039 bra.w fscc_done # go finish 18040 fscc_un_yes: 18040 fscc_un_yes: 18041 st %d0 18041 st %d0 # set true 18042 bra.w fscc_done 18042 bra.w fscc_done # go finish 18043 18043 18044 ############################################ 18044 ####################################################################### 18045 18045 18046 # 18046 # 18047 # the bsun exception bit was set. now, check 18047 # the bsun exception bit was set. now, check to see is BSUN 18048 # is enabled. if so, don't store result and 18048 # is enabled. if so, don't store result and correct stack frame 18049 # for a bsun exception. 18049 # for a bsun exception. 18050 # 18050 # 18051 fscc_chk_bsun: 18051 fscc_chk_bsun: 18052 btst &bsun_bit,FPCR_ENABL 18052 btst &bsun_bit,FPCR_ENABLE(%a6) # was BSUN set? 18053 bne.w fscc_bsun 18053 bne.w fscc_bsun 18054 18054 18055 # 18055 # 18056 # the bsun exception bit was not set. 18056 # the bsun exception bit was not set. 18057 # the result has been selected. 18057 # the result has been selected. 18058 # now, check to see if the result is to be s 18058 # now, check to see if the result is to be stored in the data register 18059 # file or in memory. 18059 # file or in memory. 18060 # 18060 # 18061 fscc_done: 18061 fscc_done: 18062 mov.l %d0,%a0 18062 mov.l %d0,%a0 # save result for a moment 18063 18063 18064 mov.b 1+EXC_OPWORD(%a6),%d 18064 mov.b 1+EXC_OPWORD(%a6),%d1 # fetch lo opword 18065 mov.l %d1,%d0 18065 mov.l %d1,%d0 # make a copy 18066 andi.b &0x38,%d1 18066 andi.b &0x38,%d1 # extract src mode 18067 18067 18068 bne.b fscc_mem_op 18068 bne.b fscc_mem_op # it's a memory operation 18069 18069 18070 mov.l %d0,%d1 18070 mov.l %d0,%d1 18071 andi.w &0x7,%d1 18071 andi.w &0x7,%d1 # pass index in d1 18072 mov.l %a0,%d0 18072 mov.l %a0,%d0 # pass result in d0 18073 bsr.l store_dreg_b 18073 bsr.l store_dreg_b # save result in regfile 18074 rts 18074 rts 18075 18075 18076 # 18076 # 18077 # the stacked <ea> is correct with the excep 18077 # the stacked <ea> is correct with the exception of: 18078 # -> Dn : <ea> is garbage 18078 # -> Dn : <ea> is garbage 18079 # 18079 # 18080 # if the addressing mode is post-increment o 18080 # if the addressing mode is post-increment or pre-decrement, 18081 # then the address registers have not been u 18081 # then the address registers have not been updated. 18082 # 18082 # 18083 fscc_mem_op: 18083 fscc_mem_op: 18084 cmpi.b %d1,&0x18 18084 cmpi.b %d1,&0x18 # is <ea> (An)+ ? 18085 beq.b fscc_mem_inc 18085 beq.b fscc_mem_inc # yes 18086 cmpi.b %d1,&0x20 18086 cmpi.b %d1,&0x20 # is <ea> -(An) ? 18087 beq.b fscc_mem_dec 18087 beq.b fscc_mem_dec # yes 18088 18088 18089 mov.l %a0,%d0 18089 mov.l %a0,%d0 # pass result in d0 18090 mov.l EXC_EA(%a6),%a0 18090 mov.l EXC_EA(%a6),%a0 # fetch <ea> 18091 bsr.l _dmem_write_byte 18091 bsr.l _dmem_write_byte # write result byte 18092 18092 18093 tst.l %d1 18093 tst.l %d1 # did dstore fail? 18094 bne.w fscc_err 18094 bne.w fscc_err # yes 18095 18095 18096 rts 18096 rts 18097 18097 18098 # addressing mode is post-increment. write t 18098 # addressing mode is post-increment. write the result byte. if the write 18099 # fails then don't update the address regist 18099 # fails then don't update the address register. if write passes then 18100 # call inc_areg() to update the address regi 18100 # call inc_areg() to update the address register. 18101 fscc_mem_inc: 18101 fscc_mem_inc: 18102 mov.l %a0,%d0 18102 mov.l %a0,%d0 # pass result in d0 18103 mov.l EXC_EA(%a6),%a0 18103 mov.l EXC_EA(%a6),%a0 # fetch <ea> 18104 bsr.l _dmem_write_byte 18104 bsr.l _dmem_write_byte # write result byte 18105 18105 18106 tst.l %d1 18106 tst.l %d1 # did dstore fail? 18107 bne.w fscc_err 18107 bne.w fscc_err # yes 18108 18108 18109 mov.b 0x1+EXC_OPWORD(%a6), 18109 mov.b 0x1+EXC_OPWORD(%a6),%d1 # fetch opword 18110 andi.w &0x7,%d1 18110 andi.w &0x7,%d1 # pass index in d1 18111 movq.l &0x1,%d0 18111 movq.l &0x1,%d0 # pass amt to inc by 18112 bsr.l inc_areg 18112 bsr.l inc_areg # increment address register 18113 18113 18114 rts 18114 rts 18115 18115 18116 # addressing mode is pre-decrement. write th 18116 # addressing mode is pre-decrement. write the result byte. if the write 18117 # fails then don't update the address regist 18117 # fails then don't update the address register. if the write passes then 18118 # call dec_areg() to update the address regi 18118 # call dec_areg() to update the address register. 18119 fscc_mem_dec: 18119 fscc_mem_dec: 18120 mov.l %a0,%d0 18120 mov.l %a0,%d0 # pass result in d0 18121 mov.l EXC_EA(%a6),%a0 18121 mov.l EXC_EA(%a6),%a0 # fetch <ea> 18122 bsr.l _dmem_write_byte 18122 bsr.l _dmem_write_byte # write result byte 18123 18123 18124 tst.l %d1 18124 tst.l %d1 # did dstore fail? 18125 bne.w fscc_err 18125 bne.w fscc_err # yes 18126 18126 18127 mov.b 0x1+EXC_OPWORD(%a6), 18127 mov.b 0x1+EXC_OPWORD(%a6),%d1 # fetch opword 18128 andi.w &0x7,%d1 18128 andi.w &0x7,%d1 # pass index in d1 18129 movq.l &0x1,%d0 18129 movq.l &0x1,%d0 # pass amt to dec by 18130 bsr.l dec_areg 18130 bsr.l dec_areg # decrement address register 18131 18131 18132 rts 18132 rts 18133 18133 18134 # the emulation routine set bsun and BSUN wa 18134 # the emulation routine set bsun and BSUN was enabled. have to 18135 # fix stack and jump to the bsun handler. 18135 # fix stack and jump to the bsun handler. 18136 # let the caller of this routine shift the s 18136 # let the caller of this routine shift the stack frame up to 18137 # eliminate the effective address field. 18137 # eliminate the effective address field. 18138 fscc_bsun: 18138 fscc_bsun: 18139 mov.b &fbsun_flg,SPCOND_FL 18139 mov.b &fbsun_flg,SPCOND_FLG(%a6) 18140 rts 18140 rts 18141 18141 18142 # the byte write to memory has failed. pass 18142 # the byte write to memory has failed. pass the failing effective address 18143 # and a FSLW to funimp_dacc(). 18143 # and a FSLW to funimp_dacc(). 18144 fscc_err: 18144 fscc_err: 18145 mov.w &0x00a1,EXC_VOFF(%a6 18145 mov.w &0x00a1,EXC_VOFF(%a6) 18146 bra.l facc_finish 18146 bra.l facc_finish 18147 18147 18148 ############################################ 18148 ######################################################################### 18149 # XDEF ************************************* 18149 # XDEF **************************************************************** # 18150 # fmovm_dynamic(): emulate "fmovm" dyn 18150 # fmovm_dynamic(): emulate "fmovm" dynamic instruction # 18151 # 18151 # # 18152 # XREF ************************************* 18152 # XREF **************************************************************** # 18153 # fetch_dreg() - fetch data register 18153 # fetch_dreg() - fetch data register # 18154 # {i,d,}mem_read() - fetch data from m 18154 # {i,d,}mem_read() - fetch data from memory # 18155 # _mem_write() - write data to memory 18155 # _mem_write() - write data to memory # 18156 # iea_iacc() - instruction memory acce 18156 # iea_iacc() - instruction memory access error occurred # 18157 # iea_dacc() - data memory access erro 18157 # iea_dacc() - data memory access error occurred # 18158 # restore() - restore An index regs if 18158 # restore() - restore An index regs if access error occurred # 18159 # 18159 # # 18160 # INPUT ************************************ 18160 # INPUT *************************************************************** # 18161 # None 18161 # None # 18162 # 18162 # # 18163 # OUTPUT *********************************** 18163 # OUTPUT ************************************************************** # 18164 # If instr is "fmovm Dn,-(A7)" from su 18164 # If instr is "fmovm Dn,-(A7)" from supervisor mode, # 18165 # d0 = size of dump 18165 # d0 = size of dump # 18166 # d1 = Dn 18166 # d1 = Dn # 18167 # Else if instruction access error, 18167 # Else if instruction access error, # 18168 # d0 = FSLW 18168 # d0 = FSLW # 18169 # Else if data access error, 18169 # Else if data access error, # 18170 # d0 = FSLW 18170 # d0 = FSLW # 18171 # a0 = address of fault 18171 # a0 = address of fault # 18172 # Else 18172 # Else # 18173 # none. 18173 # none. # 18174 # 18174 # # 18175 # ALGORITHM ******************************** 18175 # ALGORITHM *********************************************************** # 18176 # The effective address must be calcul 18176 # The effective address must be calculated since this is entered # 18177 # from an "Unimplemented Effective Address" 18177 # from an "Unimplemented Effective Address" exception handler. So, we # 18178 # have our own fcalc_ea() routine here. If a 18178 # have our own fcalc_ea() routine here. If an access error is flagged # 18179 # by a _{i,d,}mem_read() call, we must exit 18179 # by a _{i,d,}mem_read() call, we must exit through the special # 18180 # handler. 18180 # handler. # 18181 # The data register is determined and 18181 # The data register is determined and its value loaded to get the # 18182 # string of FP registers affected. This valu 18182 # string of FP registers affected. This value is used as an index into # 18183 # a lookup table such that we can determine 18183 # a lookup table such that we can determine the number of bytes # 18184 # involved. 18184 # involved. # 18185 # If the instruction is "fmovm.x <ea>, 18185 # If the instruction is "fmovm.x <ea>,Dn", a _mem_read() is used # 18186 # to read in all FP values. Again, _mem_read 18186 # to read in all FP values. Again, _mem_read() may fail and require a # 18187 # special exit. 18187 # special exit. # 18188 # If the instruction is "fmovm.x DN,<e 18188 # If the instruction is "fmovm.x DN,<ea>", a _mem_write() is used # 18189 # to write all FP values. _mem_write() may a 18189 # to write all FP values. _mem_write() may also fail. # 18190 # If the instruction is "fmovm.x DN,-( 18190 # If the instruction is "fmovm.x DN,-(a7)" from supervisor mode, # 18191 # then we return the size of the dump and th 18191 # then we return the size of the dump and the string to the caller # 18192 # so that the move can occur outside of this 18192 # so that the move can occur outside of this routine. This special # 18193 # case is required so that moves to the syst 18193 # case is required so that moves to the system stack are handled # 18194 # correctly. 18194 # correctly. # 18195 # 18195 # # 18196 # DYNAMIC: 18196 # DYNAMIC: # 18197 # fmovm.x dn, <ea> 18197 # fmovm.x dn, <ea> # 18198 # fmovm.x <ea>, dn 18198 # fmovm.x <ea>, dn # 18199 # 18199 # # 18200 # <WORD 1> <WORD2 18200 # <WORD 1> <WORD2> # 18201 # 1111 0010 00 |<ea>| 11@& 1000 0$ 18201 # 1111 0010 00 |<ea>| 11@& 1000 0$$$ 0000 # 18202 # 18202 # # 18203 # & = (0): predecrement addressing mod 18203 # & = (0): predecrement addressing mode # 18204 # (1): postincrement or control ad 18204 # (1): postincrement or control addressing mode # 18205 # @ = (0): move listed regs from memor 18205 # @ = (0): move listed regs from memory to the FPU # 18206 # (1): move listed regs from the F 18206 # (1): move listed regs from the FPU to memory # 18207 # $$$ : index of data register hold 18207 # $$$ : index of data register holding reg select mask # 18208 # 18208 # # 18209 # NOTES: 18209 # NOTES: # 18210 # If the data register holds a zero, t 18210 # If the data register holds a zero, then the # 18211 # instruction is a nop. 18211 # instruction is a nop. # 18212 # 18212 # # 18213 ############################################ 18213 ######################################################################### 18214 18214 18215 global fmovm_dynamic 18215 global fmovm_dynamic 18216 fmovm_dynamic: 18216 fmovm_dynamic: 18217 18217 18218 # extract the data register in which the bit 18218 # extract the data register in which the bit string resides... 18219 mov.b 1+EXC_EXTWORD(%a6),% 18219 mov.b 1+EXC_EXTWORD(%a6),%d1 # fetch extword 18220 andi.w &0x70,%d1 18220 andi.w &0x70,%d1 # extract reg bits 18221 lsr.b &0x4,%d1 18221 lsr.b &0x4,%d1 # shift into lo bits 18222 18222 18223 # fetch the bit string into d0... 18223 # fetch the bit string into d0... 18224 bsr.l fetch_dreg 18224 bsr.l fetch_dreg # fetch reg string 18225 18225 18226 andi.l &0x000000ff,%d0 18226 andi.l &0x000000ff,%d0 # keep only lo byte 18227 18227 18228 mov.l %d0,-(%sp) 18228 mov.l %d0,-(%sp) # save strg 18229 mov.b (tbl_fmovm_size.w,%p 18229 mov.b (tbl_fmovm_size.w,%pc,%d0),%d0 18230 mov.l %d0,-(%sp) 18230 mov.l %d0,-(%sp) # save size 18231 bsr.l fmovm_calc_ea 18231 bsr.l fmovm_calc_ea # calculate <ea> 18232 mov.l (%sp)+,%d0 18232 mov.l (%sp)+,%d0 # restore size 18233 mov.l (%sp)+,%d1 18233 mov.l (%sp)+,%d1 # restore strg 18234 18234 18235 # if the bit string is a zero, then the oper 18235 # if the bit string is a zero, then the operation is a no-op 18236 # but, make sure that we've calculated ea an 18236 # but, make sure that we've calculated ea and advanced the opword pointer 18237 beq.w fmovm_data_done 18237 beq.w fmovm_data_done 18238 18238 18239 # separate move ins from move outs... 18239 # separate move ins from move outs... 18240 btst &0x5,EXC_EXTWORD(%a6 18240 btst &0x5,EXC_EXTWORD(%a6) # is it a move in or out? 18241 beq.w fmovm_data_in 18241 beq.w fmovm_data_in # it's a move out 18242 18242 18243 ############# 18243 ############# 18244 # MOVE OUT: # 18244 # MOVE OUT: # 18245 ############# 18245 ############# 18246 fmovm_data_out: 18246 fmovm_data_out: 18247 btst &0x4,EXC_EXTWORD(%a6 18247 btst &0x4,EXC_EXTWORD(%a6) # control or predecrement? 18248 bne.w fmovm_out_ctrl 18248 bne.w fmovm_out_ctrl # control 18249 18249 18250 ############################ 18250 ############################ 18251 fmovm_out_predec: 18251 fmovm_out_predec: 18252 # for predecrement mode, the bit string is t 18252 # for predecrement mode, the bit string is the opposite of both control 18253 # operations and postincrement mode. (bit7 = 18253 # operations and postincrement mode. (bit7 = FP7 ... bit0 = FP0) 18254 # here, we convert it to be just like the ot 18254 # here, we convert it to be just like the others... 18255 mov.b (tbl_fmovm_convert.w 18255 mov.b (tbl_fmovm_convert.w,%pc,%d1.w*1),%d1 18256 18256 18257 btst &0x5,EXC_SR(%a6) 18257 btst &0x5,EXC_SR(%a6) # user or supervisor mode? 18258 beq.b fmovm_out_ctrl 18258 beq.b fmovm_out_ctrl # user 18259 18259 18260 fmovm_out_predec_s: 18260 fmovm_out_predec_s: 18261 cmpi.b SPCOND_FLG(%a6),&mda 18261 cmpi.b SPCOND_FLG(%a6),&mda7_flg # is <ea> mode -(a7)? 18262 bne.b fmovm_out_ctrl 18262 bne.b fmovm_out_ctrl 18263 18263 18264 # the operation was unfortunately an: fmovm. 18264 # the operation was unfortunately an: fmovm.x dn,-(sp) 18265 # called from supervisor mode. 18265 # called from supervisor mode. 18266 # we're also passing "size" and "strg" back 18266 # we're also passing "size" and "strg" back to the calling routine 18267 rts 18267 rts 18268 18268 18269 ############################ 18269 ############################ 18270 fmovm_out_ctrl: 18270 fmovm_out_ctrl: 18271 mov.l %a0,%a1 18271 mov.l %a0,%a1 # move <ea> to a1 18272 18272 18273 sub.l %d0,%sp 18273 sub.l %d0,%sp # subtract size of dump 18274 lea (%sp),%a0 18274 lea (%sp),%a0 18275 18275 18276 tst.b %d1 18276 tst.b %d1 # should FP0 be moved? 18277 bpl.b fmovm_out_ctrl_fp1 18277 bpl.b fmovm_out_ctrl_fp1 # no 18278 18278 18279 mov.l 0x0+EXC_FP0(%a6),(%a 18279 mov.l 0x0+EXC_FP0(%a6),(%a0)+ # yes 18280 mov.l 0x4+EXC_FP0(%a6),(%a 18280 mov.l 0x4+EXC_FP0(%a6),(%a0)+ 18281 mov.l 0x8+EXC_FP0(%a6),(%a 18281 mov.l 0x8+EXC_FP0(%a6),(%a0)+ 18282 18282 18283 fmovm_out_ctrl_fp1: 18283 fmovm_out_ctrl_fp1: 18284 lsl.b &0x1,%d1 18284 lsl.b &0x1,%d1 # should FP1 be moved? 18285 bpl.b fmovm_out_ctrl_fp2 18285 bpl.b fmovm_out_ctrl_fp2 # no 18286 18286 18287 mov.l 0x0+EXC_FP1(%a6),(%a 18287 mov.l 0x0+EXC_FP1(%a6),(%a0)+ # yes 18288 mov.l 0x4+EXC_FP1(%a6),(%a 18288 mov.l 0x4+EXC_FP1(%a6),(%a0)+ 18289 mov.l 0x8+EXC_FP1(%a6),(%a 18289 mov.l 0x8+EXC_FP1(%a6),(%a0)+ 18290 18290 18291 fmovm_out_ctrl_fp2: 18291 fmovm_out_ctrl_fp2: 18292 lsl.b &0x1,%d1 18292 lsl.b &0x1,%d1 # should FP2 be moved? 18293 bpl.b fmovm_out_ctrl_fp3 18293 bpl.b fmovm_out_ctrl_fp3 # no 18294 18294 18295 fmovm.x &0x20,(%a0) 18295 fmovm.x &0x20,(%a0) # yes 18296 add.l &0xc,%a0 18296 add.l &0xc,%a0 18297 18297 18298 fmovm_out_ctrl_fp3: 18298 fmovm_out_ctrl_fp3: 18299 lsl.b &0x1,%d1 18299 lsl.b &0x1,%d1 # should FP3 be moved? 18300 bpl.b fmovm_out_ctrl_fp4 18300 bpl.b fmovm_out_ctrl_fp4 # no 18301 18301 18302 fmovm.x &0x10,(%a0) 18302 fmovm.x &0x10,(%a0) # yes 18303 add.l &0xc,%a0 18303 add.l &0xc,%a0 18304 18304 18305 fmovm_out_ctrl_fp4: 18305 fmovm_out_ctrl_fp4: 18306 lsl.b &0x1,%d1 18306 lsl.b &0x1,%d1 # should FP4 be moved? 18307 bpl.b fmovm_out_ctrl_fp5 18307 bpl.b fmovm_out_ctrl_fp5 # no 18308 18308 18309 fmovm.x &0x08,(%a0) 18309 fmovm.x &0x08,(%a0) # yes 18310 add.l &0xc,%a0 18310 add.l &0xc,%a0 18311 18311 18312 fmovm_out_ctrl_fp5: 18312 fmovm_out_ctrl_fp5: 18313 lsl.b &0x1,%d1 18313 lsl.b &0x1,%d1 # should FP5 be moved? 18314 bpl.b fmovm_out_ctrl_fp6 18314 bpl.b fmovm_out_ctrl_fp6 # no 18315 18315 18316 fmovm.x &0x04,(%a0) 18316 fmovm.x &0x04,(%a0) # yes 18317 add.l &0xc,%a0 18317 add.l &0xc,%a0 18318 18318 18319 fmovm_out_ctrl_fp6: 18319 fmovm_out_ctrl_fp6: 18320 lsl.b &0x1,%d1 18320 lsl.b &0x1,%d1 # should FP6 be moved? 18321 bpl.b fmovm_out_ctrl_fp7 18321 bpl.b fmovm_out_ctrl_fp7 # no 18322 18322 18323 fmovm.x &0x02,(%a0) 18323 fmovm.x &0x02,(%a0) # yes 18324 add.l &0xc,%a0 18324 add.l &0xc,%a0 18325 18325 18326 fmovm_out_ctrl_fp7: 18326 fmovm_out_ctrl_fp7: 18327 lsl.b &0x1,%d1 18327 lsl.b &0x1,%d1 # should FP7 be moved? 18328 bpl.b fmovm_out_ctrl_done 18328 bpl.b fmovm_out_ctrl_done # no 18329 18329 18330 fmovm.x &0x01,(%a0) 18330 fmovm.x &0x01,(%a0) # yes 18331 add.l &0xc,%a0 18331 add.l &0xc,%a0 18332 18332 18333 fmovm_out_ctrl_done: 18333 fmovm_out_ctrl_done: 18334 mov.l %a1,L_SCR1(%a6) 18334 mov.l %a1,L_SCR1(%a6) 18335 18335 18336 lea (%sp),%a0 18336 lea (%sp),%a0 # pass: supervisor src 18337 mov.l %d0,-(%sp) 18337 mov.l %d0,-(%sp) # save size 18338 bsr.l _dmem_write 18338 bsr.l _dmem_write # copy data to user mem 18339 18339 18340 mov.l (%sp)+,%d0 18340 mov.l (%sp)+,%d0 18341 add.l %d0,%sp 18341 add.l %d0,%sp # clear fpreg data from stack 18342 18342 18343 tst.l %d1 18343 tst.l %d1 # did dstore err? 18344 bne.w fmovm_out_err 18344 bne.w fmovm_out_err # yes 18345 18345 18346 rts 18346 rts 18347 18347 18348 ############ 18348 ############ 18349 # MOVE IN: # 18349 # MOVE IN: # 18350 ############ 18350 ############ 18351 fmovm_data_in: 18351 fmovm_data_in: 18352 mov.l %a0,L_SCR1(%a6) 18352 mov.l %a0,L_SCR1(%a6) 18353 18353 18354 sub.l %d0,%sp 18354 sub.l %d0,%sp # make room for fpregs 18355 lea (%sp),%a1 18355 lea (%sp),%a1 18356 18356 18357 mov.l %d1,-(%sp) 18357 mov.l %d1,-(%sp) # save bit string for later 18358 mov.l %d0,-(%sp) 18358 mov.l %d0,-(%sp) # save # of bytes 18359 18359 18360 bsr.l _dmem_read 18360 bsr.l _dmem_read # copy data from user mem 18361 18361 18362 mov.l (%sp)+,%d0 18362 mov.l (%sp)+,%d0 # retrieve # of bytes 18363 18363 18364 tst.l %d1 18364 tst.l %d1 # did dfetch fail? 18365 bne.w fmovm_in_err 18365 bne.w fmovm_in_err # yes 18366 18366 18367 mov.l (%sp)+,%d1 18367 mov.l (%sp)+,%d1 # load bit string 18368 18368 18369 lea (%sp),%a0 18369 lea (%sp),%a0 # addr of stack 18370 18370 18371 tst.b %d1 18371 tst.b %d1 # should FP0 be moved? 18372 bpl.b fmovm_data_in_fp1 18372 bpl.b fmovm_data_in_fp1 # no 18373 18373 18374 mov.l (%a0)+,0x0+EXC_FP0(% 18374 mov.l (%a0)+,0x0+EXC_FP0(%a6) # yes 18375 mov.l (%a0)+,0x4+EXC_FP0(% 18375 mov.l (%a0)+,0x4+EXC_FP0(%a6) 18376 mov.l (%a0)+,0x8+EXC_FP0(% 18376 mov.l (%a0)+,0x8+EXC_FP0(%a6) 18377 18377 18378 fmovm_data_in_fp1: 18378 fmovm_data_in_fp1: 18379 lsl.b &0x1,%d1 18379 lsl.b &0x1,%d1 # should FP1 be moved? 18380 bpl.b fmovm_data_in_fp2 18380 bpl.b fmovm_data_in_fp2 # no 18381 18381 18382 mov.l (%a0)+,0x0+EXC_FP1(% 18382 mov.l (%a0)+,0x0+EXC_FP1(%a6) # yes 18383 mov.l (%a0)+,0x4+EXC_FP1(% 18383 mov.l (%a0)+,0x4+EXC_FP1(%a6) 18384 mov.l (%a0)+,0x8+EXC_FP1(% 18384 mov.l (%a0)+,0x8+EXC_FP1(%a6) 18385 18385 18386 fmovm_data_in_fp2: 18386 fmovm_data_in_fp2: 18387 lsl.b &0x1,%d1 18387 lsl.b &0x1,%d1 # should FP2 be moved? 18388 bpl.b fmovm_data_in_fp3 18388 bpl.b fmovm_data_in_fp3 # no 18389 18389 18390 fmovm.x (%a0)+,&0x20 18390 fmovm.x (%a0)+,&0x20 # yes 18391 18391 18392 fmovm_data_in_fp3: 18392 fmovm_data_in_fp3: 18393 lsl.b &0x1,%d1 18393 lsl.b &0x1,%d1 # should FP3 be moved? 18394 bpl.b fmovm_data_in_fp4 18394 bpl.b fmovm_data_in_fp4 # no 18395 18395 18396 fmovm.x (%a0)+,&0x10 18396 fmovm.x (%a0)+,&0x10 # yes 18397 18397 18398 fmovm_data_in_fp4: 18398 fmovm_data_in_fp4: 18399 lsl.b &0x1,%d1 18399 lsl.b &0x1,%d1 # should FP4 be moved? 18400 bpl.b fmovm_data_in_fp5 18400 bpl.b fmovm_data_in_fp5 # no 18401 18401 18402 fmovm.x (%a0)+,&0x08 18402 fmovm.x (%a0)+,&0x08 # yes 18403 18403 18404 fmovm_data_in_fp5: 18404 fmovm_data_in_fp5: 18405 lsl.b &0x1,%d1 18405 lsl.b &0x1,%d1 # should FP5 be moved? 18406 bpl.b fmovm_data_in_fp6 18406 bpl.b fmovm_data_in_fp6 # no 18407 18407 18408 fmovm.x (%a0)+,&0x04 18408 fmovm.x (%a0)+,&0x04 # yes 18409 18409 18410 fmovm_data_in_fp6: 18410 fmovm_data_in_fp6: 18411 lsl.b &0x1,%d1 18411 lsl.b &0x1,%d1 # should FP6 be moved? 18412 bpl.b fmovm_data_in_fp7 18412 bpl.b fmovm_data_in_fp7 # no 18413 18413 18414 fmovm.x (%a0)+,&0x02 18414 fmovm.x (%a0)+,&0x02 # yes 18415 18415 18416 fmovm_data_in_fp7: 18416 fmovm_data_in_fp7: 18417 lsl.b &0x1,%d1 18417 lsl.b &0x1,%d1 # should FP7 be moved? 18418 bpl.b fmovm_data_in_done 18418 bpl.b fmovm_data_in_done # no 18419 18419 18420 fmovm.x (%a0)+,&0x01 18420 fmovm.x (%a0)+,&0x01 # yes 18421 18421 18422 fmovm_data_in_done: 18422 fmovm_data_in_done: 18423 add.l %d0,%sp 18423 add.l %d0,%sp # remove fpregs from stack 18424 rts 18424 rts 18425 18425 18426 ##################################### 18426 ##################################### 18427 18427 18428 fmovm_data_done: 18428 fmovm_data_done: 18429 rts 18429 rts 18430 18430 18431 ############################################ 18431 ############################################################################## 18432 18432 18433 # 18433 # 18434 # table indexed by the operation's bit strin 18434 # table indexed by the operation's bit string that gives the number 18435 # of bytes that will be moved. 18435 # of bytes that will be moved. 18436 # 18436 # 18437 # number of bytes = (# of 1's in bit string) 18437 # number of bytes = (# of 1's in bit string) * 12(bytes/fpreg) 18438 # 18438 # 18439 tbl_fmovm_size: 18439 tbl_fmovm_size: 18440 byte 0x00,0x0c,0x0c,0x18,0x0c,0x1 18440 byte 0x00,0x0c,0x0c,0x18,0x0c,0x18,0x18,0x24 18441 byte 0x0c,0x18,0x18,0x24,0x18,0x2 18441 byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30 18442 byte 0x0c,0x18,0x18,0x24,0x18,0x2 18442 byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30 18443 byte 0x18,0x24,0x24,0x30,0x24,0x3 18443 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18444 byte 0x0c,0x18,0x18,0x24,0x18,0x2 18444 byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30 18445 byte 0x18,0x24,0x24,0x30,0x24,0x3 18445 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18446 byte 0x18,0x24,0x24,0x30,0x24,0x3 18446 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18447 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18447 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18448 byte 0x0c,0x18,0x18,0x24,0x18,0x2 18448 byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30 18449 byte 0x18,0x24,0x24,0x30,0x24,0x3 18449 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18450 byte 0x18,0x24,0x24,0x30,0x24,0x3 18450 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18451 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18451 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18452 byte 0x18,0x24,0x24,0x30,0x24,0x3 18452 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18453 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18453 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18454 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18454 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18455 byte 0x30,0x3c,0x3c,0x48,0x3c,0x4 18455 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54 18456 byte 0x0c,0x18,0x18,0x24,0x18,0x2 18456 byte 0x0c,0x18,0x18,0x24,0x18,0x24,0x24,0x30 18457 byte 0x18,0x24,0x24,0x30,0x24,0x3 18457 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18458 byte 0x18,0x24,0x24,0x30,0x24,0x3 18458 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18459 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18459 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18460 byte 0x18,0x24,0x24,0x30,0x24,0x3 18460 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18461 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18461 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18462 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18462 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18463 byte 0x30,0x3c,0x3c,0x48,0x3c,0x4 18463 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54 18464 byte 0x18,0x24,0x24,0x30,0x24,0x3 18464 byte 0x18,0x24,0x24,0x30,0x24,0x30,0x30,0x3c 18465 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18465 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18466 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18466 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18467 byte 0x30,0x3c,0x3c,0x48,0x3c,0x4 18467 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54 18468 byte 0x24,0x30,0x30,0x3c,0x30,0x3 18468 byte 0x24,0x30,0x30,0x3c,0x30,0x3c,0x3c,0x48 18469 byte 0x30,0x3c,0x3c,0x48,0x3c,0x4 18469 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54 18470 byte 0x30,0x3c,0x3c,0x48,0x3c,0x4 18470 byte 0x30,0x3c,0x3c,0x48,0x3c,0x48,0x48,0x54 18471 byte 0x3c,0x48,0x48,0x54,0x48,0x5 18471 byte 0x3c,0x48,0x48,0x54,0x48,0x54,0x54,0x60 18472 18472 18473 # 18473 # 18474 # table to convert a pre-decrement bit strin 18474 # table to convert a pre-decrement bit string into a post-increment 18475 # or control bit string. 18475 # or control bit string. 18476 # ex: 0x00 ==> 0x00 18476 # ex: 0x00 ==> 0x00 18477 # 0x01 ==> 0x80 18477 # 0x01 ==> 0x80 18478 # 0x02 ==> 0x40 18478 # 0x02 ==> 0x40 18479 # . 18479 # . 18480 # . 18480 # . 18481 # 0xfd ==> 0xbf 18481 # 0xfd ==> 0xbf 18482 # 0xfe ==> 0x7f 18482 # 0xfe ==> 0x7f 18483 # 0xff ==> 0xff 18483 # 0xff ==> 0xff 18484 # 18484 # 18485 tbl_fmovm_convert: 18485 tbl_fmovm_convert: 18486 byte 0x00,0x80,0x40,0xc0,0x20,0xa 18486 byte 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0 18487 byte 0x10,0x90,0x50,0xd0,0x30,0xb 18487 byte 0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0 18488 byte 0x08,0x88,0x48,0xc8,0x28,0xa 18488 byte 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8 18489 byte 0x18,0x98,0x58,0xd8,0x38,0xb 18489 byte 0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8 18490 byte 0x04,0x84,0x44,0xc4,0x24,0xa 18490 byte 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4 18491 byte 0x14,0x94,0x54,0xd4,0x34,0xb 18491 byte 0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4 18492 byte 0x0c,0x8c,0x4c,0xcc,0x2c,0xa 18492 byte 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec 18493 byte 0x1c,0x9c,0x5c,0xdc,0x3c,0xb 18493 byte 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc 18494 byte 0x02,0x82,0x42,0xc2,0x22,0xa 18494 byte 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2 18495 byte 0x12,0x92,0x52,0xd2,0x32,0xb 18495 byte 0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2 18496 byte 0x0a,0x8a,0x4a,0xca,0x2a,0xa 18496 byte 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea 18497 byte 0x1a,0x9a,0x5a,0xda,0x3a,0xb 18497 byte 0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa 18498 byte 0x06,0x86,0x46,0xc6,0x26,0xa 18498 byte 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6 18499 byte 0x16,0x96,0x56,0xd6,0x36,0xb 18499 byte 0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6 18500 byte 0x0e,0x8e,0x4e,0xce,0x2e,0xa 18500 byte 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee 18501 byte 0x1e,0x9e,0x5e,0xde,0x3e,0xb 18501 byte 0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe 18502 byte 0x01,0x81,0x41,0xc1,0x21,0xa 18502 byte 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1 18503 byte 0x11,0x91,0x51,0xd1,0x31,0xb 18503 byte 0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1 18504 byte 0x09,0x89,0x49,0xc9,0x29,0xa 18504 byte 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9 18505 byte 0x19,0x99,0x59,0xd9,0x39,0xb 18505 byte 0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9 18506 byte 0x05,0x85,0x45,0xc5,0x25,0xa 18506 byte 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5 18507 byte 0x15,0x95,0x55,0xd5,0x35,0xb 18507 byte 0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5 18508 byte 0x0d,0x8d,0x4d,0xcd,0x2d,0xa 18508 byte 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed 18509 byte 0x1d,0x9d,0x5d,0xdd,0x3d,0xb 18509 byte 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd 18510 byte 0x03,0x83,0x43,0xc3,0x23,0xa 18510 byte 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3 18511 byte 0x13,0x93,0x53,0xd3,0x33,0xb 18511 byte 0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3 18512 byte 0x0b,0x8b,0x4b,0xcb,0x2b,0xa 18512 byte 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb 18513 byte 0x1b,0x9b,0x5b,0xdb,0x3b,0xb 18513 byte 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb 18514 byte 0x07,0x87,0x47,0xc7,0x27,0xa 18514 byte 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7 18515 byte 0x17,0x97,0x57,0xd7,0x37,0xb 18515 byte 0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7 18516 byte 0x0f,0x8f,0x4f,0xcf,0x2f,0xa 18516 byte 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef 18517 byte 0x1f,0x9f,0x5f,0xdf,0x3f,0xb 18517 byte 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff 18518 18518 18519 global fmovm_calc_ea 18519 global fmovm_calc_ea 18520 ############################################ 18520 ############################################### 18521 # _fmovm_calc_ea: calculate effective addres 18521 # _fmovm_calc_ea: calculate effective address # 18522 ############################################ 18522 ############################################### 18523 fmovm_calc_ea: 18523 fmovm_calc_ea: 18524 mov.l %d0,%a0 18524 mov.l %d0,%a0 # move # bytes to a0 18525 18525 18526 # currently, MODE and REG are taken from the 18526 # currently, MODE and REG are taken from the EXC_OPWORD. this could be 18527 # easily changed if they were inputs passed 18527 # easily changed if they were inputs passed in registers. 18528 mov.w EXC_OPWORD(%a6),%d0 18528 mov.w EXC_OPWORD(%a6),%d0 # fetch opcode word 18529 mov.w %d0,%d1 18529 mov.w %d0,%d1 # make a copy 18530 18530 18531 andi.w &0x3f,%d0 18531 andi.w &0x3f,%d0 # extract mode field 18532 andi.l &0x7,%d1 18532 andi.l &0x7,%d1 # extract reg field 18533 18533 18534 # jump to the corresponding function for eac 18534 # jump to the corresponding function for each {MODE,REG} pair. 18535 mov.w (tbl_fea_mode.b,%pc, 18535 mov.w (tbl_fea_mode.b,%pc,%d0.w*2),%d0 # fetch jmp distance 18536 jmp (tbl_fea_mode.b,%pc, 18536 jmp (tbl_fea_mode.b,%pc,%d0.w*1) # jmp to correct ea mode 18537 18537 18538 swbeg &64 18538 swbeg &64 18539 tbl_fea_mode: 18539 tbl_fea_mode: 18540 short tbl_fea_mode - 18540 short tbl_fea_mode - tbl_fea_mode 18541 short tbl_fea_mode - 18541 short tbl_fea_mode - tbl_fea_mode 18542 short tbl_fea_mode - 18542 short tbl_fea_mode - tbl_fea_mode 18543 short tbl_fea_mode - 18543 short tbl_fea_mode - tbl_fea_mode 18544 short tbl_fea_mode - 18544 short tbl_fea_mode - tbl_fea_mode 18545 short tbl_fea_mode - 18545 short tbl_fea_mode - tbl_fea_mode 18546 short tbl_fea_mode - 18546 short tbl_fea_mode - tbl_fea_mode 18547 short tbl_fea_mode - 18547 short tbl_fea_mode - tbl_fea_mode 18548 18548 18549 short tbl_fea_mode - 18549 short tbl_fea_mode - tbl_fea_mode 18550 short tbl_fea_mode - 18550 short tbl_fea_mode - tbl_fea_mode 18551 short tbl_fea_mode - 18551 short tbl_fea_mode - tbl_fea_mode 18552 short tbl_fea_mode - 18552 short tbl_fea_mode - tbl_fea_mode 18553 short tbl_fea_mode - 18553 short tbl_fea_mode - tbl_fea_mode 18554 short tbl_fea_mode - 18554 short tbl_fea_mode - tbl_fea_mode 18555 short tbl_fea_mode - 18555 short tbl_fea_mode - tbl_fea_mode 18556 short tbl_fea_mode - 18556 short tbl_fea_mode - tbl_fea_mode 18557 18557 18558 short faddr_ind_a0 - 18558 short faddr_ind_a0 - tbl_fea_mode 18559 short faddr_ind_a1 - 18559 short faddr_ind_a1 - tbl_fea_mode 18560 short faddr_ind_a2 - 18560 short faddr_ind_a2 - tbl_fea_mode 18561 short faddr_ind_a3 - 18561 short faddr_ind_a3 - tbl_fea_mode 18562 short faddr_ind_a4 - 18562 short faddr_ind_a4 - tbl_fea_mode 18563 short faddr_ind_a5 - 18563 short faddr_ind_a5 - tbl_fea_mode 18564 short faddr_ind_a6 - 18564 short faddr_ind_a6 - tbl_fea_mode 18565 short faddr_ind_a7 - 18565 short faddr_ind_a7 - tbl_fea_mode 18566 18566 18567 short faddr_ind_p_a0 - 18567 short faddr_ind_p_a0 - tbl_fea_mode 18568 short faddr_ind_p_a1 - 18568 short faddr_ind_p_a1 - tbl_fea_mode 18569 short faddr_ind_p_a2 - 18569 short faddr_ind_p_a2 - tbl_fea_mode 18570 short faddr_ind_p_a3 - 18570 short faddr_ind_p_a3 - tbl_fea_mode 18571 short faddr_ind_p_a4 - 18571 short faddr_ind_p_a4 - tbl_fea_mode 18572 short faddr_ind_p_a5 - 18572 short faddr_ind_p_a5 - tbl_fea_mode 18573 short faddr_ind_p_a6 - 18573 short faddr_ind_p_a6 - tbl_fea_mode 18574 short faddr_ind_p_a7 - 18574 short faddr_ind_p_a7 - tbl_fea_mode 18575 18575 18576 short faddr_ind_m_a0 - 18576 short faddr_ind_m_a0 - tbl_fea_mode 18577 short faddr_ind_m_a1 - 18577 short faddr_ind_m_a1 - tbl_fea_mode 18578 short faddr_ind_m_a2 - 18578 short faddr_ind_m_a2 - tbl_fea_mode 18579 short faddr_ind_m_a3 - 18579 short faddr_ind_m_a3 - tbl_fea_mode 18580 short faddr_ind_m_a4 - 18580 short faddr_ind_m_a4 - tbl_fea_mode 18581 short faddr_ind_m_a5 - 18581 short faddr_ind_m_a5 - tbl_fea_mode 18582 short faddr_ind_m_a6 - 18582 short faddr_ind_m_a6 - tbl_fea_mode 18583 short faddr_ind_m_a7 - 18583 short faddr_ind_m_a7 - tbl_fea_mode 18584 18584 18585 short faddr_ind_disp_a0 18585 short faddr_ind_disp_a0 - tbl_fea_mode 18586 short faddr_ind_disp_a1 18586 short faddr_ind_disp_a1 - tbl_fea_mode 18587 short faddr_ind_disp_a2 18587 short faddr_ind_disp_a2 - tbl_fea_mode 18588 short faddr_ind_disp_a3 18588 short faddr_ind_disp_a3 - tbl_fea_mode 18589 short faddr_ind_disp_a4 18589 short faddr_ind_disp_a4 - tbl_fea_mode 18590 short faddr_ind_disp_a5 18590 short faddr_ind_disp_a5 - tbl_fea_mode 18591 short faddr_ind_disp_a6 18591 short faddr_ind_disp_a6 - tbl_fea_mode 18592 short faddr_ind_disp_a7 18592 short faddr_ind_disp_a7 - tbl_fea_mode 18593 18593 18594 short faddr_ind_ext - 18594 short faddr_ind_ext - tbl_fea_mode 18595 short faddr_ind_ext - 18595 short faddr_ind_ext - tbl_fea_mode 18596 short faddr_ind_ext - 18596 short faddr_ind_ext - tbl_fea_mode 18597 short faddr_ind_ext - 18597 short faddr_ind_ext - tbl_fea_mode 18598 short faddr_ind_ext - 18598 short faddr_ind_ext - tbl_fea_mode 18599 short faddr_ind_ext - 18599 short faddr_ind_ext - tbl_fea_mode 18600 short faddr_ind_ext - 18600 short faddr_ind_ext - tbl_fea_mode 18601 short faddr_ind_ext - 18601 short faddr_ind_ext - tbl_fea_mode 18602 18602 18603 short fabs_short - 18603 short fabs_short - tbl_fea_mode 18604 short fabs_long - 18604 short fabs_long - tbl_fea_mode 18605 short fpc_ind - 18605 short fpc_ind - tbl_fea_mode 18606 short fpc_ind_ext - 18606 short fpc_ind_ext - tbl_fea_mode 18607 short tbl_fea_mode - 18607 short tbl_fea_mode - tbl_fea_mode 18608 short tbl_fea_mode - 18608 short tbl_fea_mode - tbl_fea_mode 18609 short tbl_fea_mode - 18609 short tbl_fea_mode - tbl_fea_mode 18610 short tbl_fea_mode - 18610 short tbl_fea_mode - tbl_fea_mode 18611 18611 18612 ################################### 18612 ################################### 18613 # Address register indirect: (An) # 18613 # Address register indirect: (An) # 18614 ################################### 18614 ################################### 18615 faddr_ind_a0: 18615 faddr_ind_a0: 18616 mov.l EXC_DREGS+0x8(%a6),% 18616 mov.l EXC_DREGS+0x8(%a6),%a0 # Get current a0 18617 rts 18617 rts 18618 18618 18619 faddr_ind_a1: 18619 faddr_ind_a1: 18620 mov.l EXC_DREGS+0xc(%a6),% 18620 mov.l EXC_DREGS+0xc(%a6),%a0 # Get current a1 18621 rts 18621 rts 18622 18622 18623 faddr_ind_a2: 18623 faddr_ind_a2: 18624 mov.l %a2,%a0 18624 mov.l %a2,%a0 # Get current a2 18625 rts 18625 rts 18626 18626 18627 faddr_ind_a3: 18627 faddr_ind_a3: 18628 mov.l %a3,%a0 18628 mov.l %a3,%a0 # Get current a3 18629 rts 18629 rts 18630 18630 18631 faddr_ind_a4: 18631 faddr_ind_a4: 18632 mov.l %a4,%a0 18632 mov.l %a4,%a0 # Get current a4 18633 rts 18633 rts 18634 18634 18635 faddr_ind_a5: 18635 faddr_ind_a5: 18636 mov.l %a5,%a0 18636 mov.l %a5,%a0 # Get current a5 18637 rts 18637 rts 18638 18638 18639 faddr_ind_a6: 18639 faddr_ind_a6: 18640 mov.l (%a6),%a0 18640 mov.l (%a6),%a0 # Get current a6 18641 rts 18641 rts 18642 18642 18643 faddr_ind_a7: 18643 faddr_ind_a7: 18644 mov.l EXC_A7(%a6),%a0 18644 mov.l EXC_A7(%a6),%a0 # Get current a7 18645 rts 18645 rts 18646 18646 18647 ############################################ 18647 ##################################################### 18648 # Address register indirect w/ postincrement 18648 # Address register indirect w/ postincrement: (An)+ # 18649 ############################################ 18649 ##################################################### 18650 faddr_ind_p_a0: 18650 faddr_ind_p_a0: 18651 mov.l EXC_DREGS+0x8(%a6),% 18651 mov.l EXC_DREGS+0x8(%a6),%d0 # Get current a0 18652 mov.l %d0,%d1 18652 mov.l %d0,%d1 18653 add.l %a0,%d1 18653 add.l %a0,%d1 # Increment 18654 mov.l %d1,EXC_DREGS+0x8(%a 18654 mov.l %d1,EXC_DREGS+0x8(%a6) # Save incr value 18655 mov.l %d0,%a0 18655 mov.l %d0,%a0 18656 rts 18656 rts 18657 18657 18658 faddr_ind_p_a1: 18658 faddr_ind_p_a1: 18659 mov.l EXC_DREGS+0xc(%a6),% 18659 mov.l EXC_DREGS+0xc(%a6),%d0 # Get current a1 18660 mov.l %d0,%d1 18660 mov.l %d0,%d1 18661 add.l %a0,%d1 18661 add.l %a0,%d1 # Increment 18662 mov.l %d1,EXC_DREGS+0xc(%a 18662 mov.l %d1,EXC_DREGS+0xc(%a6) # Save incr value 18663 mov.l %d0,%a0 18663 mov.l %d0,%a0 18664 rts 18664 rts 18665 18665 18666 faddr_ind_p_a2: 18666 faddr_ind_p_a2: 18667 mov.l %a2,%d0 18667 mov.l %a2,%d0 # Get current a2 18668 mov.l %d0,%d1 18668 mov.l %d0,%d1 18669 add.l %a0,%d1 18669 add.l %a0,%d1 # Increment 18670 mov.l %d1,%a2 18670 mov.l %d1,%a2 # Save incr value 18671 mov.l %d0,%a0 18671 mov.l %d0,%a0 18672 rts 18672 rts 18673 18673 18674 faddr_ind_p_a3: 18674 faddr_ind_p_a3: 18675 mov.l %a3,%d0 18675 mov.l %a3,%d0 # Get current a3 18676 mov.l %d0,%d1 18676 mov.l %d0,%d1 18677 add.l %a0,%d1 18677 add.l %a0,%d1 # Increment 18678 mov.l %d1,%a3 18678 mov.l %d1,%a3 # Save incr value 18679 mov.l %d0,%a0 18679 mov.l %d0,%a0 18680 rts 18680 rts 18681 18681 18682 faddr_ind_p_a4: 18682 faddr_ind_p_a4: 18683 mov.l %a4,%d0 18683 mov.l %a4,%d0 # Get current a4 18684 mov.l %d0,%d1 18684 mov.l %d0,%d1 18685 add.l %a0,%d1 18685 add.l %a0,%d1 # Increment 18686 mov.l %d1,%a4 18686 mov.l %d1,%a4 # Save incr value 18687 mov.l %d0,%a0 18687 mov.l %d0,%a0 18688 rts 18688 rts 18689 18689 18690 faddr_ind_p_a5: 18690 faddr_ind_p_a5: 18691 mov.l %a5,%d0 18691 mov.l %a5,%d0 # Get current a5 18692 mov.l %d0,%d1 18692 mov.l %d0,%d1 18693 add.l %a0,%d1 18693 add.l %a0,%d1 # Increment 18694 mov.l %d1,%a5 18694 mov.l %d1,%a5 # Save incr value 18695 mov.l %d0,%a0 18695 mov.l %d0,%a0 18696 rts 18696 rts 18697 18697 18698 faddr_ind_p_a6: 18698 faddr_ind_p_a6: 18699 mov.l (%a6),%d0 18699 mov.l (%a6),%d0 # Get current a6 18700 mov.l %d0,%d1 18700 mov.l %d0,%d1 18701 add.l %a0,%d1 18701 add.l %a0,%d1 # Increment 18702 mov.l %d1,(%a6) 18702 mov.l %d1,(%a6) # Save incr value 18703 mov.l %d0,%a0 18703 mov.l %d0,%a0 18704 rts 18704 rts 18705 18705 18706 faddr_ind_p_a7: 18706 faddr_ind_p_a7: 18707 mov.b &mia7_flg,SPCOND_FLG 18707 mov.b &mia7_flg,SPCOND_FLG(%a6) # set "special case" flag 18708 18708 18709 mov.l EXC_A7(%a6),%d0 18709 mov.l EXC_A7(%a6),%d0 # Get current a7 18710 mov.l %d0,%d1 18710 mov.l %d0,%d1 18711 add.l %a0,%d1 18711 add.l %a0,%d1 # Increment 18712 mov.l %d1,EXC_A7(%a6) 18712 mov.l %d1,EXC_A7(%a6) # Save incr value 18713 mov.l %d0,%a0 18713 mov.l %d0,%a0 18714 rts 18714 rts 18715 18715 18716 ############################################ 18716 #################################################### 18717 # Address register indirect w/ predecrement: 18717 # Address register indirect w/ predecrement: -(An) # 18718 ############################################ 18718 #################################################### 18719 faddr_ind_m_a0: 18719 faddr_ind_m_a0: 18720 mov.l EXC_DREGS+0x8(%a6),% 18720 mov.l EXC_DREGS+0x8(%a6),%d0 # Get current a0 18721 sub.l %a0,%d0 18721 sub.l %a0,%d0 # Decrement 18722 mov.l %d0,EXC_DREGS+0x8(%a 18722 mov.l %d0,EXC_DREGS+0x8(%a6) # Save decr value 18723 mov.l %d0,%a0 18723 mov.l %d0,%a0 18724 rts 18724 rts 18725 18725 18726 faddr_ind_m_a1: 18726 faddr_ind_m_a1: 18727 mov.l EXC_DREGS+0xc(%a6),% 18727 mov.l EXC_DREGS+0xc(%a6),%d0 # Get current a1 18728 sub.l %a0,%d0 18728 sub.l %a0,%d0 # Decrement 18729 mov.l %d0,EXC_DREGS+0xc(%a 18729 mov.l %d0,EXC_DREGS+0xc(%a6) # Save decr value 18730 mov.l %d0,%a0 18730 mov.l %d0,%a0 18731 rts 18731 rts 18732 18732 18733 faddr_ind_m_a2: 18733 faddr_ind_m_a2: 18734 mov.l %a2,%d0 18734 mov.l %a2,%d0 # Get current a2 18735 sub.l %a0,%d0 18735 sub.l %a0,%d0 # Decrement 18736 mov.l %d0,%a2 18736 mov.l %d0,%a2 # Save decr value 18737 mov.l %d0,%a0 18737 mov.l %d0,%a0 18738 rts 18738 rts 18739 18739 18740 faddr_ind_m_a3: 18740 faddr_ind_m_a3: 18741 mov.l %a3,%d0 18741 mov.l %a3,%d0 # Get current a3 18742 sub.l %a0,%d0 18742 sub.l %a0,%d0 # Decrement 18743 mov.l %d0,%a3 18743 mov.l %d0,%a3 # Save decr value 18744 mov.l %d0,%a0 18744 mov.l %d0,%a0 18745 rts 18745 rts 18746 18746 18747 faddr_ind_m_a4: 18747 faddr_ind_m_a4: 18748 mov.l %a4,%d0 18748 mov.l %a4,%d0 # Get current a4 18749 sub.l %a0,%d0 18749 sub.l %a0,%d0 # Decrement 18750 mov.l %d0,%a4 18750 mov.l %d0,%a4 # Save decr value 18751 mov.l %d0,%a0 18751 mov.l %d0,%a0 18752 rts 18752 rts 18753 18753 18754 faddr_ind_m_a5: 18754 faddr_ind_m_a5: 18755 mov.l %a5,%d0 18755 mov.l %a5,%d0 # Get current a5 18756 sub.l %a0,%d0 18756 sub.l %a0,%d0 # Decrement 18757 mov.l %d0,%a5 18757 mov.l %d0,%a5 # Save decr value 18758 mov.l %d0,%a0 18758 mov.l %d0,%a0 18759 rts 18759 rts 18760 18760 18761 faddr_ind_m_a6: 18761 faddr_ind_m_a6: 18762 mov.l (%a6),%d0 18762 mov.l (%a6),%d0 # Get current a6 18763 sub.l %a0,%d0 18763 sub.l %a0,%d0 # Decrement 18764 mov.l %d0,(%a6) 18764 mov.l %d0,(%a6) # Save decr value 18765 mov.l %d0,%a0 18765 mov.l %d0,%a0 18766 rts 18766 rts 18767 18767 18768 faddr_ind_m_a7: 18768 faddr_ind_m_a7: 18769 mov.b &mda7_flg,SPCOND_FLG 18769 mov.b &mda7_flg,SPCOND_FLG(%a6) # set "special case" flag 18770 18770 18771 mov.l EXC_A7(%a6),%d0 18771 mov.l EXC_A7(%a6),%d0 # Get current a7 18772 sub.l %a0,%d0 18772 sub.l %a0,%d0 # Decrement 18773 mov.l %d0,EXC_A7(%a6) 18773 mov.l %d0,EXC_A7(%a6) # Save decr value 18774 mov.l %d0,%a0 18774 mov.l %d0,%a0 18775 rts 18775 rts 18776 18776 18777 ############################################ 18777 ######################################################## 18778 # Address register indirect w/ displacement: 18778 # Address register indirect w/ displacement: (d16, An) # 18779 ############################################ 18779 ######################################################## 18780 faddr_ind_disp_a0: 18780 faddr_ind_disp_a0: 18781 mov.l EXC_EXTWPTR(%a6),%a0 18781 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18782 addq.l &0x2,EXC_EXTWPTR(%a6 18782 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18783 bsr.l _imem_read_word 18783 bsr.l _imem_read_word 18784 18784 18785 tst.l %d1 18785 tst.l %d1 # did ifetch fail? 18786 bne.l iea_iacc 18786 bne.l iea_iacc # yes 18787 18787 18788 mov.w %d0,%a0 18788 mov.w %d0,%a0 # sign extend displacement 18789 18789 18790 add.l EXC_DREGS+0x8(%a6),% 18790 add.l EXC_DREGS+0x8(%a6),%a0 # a0 + d16 18791 rts 18791 rts 18792 18792 18793 faddr_ind_disp_a1: 18793 faddr_ind_disp_a1: 18794 mov.l EXC_EXTWPTR(%a6),%a0 18794 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18795 addq.l &0x2,EXC_EXTWPTR(%a6 18795 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18796 bsr.l _imem_read_word 18796 bsr.l _imem_read_word 18797 18797 18798 tst.l %d1 18798 tst.l %d1 # did ifetch fail? 18799 bne.l iea_iacc 18799 bne.l iea_iacc # yes 18800 18800 18801 mov.w %d0,%a0 18801 mov.w %d0,%a0 # sign extend displacement 18802 18802 18803 add.l EXC_DREGS+0xc(%a6),% 18803 add.l EXC_DREGS+0xc(%a6),%a0 # a1 + d16 18804 rts 18804 rts 18805 18805 18806 faddr_ind_disp_a2: 18806 faddr_ind_disp_a2: 18807 mov.l EXC_EXTWPTR(%a6),%a0 18807 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18808 addq.l &0x2,EXC_EXTWPTR(%a6 18808 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18809 bsr.l _imem_read_word 18809 bsr.l _imem_read_word 18810 18810 18811 tst.l %d1 18811 tst.l %d1 # did ifetch fail? 18812 bne.l iea_iacc 18812 bne.l iea_iacc # yes 18813 18813 18814 mov.w %d0,%a0 18814 mov.w %d0,%a0 # sign extend displacement 18815 18815 18816 add.l %a2,%a0 18816 add.l %a2,%a0 # a2 + d16 18817 rts 18817 rts 18818 18818 18819 faddr_ind_disp_a3: 18819 faddr_ind_disp_a3: 18820 mov.l EXC_EXTWPTR(%a6),%a0 18820 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18821 addq.l &0x2,EXC_EXTWPTR(%a6 18821 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18822 bsr.l _imem_read_word 18822 bsr.l _imem_read_word 18823 18823 18824 tst.l %d1 18824 tst.l %d1 # did ifetch fail? 18825 bne.l iea_iacc 18825 bne.l iea_iacc # yes 18826 18826 18827 mov.w %d0,%a0 18827 mov.w %d0,%a0 # sign extend displacement 18828 18828 18829 add.l %a3,%a0 18829 add.l %a3,%a0 # a3 + d16 18830 rts 18830 rts 18831 18831 18832 faddr_ind_disp_a4: 18832 faddr_ind_disp_a4: 18833 mov.l EXC_EXTWPTR(%a6),%a0 18833 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18834 addq.l &0x2,EXC_EXTWPTR(%a6 18834 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18835 bsr.l _imem_read_word 18835 bsr.l _imem_read_word 18836 18836 18837 tst.l %d1 18837 tst.l %d1 # did ifetch fail? 18838 bne.l iea_iacc 18838 bne.l iea_iacc # yes 18839 18839 18840 mov.w %d0,%a0 18840 mov.w %d0,%a0 # sign extend displacement 18841 18841 18842 add.l %a4,%a0 18842 add.l %a4,%a0 # a4 + d16 18843 rts 18843 rts 18844 18844 18845 faddr_ind_disp_a5: 18845 faddr_ind_disp_a5: 18846 mov.l EXC_EXTWPTR(%a6),%a0 18846 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18847 addq.l &0x2,EXC_EXTWPTR(%a6 18847 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18848 bsr.l _imem_read_word 18848 bsr.l _imem_read_word 18849 18849 18850 tst.l %d1 18850 tst.l %d1 # did ifetch fail? 18851 bne.l iea_iacc 18851 bne.l iea_iacc # yes 18852 18852 18853 mov.w %d0,%a0 18853 mov.w %d0,%a0 # sign extend displacement 18854 18854 18855 add.l %a5,%a0 18855 add.l %a5,%a0 # a5 + d16 18856 rts 18856 rts 18857 18857 18858 faddr_ind_disp_a6: 18858 faddr_ind_disp_a6: 18859 mov.l EXC_EXTWPTR(%a6),%a0 18859 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18860 addq.l &0x2,EXC_EXTWPTR(%a6 18860 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18861 bsr.l _imem_read_word 18861 bsr.l _imem_read_word 18862 18862 18863 tst.l %d1 18863 tst.l %d1 # did ifetch fail? 18864 bne.l iea_iacc 18864 bne.l iea_iacc # yes 18865 18865 18866 mov.w %d0,%a0 18866 mov.w %d0,%a0 # sign extend displacement 18867 18867 18868 add.l (%a6),%a0 18868 add.l (%a6),%a0 # a6 + d16 18869 rts 18869 rts 18870 18870 18871 faddr_ind_disp_a7: 18871 faddr_ind_disp_a7: 18872 mov.l EXC_EXTWPTR(%a6),%a0 18872 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18873 addq.l &0x2,EXC_EXTWPTR(%a6 18873 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18874 bsr.l _imem_read_word 18874 bsr.l _imem_read_word 18875 18875 18876 tst.l %d1 18876 tst.l %d1 # did ifetch fail? 18877 bne.l iea_iacc 18877 bne.l iea_iacc # yes 18878 18878 18879 mov.w %d0,%a0 18879 mov.w %d0,%a0 # sign extend displacement 18880 18880 18881 add.l EXC_A7(%a6),%a0 18881 add.l EXC_A7(%a6),%a0 # a7 + d16 18882 rts 18882 rts 18883 18883 18884 ############################################ 18884 ######################################################################## 18885 # Address register indirect w/ index(8-bit d 18885 # Address register indirect w/ index(8-bit displacement): (d8, An, Xn) # 18886 # " " " w/ " (base di 18886 # " " " w/ " (base displacement): (bd, An, Xn) # 18887 # Memory indirect postindexed: ([bd, An], Xn 18887 # Memory indirect postindexed: ([bd, An], Xn, od) # 18888 # Memory indirect preindexed: ([bd, An, Xn], 18888 # Memory indirect preindexed: ([bd, An, Xn], od) # 18889 ############################################ 18889 ######################################################################## 18890 faddr_ind_ext: 18890 faddr_ind_ext: 18891 addq.l &0x8,%d1 18891 addq.l &0x8,%d1 18892 bsr.l fetch_dreg 18892 bsr.l fetch_dreg # fetch base areg 18893 mov.l %d0,-(%sp) 18893 mov.l %d0,-(%sp) 18894 18894 18895 mov.l EXC_EXTWPTR(%a6),%a0 18895 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18896 addq.l &0x2,EXC_EXTWPTR(%a6 18896 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18897 bsr.l _imem_read_word 18897 bsr.l _imem_read_word # fetch extword in d0 18898 18898 18899 tst.l %d1 18899 tst.l %d1 # did ifetch fail? 18900 bne.l iea_iacc 18900 bne.l iea_iacc # yes 18901 18901 18902 mov.l (%sp)+,%a0 18902 mov.l (%sp)+,%a0 18903 18903 18904 btst &0x8,%d0 18904 btst &0x8,%d0 18905 bne.w fcalc_mem_ind 18905 bne.w fcalc_mem_ind 18906 18906 18907 mov.l %d0,L_SCR1(%a6) 18907 mov.l %d0,L_SCR1(%a6) # hold opword 18908 18908 18909 mov.l %d0,%d1 18909 mov.l %d0,%d1 18910 rol.w &0x4,%d1 18910 rol.w &0x4,%d1 18911 andi.w &0xf,%d1 18911 andi.w &0xf,%d1 # extract index regno 18912 18912 18913 # count on fetch_dreg() not to alter a0... 18913 # count on fetch_dreg() not to alter a0... 18914 bsr.l fetch_dreg 18914 bsr.l fetch_dreg # fetch index 18915 18915 18916 mov.l %d2,-(%sp) 18916 mov.l %d2,-(%sp) # save d2 18917 mov.l L_SCR1(%a6),%d2 18917 mov.l L_SCR1(%a6),%d2 # fetch opword 18918 18918 18919 btst &0xb,%d2 18919 btst &0xb,%d2 # is it word or long? 18920 bne.b faii8_long 18920 bne.b faii8_long 18921 ext.l %d0 18921 ext.l %d0 # sign extend word index 18922 faii8_long: 18922 faii8_long: 18923 mov.l %d2,%d1 18923 mov.l %d2,%d1 18924 rol.w &0x7,%d1 18924 rol.w &0x7,%d1 18925 andi.l &0x3,%d1 18925 andi.l &0x3,%d1 # extract scale value 18926 18926 18927 lsl.l %d1,%d0 18927 lsl.l %d1,%d0 # shift index by scale 18928 18928 18929 extb.l %d2 18929 extb.l %d2 # sign extend displacement 18930 add.l %d2,%d0 18930 add.l %d2,%d0 # index + disp 18931 add.l %d0,%a0 18931 add.l %d0,%a0 # An + (index + disp) 18932 18932 18933 mov.l (%sp)+,%d2 18933 mov.l (%sp)+,%d2 # restore old d2 18934 rts 18934 rts 18935 18935 18936 ########################### 18936 ########################### 18937 # Absolute short: (XXX).W # 18937 # Absolute short: (XXX).W # 18938 ########################### 18938 ########################### 18939 fabs_short: 18939 fabs_short: 18940 mov.l EXC_EXTWPTR(%a6),%a0 18940 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18941 addq.l &0x2,EXC_EXTWPTR(%a6 18941 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18942 bsr.l _imem_read_word 18942 bsr.l _imem_read_word # fetch short address 18943 18943 18944 tst.l %d1 18944 tst.l %d1 # did ifetch fail? 18945 bne.l iea_iacc 18945 bne.l iea_iacc # yes 18946 18946 18947 mov.w %d0,%a0 18947 mov.w %d0,%a0 # return <ea> in a0 18948 rts 18948 rts 18949 18949 18950 ########################## 18950 ########################## 18951 # Absolute long: (XXX).L # 18951 # Absolute long: (XXX).L # 18952 ########################## 18952 ########################## 18953 fabs_long: 18953 fabs_long: 18954 mov.l EXC_EXTWPTR(%a6),%a0 18954 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18955 addq.l &0x4,EXC_EXTWPTR(%a6 18955 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 18956 bsr.l _imem_read_long 18956 bsr.l _imem_read_long # fetch long address 18957 18957 18958 tst.l %d1 18958 tst.l %d1 # did ifetch fail? 18959 bne.l iea_iacc 18959 bne.l iea_iacc # yes 18960 18960 18961 mov.l %d0,%a0 18961 mov.l %d0,%a0 # return <ea> in a0 18962 rts 18962 rts 18963 18963 18964 ############################################ 18964 ####################################################### 18965 # Program counter indirect w/ displacement: 18965 # Program counter indirect w/ displacement: (d16, PC) # 18966 ############################################ 18966 ####################################################### 18967 fpc_ind: 18967 fpc_ind: 18968 mov.l EXC_EXTWPTR(%a6),%a0 18968 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18969 addq.l &0x2,EXC_EXTWPTR(%a6 18969 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18970 bsr.l _imem_read_word 18970 bsr.l _imem_read_word # fetch word displacement 18971 18971 18972 tst.l %d1 18972 tst.l %d1 # did ifetch fail? 18973 bne.l iea_iacc 18973 bne.l iea_iacc # yes 18974 18974 18975 mov.w %d0,%a0 18975 mov.w %d0,%a0 # sign extend displacement 18976 18976 18977 add.l EXC_EXTWPTR(%a6),%a0 18977 add.l EXC_EXTWPTR(%a6),%a0 # pc + d16 18978 18978 18979 # _imem_read_word() increased the extwptr by 18979 # _imem_read_word() increased the extwptr by 2. need to adjust here. 18980 subq.l &0x2,%a0 18980 subq.l &0x2,%a0 # adjust <ea> 18981 rts 18981 rts 18982 18982 18983 ############################################ 18983 ########################################################## 18984 # PC indirect w/ index(8-bit displacement): 18984 # PC indirect w/ index(8-bit displacement): (d8, PC, An) # 18985 # " " w/ " (base displacement): ( 18985 # " " w/ " (base displacement): (bd, PC, An) # 18986 # PC memory indirect postindexed: ([bd, PC], 18986 # PC memory indirect postindexed: ([bd, PC], Xn, od) # 18987 # PC memory indirect preindexed: ([bd, PC, X 18987 # PC memory indirect preindexed: ([bd, PC, Xn], od) # 18988 ############################################ 18988 ########################################################## 18989 fpc_ind_ext: 18989 fpc_ind_ext: 18990 mov.l EXC_EXTWPTR(%a6),%a0 18990 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 18991 addq.l &0x2,EXC_EXTWPTR(%a6 18991 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 18992 bsr.l _imem_read_word 18992 bsr.l _imem_read_word # fetch ext word 18993 18993 18994 tst.l %d1 18994 tst.l %d1 # did ifetch fail? 18995 bne.l iea_iacc 18995 bne.l iea_iacc # yes 18996 18996 18997 mov.l EXC_EXTWPTR(%a6),%a0 18997 mov.l EXC_EXTWPTR(%a6),%a0 # put base in a0 18998 subq.l &0x2,%a0 18998 subq.l &0x2,%a0 # adjust base 18999 18999 19000 btst &0x8,%d0 19000 btst &0x8,%d0 # is disp only 8 bits? 19001 bne.w fcalc_mem_ind 19001 bne.w fcalc_mem_ind # calc memory indirect 19002 19002 19003 mov.l %d0,L_SCR1(%a6) 19003 mov.l %d0,L_SCR1(%a6) # store opword 19004 19004 19005 mov.l %d0,%d1 19005 mov.l %d0,%d1 # make extword copy 19006 rol.w &0x4,%d1 19006 rol.w &0x4,%d1 # rotate reg num into place 19007 andi.w &0xf,%d1 19007 andi.w &0xf,%d1 # extract register number 19008 19008 19009 # count on fetch_dreg() not to alter a0... 19009 # count on fetch_dreg() not to alter a0... 19010 bsr.l fetch_dreg 19010 bsr.l fetch_dreg # fetch index 19011 19011 19012 mov.l %d2,-(%sp) 19012 mov.l %d2,-(%sp) # save d2 19013 mov.l L_SCR1(%a6),%d2 19013 mov.l L_SCR1(%a6),%d2 # fetch opword 19014 19014 19015 btst &0xb,%d2 19015 btst &0xb,%d2 # is index word or long? 19016 bne.b fpii8_long 19016 bne.b fpii8_long # long 19017 ext.l %d0 19017 ext.l %d0 # sign extend word index 19018 fpii8_long: 19018 fpii8_long: 19019 mov.l %d2,%d1 19019 mov.l %d2,%d1 19020 rol.w &0x7,%d1 19020 rol.w &0x7,%d1 # rotate scale value into place 19021 andi.l &0x3,%d1 19021 andi.l &0x3,%d1 # extract scale value 19022 19022 19023 lsl.l %d1,%d0 19023 lsl.l %d1,%d0 # shift index by scale 19024 19024 19025 extb.l %d2 19025 extb.l %d2 # sign extend displacement 19026 add.l %d2,%d0 19026 add.l %d2,%d0 # disp + index 19027 add.l %d0,%a0 19027 add.l %d0,%a0 # An + (index + disp) 19028 19028 19029 mov.l (%sp)+,%d2 19029 mov.l (%sp)+,%d2 # restore temp register 19030 rts 19030 rts 19031 19031 19032 # d2 = index 19032 # d2 = index 19033 # d3 = base 19033 # d3 = base 19034 # d4 = od 19034 # d4 = od 19035 # d5 = extword 19035 # d5 = extword 19036 fcalc_mem_ind: 19036 fcalc_mem_ind: 19037 btst &0x6,%d0 19037 btst &0x6,%d0 # is the index suppressed? 19038 beq.b fcalc_index 19038 beq.b fcalc_index 19039 19039 19040 movm.l &0x3c00,-(%sp) 19040 movm.l &0x3c00,-(%sp) # save d2-d5 19041 19041 19042 mov.l %d0,%d5 19042 mov.l %d0,%d5 # put extword in d5 19043 mov.l %a0,%d3 19043 mov.l %a0,%d3 # put base in d3 19044 19044 19045 clr.l %d2 19045 clr.l %d2 # yes, so index = 0 19046 bra.b fbase_supp_ck 19046 bra.b fbase_supp_ck 19047 19047 19048 # index: 19048 # index: 19049 fcalc_index: 19049 fcalc_index: 19050 mov.l %d0,L_SCR1(%a6) 19050 mov.l %d0,L_SCR1(%a6) # save d0 (opword) 19051 bfextu %d0{&16:&4},%d1 19051 bfextu %d0{&16:&4},%d1 # fetch dreg index 19052 bsr.l fetch_dreg 19052 bsr.l fetch_dreg 19053 19053 19054 movm.l &0x3c00,-(%sp) 19054 movm.l &0x3c00,-(%sp) # save d2-d5 19055 mov.l %d0,%d2 19055 mov.l %d0,%d2 # put index in d2 19056 mov.l L_SCR1(%a6),%d5 19056 mov.l L_SCR1(%a6),%d5 19057 mov.l %a0,%d3 19057 mov.l %a0,%d3 19058 19058 19059 btst &0xb,%d5 19059 btst &0xb,%d5 # is index word or long? 19060 bne.b fno_ext 19060 bne.b fno_ext 19061 ext.l %d2 19061 ext.l %d2 19062 19062 19063 fno_ext: 19063 fno_ext: 19064 bfextu %d5{&21:&2},%d0 19064 bfextu %d5{&21:&2},%d0 19065 lsl.l %d0,%d2 19065 lsl.l %d0,%d2 19066 19066 19067 # base address (passed as parameter in d3): 19067 # base address (passed as parameter in d3): 19068 # we clear the value here if it should actua 19068 # we clear the value here if it should actually be suppressed. 19069 fbase_supp_ck: 19069 fbase_supp_ck: 19070 btst &0x7,%d5 19070 btst &0x7,%d5 # is the bd suppressed? 19071 beq.b fno_base_sup 19071 beq.b fno_base_sup 19072 clr.l %d3 19072 clr.l %d3 19073 19073 19074 # base displacement: 19074 # base displacement: 19075 fno_base_sup: 19075 fno_base_sup: 19076 bfextu %d5{&26:&2},%d0 19076 bfextu %d5{&26:&2},%d0 # get bd size 19077 # beq.l fmovm_error 19077 # beq.l fmovm_error # if (size == 0) it's reserved 19078 19078 19079 cmpi.b %d0,&0x2 19079 cmpi.b %d0,&0x2 19080 blt.b fno_bd 19080 blt.b fno_bd 19081 beq.b fget_word_bd 19081 beq.b fget_word_bd 19082 19082 19083 mov.l EXC_EXTWPTR(%a6),%a0 19083 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19084 addq.l &0x4,EXC_EXTWPTR(%a6 19084 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19085 bsr.l _imem_read_long 19085 bsr.l _imem_read_long 19086 19086 19087 tst.l %d1 19087 tst.l %d1 # did ifetch fail? 19088 bne.l fcea_iacc 19088 bne.l fcea_iacc # yes 19089 19089 19090 bra.b fchk_ind 19090 bra.b fchk_ind 19091 19091 19092 fget_word_bd: 19092 fget_word_bd: 19093 mov.l EXC_EXTWPTR(%a6),%a0 19093 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19094 addq.l &0x2,EXC_EXTWPTR(%a6 19094 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 19095 bsr.l _imem_read_word 19095 bsr.l _imem_read_word 19096 19096 19097 tst.l %d1 19097 tst.l %d1 # did ifetch fail? 19098 bne.l fcea_iacc 19098 bne.l fcea_iacc # yes 19099 19099 19100 ext.l %d0 19100 ext.l %d0 # sign extend bd 19101 19101 19102 fchk_ind: 19102 fchk_ind: 19103 add.l %d0,%d3 19103 add.l %d0,%d3 # base += bd 19104 19104 19105 # outer displacement: 19105 # outer displacement: 19106 fno_bd: 19106 fno_bd: 19107 bfextu %d5{&30:&2},%d0 19107 bfextu %d5{&30:&2},%d0 # is od suppressed? 19108 beq.w faii_bd 19108 beq.w faii_bd 19109 19109 19110 cmpi.b %d0,&0x2 19110 cmpi.b %d0,&0x2 19111 blt.b fnull_od 19111 blt.b fnull_od 19112 beq.b fword_od 19112 beq.b fword_od 19113 19113 19114 mov.l EXC_EXTWPTR(%a6),%a0 19114 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19115 addq.l &0x4,EXC_EXTWPTR(%a6 19115 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19116 bsr.l _imem_read_long 19116 bsr.l _imem_read_long 19117 19117 19118 tst.l %d1 19118 tst.l %d1 # did ifetch fail? 19119 bne.l fcea_iacc 19119 bne.l fcea_iacc # yes 19120 19120 19121 bra.b fadd_them 19121 bra.b fadd_them 19122 19122 19123 fword_od: 19123 fword_od: 19124 mov.l EXC_EXTWPTR(%a6),%a0 19124 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19125 addq.l &0x2,EXC_EXTWPTR(%a6 19125 addq.l &0x2,EXC_EXTWPTR(%a6) # incr instruction ptr 19126 bsr.l _imem_read_word 19126 bsr.l _imem_read_word 19127 19127 19128 tst.l %d1 19128 tst.l %d1 # did ifetch fail? 19129 bne.l fcea_iacc 19129 bne.l fcea_iacc # yes 19130 19130 19131 ext.l %d0 19131 ext.l %d0 # sign extend od 19132 bra.b fadd_them 19132 bra.b fadd_them 19133 19133 19134 fnull_od: 19134 fnull_od: 19135 clr.l %d0 19135 clr.l %d0 19136 19136 19137 fadd_them: 19137 fadd_them: 19138 mov.l %d0,%d4 19138 mov.l %d0,%d4 19139 19139 19140 btst &0x2,%d5 19140 btst &0x2,%d5 # pre or post indexing? 19141 beq.b fpre_indexed 19141 beq.b fpre_indexed 19142 19142 19143 mov.l %d3,%a0 19143 mov.l %d3,%a0 19144 bsr.l _dmem_read_long 19144 bsr.l _dmem_read_long 19145 19145 19146 tst.l %d1 19146 tst.l %d1 # did dfetch fail? 19147 bne.w fcea_err 19147 bne.w fcea_err # yes 19148 19148 19149 add.l %d2,%d0 19149 add.l %d2,%d0 # <ea> += index 19150 add.l %d4,%d0 19150 add.l %d4,%d0 # <ea> += od 19151 bra.b fdone_ea 19151 bra.b fdone_ea 19152 19152 19153 fpre_indexed: 19153 fpre_indexed: 19154 add.l %d2,%d3 19154 add.l %d2,%d3 # preindexing 19155 mov.l %d3,%a0 19155 mov.l %d3,%a0 19156 bsr.l _dmem_read_long 19156 bsr.l _dmem_read_long 19157 19157 19158 tst.l %d1 19158 tst.l %d1 # did dfetch fail? 19159 bne.w fcea_err 19159 bne.w fcea_err # yes 19160 19160 19161 add.l %d4,%d0 19161 add.l %d4,%d0 # ea += od 19162 bra.b fdone_ea 19162 bra.b fdone_ea 19163 19163 19164 faii_bd: 19164 faii_bd: 19165 add.l %d2,%d3 19165 add.l %d2,%d3 # ea = (base + bd) + index 19166 mov.l %d3,%d0 19166 mov.l %d3,%d0 19167 fdone_ea: 19167 fdone_ea: 19168 mov.l %d0,%a0 19168 mov.l %d0,%a0 19169 19169 19170 movm.l (%sp)+,&0x003c 19170 movm.l (%sp)+,&0x003c # restore d2-d5 19171 rts 19171 rts 19172 19172 19173 ############################################ 19173 ######################################################### 19174 fcea_err: 19174 fcea_err: 19175 mov.l %d3,%a0 19175 mov.l %d3,%a0 19176 19176 19177 movm.l (%sp)+,&0x003c 19177 movm.l (%sp)+,&0x003c # restore d2-d5 19178 mov.w &0x0101,%d0 19178 mov.w &0x0101,%d0 19179 bra.l iea_dacc 19179 bra.l iea_dacc 19180 19180 19181 fcea_iacc: 19181 fcea_iacc: 19182 movm.l (%sp)+,&0x003c 19182 movm.l (%sp)+,&0x003c # restore d2-d5 19183 bra.l iea_iacc 19183 bra.l iea_iacc 19184 19184 19185 fmovm_out_err: 19185 fmovm_out_err: 19186 bsr.l restore 19186 bsr.l restore 19187 mov.w &0x00e1,%d0 19187 mov.w &0x00e1,%d0 19188 bra.b fmovm_err 19188 bra.b fmovm_err 19189 19189 19190 fmovm_in_err: 19190 fmovm_in_err: 19191 bsr.l restore 19191 bsr.l restore 19192 mov.w &0x0161,%d0 19192 mov.w &0x0161,%d0 19193 19193 19194 fmovm_err: 19194 fmovm_err: 19195 mov.l L_SCR1(%a6),%a0 19195 mov.l L_SCR1(%a6),%a0 19196 bra.l iea_dacc 19196 bra.l iea_dacc 19197 19197 19198 ############################################ 19198 ######################################################################### 19199 # XDEF ************************************* 19199 # XDEF **************************************************************** # 19200 # fmovm_ctrl(): emulate fmovm.l of con 19200 # fmovm_ctrl(): emulate fmovm.l of control registers instr # 19201 # 19201 # # 19202 # XREF ************************************* 19202 # XREF **************************************************************** # 19203 # _imem_read_long() - read longword fr 19203 # _imem_read_long() - read longword from memory # 19204 # iea_iacc() - _imem_read_long() faile 19204 # iea_iacc() - _imem_read_long() failed; error recovery # 19205 # 19205 # # 19206 # INPUT ************************************ 19206 # INPUT *************************************************************** # 19207 # None 19207 # None # 19208 # 19208 # # 19209 # OUTPUT *********************************** 19209 # OUTPUT ************************************************************** # 19210 # If _imem_read_long() doesn't fail: 19210 # If _imem_read_long() doesn't fail: # 19211 # USER_FPCR(a6) = new FPCR va 19211 # USER_FPCR(a6) = new FPCR value # 19212 # USER_FPSR(a6) = new FPSR va 19212 # USER_FPSR(a6) = new FPSR value # 19213 # USER_FPIAR(a6) = new FPIAR v 19213 # USER_FPIAR(a6) = new FPIAR value # 19214 # 19214 # # 19215 # ALGORITHM ******************************** 19215 # ALGORITHM *********************************************************** # 19216 # Decode the instruction type by looki 19216 # Decode the instruction type by looking at the extension word # 19217 # in order to see how many control registers 19217 # in order to see how many control registers to fetch from memory. # 19218 # Fetch them using _imem_read_long(). If thi 19218 # Fetch them using _imem_read_long(). If this fetch fails, exit through # 19219 # the special access error exit handler iea_ 19219 # the special access error exit handler iea_iacc(). # 19220 # 19220 # # 19221 # Instruction word decoding: 19221 # Instruction word decoding: # 19222 # 19222 # # 19223 # fmovem.l #<data>, {FPIAR&|FPCR&|FPSR 19223 # fmovem.l #<data>, {FPIAR&|FPCR&|FPSR} # 19224 # 19224 # # 19225 # WORD1 WORD 19225 # WORD1 WORD2 # 19226 # 1111 0010 00 111100 100$ $$00 00 19226 # 1111 0010 00 111100 100$ $$00 0000 0000 # 19227 # 19227 # # 19228 # $$$ (100): FPCR 19228 # $$$ (100): FPCR # 19229 # (010): FPSR 19229 # (010): FPSR # 19230 # (001): FPIAR 19230 # (001): FPIAR # 19231 # (000): FPIAR 19231 # (000): FPIAR # 19232 # 19232 # # 19233 ############################################ 19233 ######################################################################### 19234 19234 19235 global fmovm_ctrl 19235 global fmovm_ctrl 19236 fmovm_ctrl: 19236 fmovm_ctrl: 19237 mov.b EXC_EXTWORD(%a6),%d0 19237 mov.b EXC_EXTWORD(%a6),%d0 # fetch reg select bits 19238 cmpi.b %d0,&0x9c 19238 cmpi.b %d0,&0x9c # fpcr & fpsr & fpiar ? 19239 beq.w fctrl_in_7 19239 beq.w fctrl_in_7 # yes 19240 cmpi.b %d0,&0x98 19240 cmpi.b %d0,&0x98 # fpcr & fpsr ? 19241 beq.w fctrl_in_6 19241 beq.w fctrl_in_6 # yes 19242 cmpi.b %d0,&0x94 19242 cmpi.b %d0,&0x94 # fpcr & fpiar ? 19243 beq.b fctrl_in_5 19243 beq.b fctrl_in_5 # yes 19244 19244 19245 # fmovem.l #<data>, fpsr/fpiar 19245 # fmovem.l #<data>, fpsr/fpiar 19246 fctrl_in_3: 19246 fctrl_in_3: 19247 mov.l EXC_EXTWPTR(%a6),%a0 19247 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19248 addq.l &0x4,EXC_EXTWPTR(%a6 19248 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19249 bsr.l _imem_read_long 19249 bsr.l _imem_read_long # fetch FPSR from mem 19250 19250 19251 tst.l %d1 19251 tst.l %d1 # did ifetch fail? 19252 bne.l iea_iacc 19252 bne.l iea_iacc # yes 19253 19253 19254 mov.l %d0,USER_FPSR(%a6) 19254 mov.l %d0,USER_FPSR(%a6) # store new FPSR to stack 19255 mov.l EXC_EXTWPTR(%a6),%a0 19255 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19256 addq.l &0x4,EXC_EXTWPTR(%a6 19256 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19257 bsr.l _imem_read_long 19257 bsr.l _imem_read_long # fetch FPIAR from mem 19258 19258 19259 tst.l %d1 19259 tst.l %d1 # did ifetch fail? 19260 bne.l iea_iacc 19260 bne.l iea_iacc # yes 19261 19261 19262 mov.l %d0,USER_FPIAR(%a6) 19262 mov.l %d0,USER_FPIAR(%a6) # store new FPIAR to stack 19263 rts 19263 rts 19264 19264 19265 # fmovem.l #<data>, fpcr/fpiar 19265 # fmovem.l #<data>, fpcr/fpiar 19266 fctrl_in_5: 19266 fctrl_in_5: 19267 mov.l EXC_EXTWPTR(%a6),%a0 19267 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19268 addq.l &0x4,EXC_EXTWPTR(%a6 19268 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19269 bsr.l _imem_read_long 19269 bsr.l _imem_read_long # fetch FPCR from mem 19270 19270 19271 tst.l %d1 19271 tst.l %d1 # did ifetch fail? 19272 bne.l iea_iacc 19272 bne.l iea_iacc # yes 19273 19273 19274 mov.l %d0,USER_FPCR(%a6) 19274 mov.l %d0,USER_FPCR(%a6) # store new FPCR to stack 19275 mov.l EXC_EXTWPTR(%a6),%a0 19275 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19276 addq.l &0x4,EXC_EXTWPTR(%a6 19276 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19277 bsr.l _imem_read_long 19277 bsr.l _imem_read_long # fetch FPIAR from mem 19278 19278 19279 tst.l %d1 19279 tst.l %d1 # did ifetch fail? 19280 bne.l iea_iacc 19280 bne.l iea_iacc # yes 19281 19281 19282 mov.l %d0,USER_FPIAR(%a6) 19282 mov.l %d0,USER_FPIAR(%a6) # store new FPIAR to stack 19283 rts 19283 rts 19284 19284 19285 # fmovem.l #<data>, fpcr/fpsr 19285 # fmovem.l #<data>, fpcr/fpsr 19286 fctrl_in_6: 19286 fctrl_in_6: 19287 mov.l EXC_EXTWPTR(%a6),%a0 19287 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19288 addq.l &0x4,EXC_EXTWPTR(%a6 19288 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19289 bsr.l _imem_read_long 19289 bsr.l _imem_read_long # fetch FPCR from mem 19290 19290 19291 tst.l %d1 19291 tst.l %d1 # did ifetch fail? 19292 bne.l iea_iacc 19292 bne.l iea_iacc # yes 19293 19293 19294 mov.l %d0,USER_FPCR(%a6) 19294 mov.l %d0,USER_FPCR(%a6) # store new FPCR to mem 19295 mov.l EXC_EXTWPTR(%a6),%a0 19295 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19296 addq.l &0x4,EXC_EXTWPTR(%a6 19296 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19297 bsr.l _imem_read_long 19297 bsr.l _imem_read_long # fetch FPSR from mem 19298 19298 19299 tst.l %d1 19299 tst.l %d1 # did ifetch fail? 19300 bne.l iea_iacc 19300 bne.l iea_iacc # yes 19301 19301 19302 mov.l %d0,USER_FPSR(%a6) 19302 mov.l %d0,USER_FPSR(%a6) # store new FPSR to mem 19303 rts 19303 rts 19304 19304 19305 # fmovem.l #<data>, fpcr/fpsr/fpiar 19305 # fmovem.l #<data>, fpcr/fpsr/fpiar 19306 fctrl_in_7: 19306 fctrl_in_7: 19307 mov.l EXC_EXTWPTR(%a6),%a0 19307 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19308 addq.l &0x4,EXC_EXTWPTR(%a6 19308 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19309 bsr.l _imem_read_long 19309 bsr.l _imem_read_long # fetch FPCR from mem 19310 19310 19311 tst.l %d1 19311 tst.l %d1 # did ifetch fail? 19312 bne.l iea_iacc 19312 bne.l iea_iacc # yes 19313 19313 19314 mov.l %d0,USER_FPCR(%a6) 19314 mov.l %d0,USER_FPCR(%a6) # store new FPCR to mem 19315 mov.l EXC_EXTWPTR(%a6),%a0 19315 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19316 addq.l &0x4,EXC_EXTWPTR(%a6 19316 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19317 bsr.l _imem_read_long 19317 bsr.l _imem_read_long # fetch FPSR from mem 19318 19318 19319 tst.l %d1 19319 tst.l %d1 # did ifetch fail? 19320 bne.l iea_iacc 19320 bne.l iea_iacc # yes 19321 19321 19322 mov.l %d0,USER_FPSR(%a6) 19322 mov.l %d0,USER_FPSR(%a6) # store new FPSR to mem 19323 mov.l EXC_EXTWPTR(%a6),%a0 19323 mov.l EXC_EXTWPTR(%a6),%a0 # fetch instruction addr 19324 addq.l &0x4,EXC_EXTWPTR(%a6 19324 addq.l &0x4,EXC_EXTWPTR(%a6) # incr instruction ptr 19325 bsr.l _imem_read_long 19325 bsr.l _imem_read_long # fetch FPIAR from mem 19326 19326 19327 tst.l %d1 19327 tst.l %d1 # did ifetch fail? 19328 bne.l iea_iacc 19328 bne.l iea_iacc # yes 19329 19329 19330 mov.l %d0,USER_FPIAR(%a6) 19330 mov.l %d0,USER_FPIAR(%a6) # store new FPIAR to mem 19331 rts 19331 rts 19332 19332 19333 ############################################ 19333 ######################################################################### 19334 # XDEF ************************************* 19334 # XDEF **************************************************************** # 19335 # _dcalc_ea(): calc correct <ea> from 19335 # _dcalc_ea(): calc correct <ea> from <ea> stacked on exception # 19336 # 19336 # # 19337 # XREF ************************************* 19337 # XREF **************************************************************** # 19338 # inc_areg() - increment an address re 19338 # inc_areg() - increment an address register # 19339 # dec_areg() - decrement an address re 19339 # dec_areg() - decrement an address register # 19340 # 19340 # # 19341 # INPUT ************************************ 19341 # INPUT *************************************************************** # 19342 # d0 = number of bytes to adjust <ea> 19342 # d0 = number of bytes to adjust <ea> by # 19343 # 19343 # # 19344 # OUTPUT *********************************** 19344 # OUTPUT ************************************************************** # 19345 # None 19345 # None # 19346 # 19346 # # 19347 # ALGORITHM ******************************** 19347 # ALGORITHM *********************************************************** # 19348 # "Dummy" CALCulate Effective Address: 19348 # "Dummy" CALCulate Effective Address: # 19349 # The stacked <ea> for FP unimplemente 19349 # The stacked <ea> for FP unimplemented instructions and opclass # 19350 # two packed instructions is correct w 19350 # two packed instructions is correct with the exception of... # 19351 # 19351 # # 19352 # 1) -(An) : The register is not upd 19352 # 1) -(An) : The register is not updated regardless of size. # 19353 # Also, for extended prec 19353 # Also, for extended precision and packed, the # 19354 # stacked <ea> value is 8 19354 # stacked <ea> value is 8 bytes too big # 19355 # 2) (An)+ : The register is not upd 19355 # 2) (An)+ : The register is not updated. # 19356 # 3) #<data> : The upper longword of t 19356 # 3) #<data> : The upper longword of the immediate operand is # 19357 # stacked b,w,l and s siz 19357 # stacked b,w,l and s sizes are completely stacked. # 19358 # d,x, and p are not. 19358 # d,x, and p are not. # 19359 # 19359 # # 19360 ############################################ 19360 ######################################################################### 19361 19361 19362 global _dcalc_ea 19362 global _dcalc_ea 19363 _dcalc_ea: 19363 _dcalc_ea: 19364 mov.l %d0, %a0 19364 mov.l %d0, %a0 # move # bytes to %a0 19365 19365 19366 mov.b 1+EXC_OPWORD(%a6), % 19366 mov.b 1+EXC_OPWORD(%a6), %d0 # fetch opcode word 19367 mov.l %d0, %d1 19367 mov.l %d0, %d1 # make a copy 19368 19368 19369 andi.w &0x38, %d0 19369 andi.w &0x38, %d0 # extract mode field 19370 andi.l &0x7, %d1 19370 andi.l &0x7, %d1 # extract reg field 19371 19371 19372 cmpi.b %d0,&0x18 19372 cmpi.b %d0,&0x18 # is mode (An)+ ? 19373 beq.b dcea_pi 19373 beq.b dcea_pi # yes 19374 19374 19375 cmpi.b %d0,&0x20 19375 cmpi.b %d0,&0x20 # is mode -(An) ? 19376 beq.b dcea_pd 19376 beq.b dcea_pd # yes 19377 19377 19378 or.w %d1,%d0 19378 or.w %d1,%d0 # concat mode,reg 19379 cmpi.b %d0,&0x3c 19379 cmpi.b %d0,&0x3c # is mode #<data>? 19380 19380 19381 beq.b dcea_imm 19381 beq.b dcea_imm # yes 19382 19382 19383 mov.l EXC_EA(%a6),%a0 19383 mov.l EXC_EA(%a6),%a0 # return <ea> 19384 rts 19384 rts 19385 19385 19386 # need to set immediate data flag here since 19386 # need to set immediate data flag here since we'll need to do 19387 # an imem_read to fetch this later. 19387 # an imem_read to fetch this later. 19388 dcea_imm: 19388 dcea_imm: 19389 mov.b &immed_flg,SPCOND_FL 19389 mov.b &immed_flg,SPCOND_FLG(%a6) 19390 lea ([USER_FPIAR,%a6],0x 19390 lea ([USER_FPIAR,%a6],0x4),%a0 # no; return <ea> 19391 rts 19391 rts 19392 19392 19393 # here, the <ea> is stacked correctly. howev 19393 # here, the <ea> is stacked correctly. however, we must update the 19394 # address register... 19394 # address register... 19395 dcea_pi: 19395 dcea_pi: 19396 mov.l %a0,%d0 19396 mov.l %a0,%d0 # pass amt to inc by 19397 bsr.l inc_areg 19397 bsr.l inc_areg # inc addr register 19398 19398 19399 mov.l EXC_EA(%a6),%a0 19399 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 19400 rts 19400 rts 19401 19401 19402 # the <ea> is stacked correctly for all but 19402 # the <ea> is stacked correctly for all but extended and packed which 19403 # the <ea>s are 8 bytes too large. 19403 # the <ea>s are 8 bytes too large. 19404 # it would make no sense to have a pre-decre 19404 # it would make no sense to have a pre-decrement to a7 in supervisor 19405 # mode so we don't even worry about this tri 19405 # mode so we don't even worry about this tricky case here : ) 19406 dcea_pd: 19406 dcea_pd: 19407 mov.l %a0,%d0 19407 mov.l %a0,%d0 # pass amt to dec by 19408 bsr.l dec_areg 19408 bsr.l dec_areg # dec addr register 19409 19409 19410 mov.l EXC_EA(%a6),%a0 19410 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 19411 19411 19412 cmpi.b %d0,&0xc 19412 cmpi.b %d0,&0xc # is opsize ext or packed? 19413 beq.b dcea_pd2 19413 beq.b dcea_pd2 # yes 19414 rts 19414 rts 19415 dcea_pd2: 19415 dcea_pd2: 19416 sub.l &0x8,%a0 19416 sub.l &0x8,%a0 # correct <ea> 19417 mov.l %a0,EXC_EA(%a6) 19417 mov.l %a0,EXC_EA(%a6) # put correct <ea> on stack 19418 rts 19418 rts 19419 19419 19420 ############################################ 19420 ######################################################################### 19421 # XDEF ************************************* 19421 # XDEF **************************************************************** # 19422 # _calc_ea_fout(): calculate correct s 19422 # _calc_ea_fout(): calculate correct stacked <ea> for extended # 19423 # and packed data opc 19423 # and packed data opclass 3 operations. # 19424 # 19424 # # 19425 # XREF ************************************* 19425 # XREF **************************************************************** # 19426 # None 19426 # None # 19427 # 19427 # # 19428 # INPUT ************************************ 19428 # INPUT *************************************************************** # 19429 # None 19429 # None # 19430 # 19430 # # 19431 # OUTPUT *********************************** 19431 # OUTPUT ************************************************************** # 19432 # a0 = return correct effective addres 19432 # a0 = return correct effective address # 19433 # 19433 # # 19434 # ALGORITHM ******************************** 19434 # ALGORITHM *********************************************************** # 19435 # For opclass 3 extended and packed da 19435 # For opclass 3 extended and packed data operations, the <ea> # 19436 # stacked for the exception is incorrect for 19436 # stacked for the exception is incorrect for -(an) and (an)+ addressing # 19437 # modes. Also, while we're at it, the index 19437 # modes. Also, while we're at it, the index register itself must get # 19438 # updated. 19438 # updated. # 19439 # So, for -(an), we must subtract 8 of 19439 # So, for -(an), we must subtract 8 off of the stacked <ea> value # 19440 # and return that value as the correct <ea> 19440 # and return that value as the correct <ea> and store that value in An. # 19441 # For (an)+, the stacked <ea> is correct but 19441 # For (an)+, the stacked <ea> is correct but we must adjust An by +12. # 19442 # 19442 # # 19443 ############################################ 19443 ######################################################################### 19444 19444 19445 # This calc_ea is currently used to retrieve 19445 # This calc_ea is currently used to retrieve the correct <ea> 19446 # for fmove outs of type extended and packed 19446 # for fmove outs of type extended and packed. 19447 global _calc_ea_fout 19447 global _calc_ea_fout 19448 _calc_ea_fout: 19448 _calc_ea_fout: 19449 mov.b 1+EXC_OPWORD(%a6),%d 19449 mov.b 1+EXC_OPWORD(%a6),%d0 # fetch opcode word 19450 mov.l %d0,%d1 19450 mov.l %d0,%d1 # make a copy 19451 19451 19452 andi.w &0x38,%d0 19452 andi.w &0x38,%d0 # extract mode field 19453 andi.l &0x7,%d1 19453 andi.l &0x7,%d1 # extract reg field 19454 19454 19455 cmpi.b %d0,&0x18 19455 cmpi.b %d0,&0x18 # is mode (An)+ ? 19456 beq.b ceaf_pi 19456 beq.b ceaf_pi # yes 19457 19457 19458 cmpi.b %d0,&0x20 19458 cmpi.b %d0,&0x20 # is mode -(An) ? 19459 beq.w ceaf_pd 19459 beq.w ceaf_pd # yes 19460 19460 19461 mov.l EXC_EA(%a6),%a0 19461 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 19462 rts 19462 rts 19463 19463 19464 # (An)+ : extended and packed fmove out 19464 # (An)+ : extended and packed fmove out 19465 # : stacked <ea> is correct 19465 # : stacked <ea> is correct 19466 # : "An" not updated 19466 # : "An" not updated 19467 ceaf_pi: 19467 ceaf_pi: 19468 mov.w (tbl_ceaf_pi.b,%pc,% 19468 mov.w (tbl_ceaf_pi.b,%pc,%d1.w*2),%d1 19469 mov.l EXC_EA(%a6),%a0 19469 mov.l EXC_EA(%a6),%a0 19470 jmp (tbl_ceaf_pi.b,%pc,% 19470 jmp (tbl_ceaf_pi.b,%pc,%d1.w*1) 19471 19471 19472 swbeg &0x8 19472 swbeg &0x8 19473 tbl_ceaf_pi: 19473 tbl_ceaf_pi: 19474 short ceaf_pi0 - tbl_ceaf_ 19474 short ceaf_pi0 - tbl_ceaf_pi 19475 short ceaf_pi1 - tbl_ceaf_ 19475 short ceaf_pi1 - tbl_ceaf_pi 19476 short ceaf_pi2 - tbl_ceaf_ 19476 short ceaf_pi2 - tbl_ceaf_pi 19477 short ceaf_pi3 - tbl_ceaf_ 19477 short ceaf_pi3 - tbl_ceaf_pi 19478 short ceaf_pi4 - tbl_ceaf_ 19478 short ceaf_pi4 - tbl_ceaf_pi 19479 short ceaf_pi5 - tbl_ceaf_ 19479 short ceaf_pi5 - tbl_ceaf_pi 19480 short ceaf_pi6 - tbl_ceaf_ 19480 short ceaf_pi6 - tbl_ceaf_pi 19481 short ceaf_pi7 - tbl_ceaf_ 19481 short ceaf_pi7 - tbl_ceaf_pi 19482 19482 19483 ceaf_pi0: 19483 ceaf_pi0: 19484 addi.l &0xc,EXC_DREGS+0x8(% 19484 addi.l &0xc,EXC_DREGS+0x8(%a6) 19485 rts 19485 rts 19486 ceaf_pi1: 19486 ceaf_pi1: 19487 addi.l &0xc,EXC_DREGS+0xc(% 19487 addi.l &0xc,EXC_DREGS+0xc(%a6) 19488 rts 19488 rts 19489 ceaf_pi2: 19489 ceaf_pi2: 19490 add.l &0xc,%a2 19490 add.l &0xc,%a2 19491 rts 19491 rts 19492 ceaf_pi3: 19492 ceaf_pi3: 19493 add.l &0xc,%a3 19493 add.l &0xc,%a3 19494 rts 19494 rts 19495 ceaf_pi4: 19495 ceaf_pi4: 19496 add.l &0xc,%a4 19496 add.l &0xc,%a4 19497 rts 19497 rts 19498 ceaf_pi5: 19498 ceaf_pi5: 19499 add.l &0xc,%a5 19499 add.l &0xc,%a5 19500 rts 19500 rts 19501 ceaf_pi6: 19501 ceaf_pi6: 19502 addi.l &0xc,EXC_A6(%a6) 19502 addi.l &0xc,EXC_A6(%a6) 19503 rts 19503 rts 19504 ceaf_pi7: 19504 ceaf_pi7: 19505 mov.b &mia7_flg,SPCOND_FLG 19505 mov.b &mia7_flg,SPCOND_FLG(%a6) 19506 addi.l &0xc,EXC_A7(%a6) 19506 addi.l &0xc,EXC_A7(%a6) 19507 rts 19507 rts 19508 19508 19509 # -(An) : extended and packed fmove out 19509 # -(An) : extended and packed fmove out 19510 # : stacked <ea> = actual <ea> + 8 19510 # : stacked <ea> = actual <ea> + 8 19511 # : "An" not updated 19511 # : "An" not updated 19512 ceaf_pd: 19512 ceaf_pd: 19513 mov.w (tbl_ceaf_pd.b,%pc,% 19513 mov.w (tbl_ceaf_pd.b,%pc,%d1.w*2),%d1 19514 mov.l EXC_EA(%a6),%a0 19514 mov.l EXC_EA(%a6),%a0 19515 sub.l &0x8,%a0 19515 sub.l &0x8,%a0 19516 sub.l &0x8,EXC_EA(%a6) 19516 sub.l &0x8,EXC_EA(%a6) 19517 jmp (tbl_ceaf_pd.b,%pc,% 19517 jmp (tbl_ceaf_pd.b,%pc,%d1.w*1) 19518 19518 19519 swbeg &0x8 19519 swbeg &0x8 19520 tbl_ceaf_pd: 19520 tbl_ceaf_pd: 19521 short ceaf_pd0 - tbl_ceaf_ 19521 short ceaf_pd0 - tbl_ceaf_pd 19522 short ceaf_pd1 - tbl_ceaf_ 19522 short ceaf_pd1 - tbl_ceaf_pd 19523 short ceaf_pd2 - tbl_ceaf_ 19523 short ceaf_pd2 - tbl_ceaf_pd 19524 short ceaf_pd3 - tbl_ceaf_ 19524 short ceaf_pd3 - tbl_ceaf_pd 19525 short ceaf_pd4 - tbl_ceaf_ 19525 short ceaf_pd4 - tbl_ceaf_pd 19526 short ceaf_pd5 - tbl_ceaf_ 19526 short ceaf_pd5 - tbl_ceaf_pd 19527 short ceaf_pd6 - tbl_ceaf_ 19527 short ceaf_pd6 - tbl_ceaf_pd 19528 short ceaf_pd7 - tbl_ceaf_ 19528 short ceaf_pd7 - tbl_ceaf_pd 19529 19529 19530 ceaf_pd0: 19530 ceaf_pd0: 19531 mov.l %a0,EXC_DREGS+0x8(%a 19531 mov.l %a0,EXC_DREGS+0x8(%a6) 19532 rts 19532 rts 19533 ceaf_pd1: 19533 ceaf_pd1: 19534 mov.l %a0,EXC_DREGS+0xc(%a 19534 mov.l %a0,EXC_DREGS+0xc(%a6) 19535 rts 19535 rts 19536 ceaf_pd2: 19536 ceaf_pd2: 19537 mov.l %a0,%a2 19537 mov.l %a0,%a2 19538 rts 19538 rts 19539 ceaf_pd3: 19539 ceaf_pd3: 19540 mov.l %a0,%a3 19540 mov.l %a0,%a3 19541 rts 19541 rts 19542 ceaf_pd4: 19542 ceaf_pd4: 19543 mov.l %a0,%a4 19543 mov.l %a0,%a4 19544 rts 19544 rts 19545 ceaf_pd5: 19545 ceaf_pd5: 19546 mov.l %a0,%a5 19546 mov.l %a0,%a5 19547 rts 19547 rts 19548 ceaf_pd6: 19548 ceaf_pd6: 19549 mov.l %a0,EXC_A6(%a6) 19549 mov.l %a0,EXC_A6(%a6) 19550 rts 19550 rts 19551 ceaf_pd7: 19551 ceaf_pd7: 19552 mov.l %a0,EXC_A7(%a6) 19552 mov.l %a0,EXC_A7(%a6) 19553 mov.b &mda7_flg,SPCOND_FLG 19553 mov.b &mda7_flg,SPCOND_FLG(%a6) 19554 rts 19554 rts 19555 19555 19556 ############################################ 19556 ######################################################################### 19557 # XDEF ************************************* 19557 # XDEF **************************************************************** # 19558 # _load_fop(): load operand for unimpl 19558 # _load_fop(): load operand for unimplemented FP exception # 19559 # 19559 # # 19560 # XREF ************************************* 19560 # XREF **************************************************************** # 19561 # set_tag_x() - determine ext prec opt 19561 # set_tag_x() - determine ext prec optype tag # 19562 # set_tag_s() - determine sgl prec opt 19562 # set_tag_s() - determine sgl prec optype tag # 19563 # set_tag_d() - determine dbl prec opt 19563 # set_tag_d() - determine dbl prec optype tag # 19564 # unnorm_fix() - convert normalized nu 19564 # unnorm_fix() - convert normalized number to denorm or zero # 19565 # norm() - normalize a denormalized nu 19565 # norm() - normalize a denormalized number # 19566 # get_packed() - fetch a packed operan 19566 # get_packed() - fetch a packed operand from memory # 19567 # _dcalc_ea() - calculate <ea>, fixing 19567 # _dcalc_ea() - calculate <ea>, fixing An in process # 19568 # 19568 # # 19569 # _imem_read_{word,long}() - read from 19569 # _imem_read_{word,long}() - read from instruction memory # 19570 # _dmem_read() - read from data memory 19570 # _dmem_read() - read from data memory # 19571 # _dmem_read_{byte,word,long}() - read 19571 # _dmem_read_{byte,word,long}() - read from data memory # 19572 # 19572 # # 19573 # facc_in_{b,w,l,d,x}() - mem read fai 19573 # facc_in_{b,w,l,d,x}() - mem read failed; special exit point # 19574 # 19574 # # 19575 # INPUT ************************************ 19575 # INPUT *************************************************************** # 19576 # None 19576 # None # 19577 # 19577 # # 19578 # OUTPUT *********************************** 19578 # OUTPUT ************************************************************** # 19579 # If memory access doesn't fail: 19579 # If memory access doesn't fail: # 19580 # FP_SRC(a6) = source operand 19580 # FP_SRC(a6) = source operand in extended precision # 19581 # FP_DST(a6) = destination ope 19581 # FP_DST(a6) = destination operand in extended precision # 19582 # 19582 # # 19583 # ALGORITHM ******************************** 19583 # ALGORITHM *********************************************************** # 19584 # This is called from the Unimplemente 19584 # This is called from the Unimplemented FP exception handler in # 19585 # order to load the source and maybe destina 19585 # order to load the source and maybe destination operand into # 19586 # FP_SRC(a6) and FP_DST(a6). If the instruct 19586 # FP_SRC(a6) and FP_DST(a6). If the instruction was opclass zero, load # 19587 # the source and destination from the FP reg 19587 # the source and destination from the FP register file. Set the optype # 19588 # tags for both if dyadic, one for monadic. 19588 # tags for both if dyadic, one for monadic. If a number is an UNNORM, # 19589 # convert it to a DENORM or a ZERO. 19589 # convert it to a DENORM or a ZERO. # 19590 # If the instruction is opclass two (m 19590 # If the instruction is opclass two (memory->reg), then fetch # 19591 # the destination from the register file and 19591 # the destination from the register file and the source operand from # 19592 # memory. Tag and fix both as above w/ opcla 19592 # memory. Tag and fix both as above w/ opclass zero instructions. # 19593 # If the source operand is byte,word,l 19593 # If the source operand is byte,word,long, or single, it may be # 19594 # in the data register file. If it's actuall 19594 # in the data register file. If it's actually out in memory, use one of # 19595 # the mem_read() routines to fetch it. If th 19595 # the mem_read() routines to fetch it. If the mem_read() access returns # 19596 # a failing value, exit through the special 19596 # a failing value, exit through the special facc_in() routine which # 19597 # will create an access error exception fram 19597 # will create an access error exception frame from the current exception # 19598 # frame. 19598 # frame. # 19599 # Immediate data and regular data acce 19599 # Immediate data and regular data accesses are separated because # 19600 # if an immediate data access fails, the res 19600 # if an immediate data access fails, the resulting fault status # 19601 # longword stacked for the access error exce 19601 # longword stacked for the access error exception must have the # 19602 # instruction bit set. 19602 # instruction bit set. # 19603 # 19603 # # 19604 ############################################ 19604 ######################################################################### 19605 19605 19606 global _load_fop 19606 global _load_fop 19607 _load_fop: 19607 _load_fop: 19608 19608 19609 # 15 13 12 10 9 7 6 0 19609 # 15 13 12 10 9 7 6 0 19610 # / \ / \ / \ / \ 19610 # / \ / \ / \ / \ 19611 # --------------------------------- 19611 # --------------------------------- 19612 # | opclass | RX | RY | EXTENSION | (2nd w 19612 # | opclass | RX | RY | EXTENSION | (2nd word of general FP instruction) 19613 # --------------------------------- 19613 # --------------------------------- 19614 # 19614 # 19615 19615 19616 # bfextu EXC_CMDREG(%a6){&0:& 19616 # bfextu EXC_CMDREG(%a6){&0:&3}, %d0 # extract opclass 19617 # cmpi.b %d0, &0x2 19617 # cmpi.b %d0, &0x2 # which class is it? ('000,'010,'011) 19618 # beq.w op010 19618 # beq.w op010 # handle <ea> -> fpn 19619 # bgt.w op011 19619 # bgt.w op011 # handle fpn -> <ea> 19620 19620 19621 # we're not using op011 for now... 19621 # we're not using op011 for now... 19622 btst &0x6,EXC_CMDREG(%a6) 19622 btst &0x6,EXC_CMDREG(%a6) 19623 bne.b op010 19623 bne.b op010 19624 19624 19625 ############################ 19625 ############################ 19626 # OPCLASS '000: reg -> reg # 19626 # OPCLASS '000: reg -> reg # 19627 ############################ 19627 ############################ 19628 op000: 19628 op000: 19629 mov.b 1+EXC_CMDREG(%a6),%d 19629 mov.b 1+EXC_CMDREG(%a6),%d0 # fetch extension word lo 19630 btst &0x5,%d0 19630 btst &0x5,%d0 # testing extension bits 19631 beq.b op000_src 19631 beq.b op000_src # (bit 5 == 0) => monadic 19632 btst &0x4,%d0 19632 btst &0x4,%d0 # (bit 5 == 1) 19633 beq.b op000_dst 19633 beq.b op000_dst # (bit 4 == 0) => dyadic 19634 and.w &0x007f,%d0 19634 and.w &0x007f,%d0 # extract extension bits {6:0} 19635 cmpi.w %d0,&0x0038 19635 cmpi.w %d0,&0x0038 # is it an fcmp (dyadic) ? 19636 bne.b op000_src 19636 bne.b op000_src # it's an fcmp 19637 19637 19638 op000_dst: 19638 op000_dst: 19639 bfextu EXC_CMDREG(%a6){&6:& 19639 bfextu EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field 19640 bsr.l load_fpn2 19640 bsr.l load_fpn2 # fetch dst fpreg into FP_DST 19641 19641 19642 bsr.l set_tag_x 19642 bsr.l set_tag_x # get dst optype tag 19643 19643 19644 cmpi.b %d0, &UNNORM 19644 cmpi.b %d0, &UNNORM # is dst fpreg an UNNORM? 19645 beq.b op000_dst_unnorm 19645 beq.b op000_dst_unnorm # yes 19646 op000_dst_cont: 19646 op000_dst_cont: 19647 mov.b %d0, DTAG(%a6) 19647 mov.b %d0, DTAG(%a6) # store the dst optype tag 19648 19648 19649 op000_src: 19649 op000_src: 19650 bfextu EXC_CMDREG(%a6){&3:& 19650 bfextu EXC_CMDREG(%a6){&3:&3}, %d0 # extract src field 19651 bsr.l load_fpn1 19651 bsr.l load_fpn1 # fetch src fpreg into FP_SRC 19652 19652 19653 bsr.l set_tag_x 19653 bsr.l set_tag_x # get src optype tag 19654 19654 19655 cmpi.b %d0, &UNNORM 19655 cmpi.b %d0, &UNNORM # is src fpreg an UNNORM? 19656 beq.b op000_src_unnorm 19656 beq.b op000_src_unnorm # yes 19657 op000_src_cont: 19657 op000_src_cont: 19658 mov.b %d0, STAG(%a6) 19658 mov.b %d0, STAG(%a6) # store the src optype tag 19659 rts 19659 rts 19660 19660 19661 op000_dst_unnorm: 19661 op000_dst_unnorm: 19662 bsr.l unnorm_fix 19662 bsr.l unnorm_fix # fix the dst UNNORM 19663 bra.b op000_dst_cont 19663 bra.b op000_dst_cont 19664 op000_src_unnorm: 19664 op000_src_unnorm: 19665 bsr.l unnorm_fix 19665 bsr.l unnorm_fix # fix the src UNNORM 19666 bra.b op000_src_cont 19666 bra.b op000_src_cont 19667 19667 19668 ############################# 19668 ############################# 19669 # OPCLASS '010: <ea> -> reg # 19669 # OPCLASS '010: <ea> -> reg # 19670 ############################# 19670 ############################# 19671 op010: 19671 op010: 19672 mov.w EXC_CMDREG(%a6),%d0 19672 mov.w EXC_CMDREG(%a6),%d0 # fetch extension word 19673 btst &0x5,%d0 19673 btst &0x5,%d0 # testing extension bits 19674 beq.b op010_src 19674 beq.b op010_src # (bit 5 == 0) => monadic 19675 btst &0x4,%d0 19675 btst &0x4,%d0 # (bit 5 == 1) 19676 beq.b op010_dst 19676 beq.b op010_dst # (bit 4 == 0) => dyadic 19677 and.w &0x007f,%d0 19677 and.w &0x007f,%d0 # extract extension bits {6:0} 19678 cmpi.w %d0,&0x0038 19678 cmpi.w %d0,&0x0038 # is it an fcmp (dyadic) ? 19679 bne.b op010_src 19679 bne.b op010_src # it's an fcmp 19680 19680 19681 op010_dst: 19681 op010_dst: 19682 bfextu EXC_CMDREG(%a6){&6:& 19682 bfextu EXC_CMDREG(%a6){&6:&3}, %d0 # extract dst field 19683 bsr.l load_fpn2 19683 bsr.l load_fpn2 # fetch dst fpreg ptr 19684 19684 19685 bsr.l set_tag_x 19685 bsr.l set_tag_x # get dst type tag 19686 19686 19687 cmpi.b %d0, &UNNORM 19687 cmpi.b %d0, &UNNORM # is dst fpreg an UNNORM? 19688 beq.b op010_dst_unnorm 19688 beq.b op010_dst_unnorm # yes 19689 op010_dst_cont: 19689 op010_dst_cont: 19690 mov.b %d0, DTAG(%a6) 19690 mov.b %d0, DTAG(%a6) # store the dst optype tag 19691 19691 19692 op010_src: 19692 op010_src: 19693 bfextu EXC_CMDREG(%a6){&3:& 19693 bfextu EXC_CMDREG(%a6){&3:&3}, %d0 # extract src type field 19694 19694 19695 bfextu EXC_OPWORD(%a6){&10: 19695 bfextu EXC_OPWORD(%a6){&10:&3}, %d1 # extract <ea> mode field 19696 bne.w fetch_from_mem 19696 bne.w fetch_from_mem # src op is in memory 19697 19697 19698 op010_dreg: 19698 op010_dreg: 19699 clr.b STAG(%a6) 19699 clr.b STAG(%a6) # either NORM or ZERO 19700 bfextu EXC_OPWORD(%a6){&13: 19700 bfextu EXC_OPWORD(%a6){&13:&3}, %d1 # extract src reg field 19701 19701 19702 mov.w (tbl_op010_dreg.b,%p 19702 mov.w (tbl_op010_dreg.b,%pc,%d0.w*2), %d0 # jmp based on optype 19703 jmp (tbl_op010_dreg.b,%p 19703 jmp (tbl_op010_dreg.b,%pc,%d0.w*1) # fetch src from dreg 19704 19704 19705 op010_dst_unnorm: 19705 op010_dst_unnorm: 19706 bsr.l unnorm_fix 19706 bsr.l unnorm_fix # fix the dst UNNORM 19707 bra.b op010_dst_cont 19707 bra.b op010_dst_cont 19708 19708 19709 swbeg &0x8 19709 swbeg &0x8 19710 tbl_op010_dreg: 19710 tbl_op010_dreg: 19711 short opd_long - tb 19711 short opd_long - tbl_op010_dreg 19712 short opd_sgl - tb 19712 short opd_sgl - tbl_op010_dreg 19713 short tbl_op010_dreg - tb 19713 short tbl_op010_dreg - tbl_op010_dreg 19714 short tbl_op010_dreg - tb 19714 short tbl_op010_dreg - tbl_op010_dreg 19715 short opd_word - tb 19715 short opd_word - tbl_op010_dreg 19716 short tbl_op010_dreg - tb 19716 short tbl_op010_dreg - tbl_op010_dreg 19717 short opd_byte - tb 19717 short opd_byte - tbl_op010_dreg 19718 short tbl_op010_dreg - tb 19718 short tbl_op010_dreg - tbl_op010_dreg 19719 19719 19720 # 19720 # 19721 # LONG: can be either NORM or ZERO... 19721 # LONG: can be either NORM or ZERO... 19722 # 19722 # 19723 opd_long: 19723 opd_long: 19724 bsr.l fetch_dreg 19724 bsr.l fetch_dreg # fetch long in d0 19725 fmov.l %d0, %fp0 19725 fmov.l %d0, %fp0 # load a long 19726 fmovm.x &0x80, FP_SRC(%a6) 19726 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19727 fbeq.w opd_long_zero 19727 fbeq.w opd_long_zero # long is a ZERO 19728 rts 19728 rts 19729 opd_long_zero: 19729 opd_long_zero: 19730 mov.b &ZERO, STAG(%a6) 19730 mov.b &ZERO, STAG(%a6) # set ZERO optype flag 19731 rts 19731 rts 19732 19732 19733 # 19733 # 19734 # WORD: can be either NORM or ZERO... 19734 # WORD: can be either NORM or ZERO... 19735 # 19735 # 19736 opd_word: 19736 opd_word: 19737 bsr.l fetch_dreg 19737 bsr.l fetch_dreg # fetch word in d0 19738 fmov.w %d0, %fp0 19738 fmov.w %d0, %fp0 # load a word 19739 fmovm.x &0x80, FP_SRC(%a6) 19739 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19740 fbeq.w opd_word_zero 19740 fbeq.w opd_word_zero # WORD is a ZERO 19741 rts 19741 rts 19742 opd_word_zero: 19742 opd_word_zero: 19743 mov.b &ZERO, STAG(%a6) 19743 mov.b &ZERO, STAG(%a6) # set ZERO optype flag 19744 rts 19744 rts 19745 19745 19746 # 19746 # 19747 # BYTE: can be either NORM or ZERO... 19747 # BYTE: can be either NORM or ZERO... 19748 # 19748 # 19749 opd_byte: 19749 opd_byte: 19750 bsr.l fetch_dreg 19750 bsr.l fetch_dreg # fetch word in d0 19751 fmov.b %d0, %fp0 19751 fmov.b %d0, %fp0 # load a byte 19752 fmovm.x &0x80, FP_SRC(%a6) 19752 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19753 fbeq.w opd_byte_zero 19753 fbeq.w opd_byte_zero # byte is a ZERO 19754 rts 19754 rts 19755 opd_byte_zero: 19755 opd_byte_zero: 19756 mov.b &ZERO, STAG(%a6) 19756 mov.b &ZERO, STAG(%a6) # set ZERO optype flag 19757 rts 19757 rts 19758 19758 19759 # 19759 # 19760 # SGL: can be either NORM, DENORM, ZERO, INF 19760 # SGL: can be either NORM, DENORM, ZERO, INF, QNAN or SNAN but not UNNORM 19761 # 19761 # 19762 # separate SNANs and DENORMs so they can be 19762 # separate SNANs and DENORMs so they can be loaded w/ special care. 19763 # all others can simply be moved "in" using 19763 # all others can simply be moved "in" using fmove. 19764 # 19764 # 19765 opd_sgl: 19765 opd_sgl: 19766 bsr.l fetch_dreg 19766 bsr.l fetch_dreg # fetch sgl in d0 19767 mov.l %d0,L_SCR1(%a6) 19767 mov.l %d0,L_SCR1(%a6) 19768 19768 19769 lea L_SCR1(%a6), %a0 19769 lea L_SCR1(%a6), %a0 # pass: ptr to the sgl 19770 bsr.l set_tag_s 19770 bsr.l set_tag_s # determine sgl type 19771 mov.b %d0, STAG(%a6) 19771 mov.b %d0, STAG(%a6) # save the src tag 19772 19772 19773 cmpi.b %d0, &SNAN 19773 cmpi.b %d0, &SNAN # is it an SNAN? 19774 beq.w get_sgl_snan 19774 beq.w get_sgl_snan # yes 19775 19775 19776 cmpi.b %d0, &DENORM 19776 cmpi.b %d0, &DENORM # is it a DENORM? 19777 beq.w get_sgl_denorm 19777 beq.w get_sgl_denorm # yes 19778 19778 19779 fmov.s (%a0), %fp0 19779 fmov.s (%a0), %fp0 # no, so can load it regular 19780 fmovm.x &0x80, FP_SRC(%a6) 19780 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19781 rts 19781 rts 19782 19782 19783 ############################################ 19783 ############################################################################## 19784 19784 19785 ############################################ 19785 ######################################################################### 19786 # fetch_from_mem(): 19786 # fetch_from_mem(): # 19787 # - src is out in memory. must: 19787 # - src is out in memory. must: # 19788 # (1) calc ea - must read AFTER you kn 19788 # (1) calc ea - must read AFTER you know the src type since # 19789 # if the ea is -() or () 19789 # if the ea is -() or ()+, need to know # of bytes. # 19790 # (2) read it in from either user or s 19790 # (2) read it in from either user or supervisor space # 19791 # (3) if (b || w || l) then simply rea 19791 # (3) if (b || w || l) then simply read in # 19792 # if (s || d || x) then check for 19792 # if (s || d || x) then check for SNAN,UNNORM,DENORM # 19793 # if (packed) then punt for now 19793 # if (packed) then punt for now # 19794 # INPUT: 19794 # INPUT: # 19795 # %d0 : src type field 19795 # %d0 : src type field # 19796 ############################################ 19796 ######################################################################### 19797 fetch_from_mem: 19797 fetch_from_mem: 19798 clr.b STAG(%a6) 19798 clr.b STAG(%a6) # either NORM or ZERO 19799 19799 19800 mov.w (tbl_fp_type.b,%pc,% 19800 mov.w (tbl_fp_type.b,%pc,%d0.w*2), %d0 # index by src type field 19801 jmp (tbl_fp_type.b,%pc,% 19801 jmp (tbl_fp_type.b,%pc,%d0.w*1) 19802 19802 19803 swbeg &0x8 19803 swbeg &0x8 19804 tbl_fp_type: 19804 tbl_fp_type: 19805 short load_long - tb 19805 short load_long - tbl_fp_type 19806 short load_sgl - tb 19806 short load_sgl - tbl_fp_type 19807 short load_ext - tb 19807 short load_ext - tbl_fp_type 19808 short load_packed - tb 19808 short load_packed - tbl_fp_type 19809 short load_word - tb 19809 short load_word - tbl_fp_type 19810 short load_dbl - tb 19810 short load_dbl - tbl_fp_type 19811 short load_byte - tb 19811 short load_byte - tbl_fp_type 19812 short tbl_fp_type - tb 19812 short tbl_fp_type - tbl_fp_type 19813 19813 19814 ######################################### 19814 ######################################### 19815 # load a LONG into %fp0: # 19815 # load a LONG into %fp0: # 19816 # -number can't fault # 19816 # -number can't fault # 19817 # (1) calc ea # 19817 # (1) calc ea # 19818 # (2) read 4 bytes into L_SCR1 # 19818 # (2) read 4 bytes into L_SCR1 # 19819 # (3) fmov.l into %fp0 # 19819 # (3) fmov.l into %fp0 # 19820 ######################################### 19820 ######################################### 19821 load_long: 19821 load_long: 19822 movq.l &0x4, %d0 19822 movq.l &0x4, %d0 # pass: 4 (bytes) 19823 bsr.l _dcalc_ea 19823 bsr.l _dcalc_ea # calc <ea>; <ea> in %a0 19824 19824 19825 cmpi.b SPCOND_FLG(%a6),&imm 19825 cmpi.b SPCOND_FLG(%a6),&immed_flg 19826 beq.b load_long_immed 19826 beq.b load_long_immed 19827 19827 19828 bsr.l _dmem_read_long 19828 bsr.l _dmem_read_long # fetch src operand from memory 19829 19829 19830 tst.l %d1 19830 tst.l %d1 # did dfetch fail? 19831 bne.l facc_in_l 19831 bne.l facc_in_l # yes 19832 19832 19833 load_long_cont: 19833 load_long_cont: 19834 fmov.l %d0, %fp0 19834 fmov.l %d0, %fp0 # read into %fp0;convert to xprec 19835 fmovm.x &0x80, FP_SRC(%a6) 19835 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19836 19836 19837 fbeq.w load_long_zero 19837 fbeq.w load_long_zero # src op is a ZERO 19838 rts 19838 rts 19839 load_long_zero: 19839 load_long_zero: 19840 mov.b &ZERO, STAG(%a6) 19840 mov.b &ZERO, STAG(%a6) # set optype tag to ZERO 19841 rts 19841 rts 19842 19842 19843 load_long_immed: 19843 load_long_immed: 19844 bsr.l _imem_read_long 19844 bsr.l _imem_read_long # fetch src operand immed data 19845 19845 19846 tst.l %d1 19846 tst.l %d1 # did ifetch fail? 19847 bne.l funimp_iacc 19847 bne.l funimp_iacc # yes 19848 bra.b load_long_cont 19848 bra.b load_long_cont 19849 19849 19850 ######################################### 19850 ######################################### 19851 # load a WORD into %fp0: # 19851 # load a WORD into %fp0: # 19852 # -number can't fault # 19852 # -number can't fault # 19853 # (1) calc ea # 19853 # (1) calc ea # 19854 # (2) read 2 bytes into L_SCR1 # 19854 # (2) read 2 bytes into L_SCR1 # 19855 # (3) fmov.w into %fp0 # 19855 # (3) fmov.w into %fp0 # 19856 ######################################### 19856 ######################################### 19857 load_word: 19857 load_word: 19858 movq.l &0x2, %d0 19858 movq.l &0x2, %d0 # pass: 2 (bytes) 19859 bsr.l _dcalc_ea 19859 bsr.l _dcalc_ea # calc <ea>; <ea> in %a0 19860 19860 19861 cmpi.b SPCOND_FLG(%a6),&imm 19861 cmpi.b SPCOND_FLG(%a6),&immed_flg 19862 beq.b load_word_immed 19862 beq.b load_word_immed 19863 19863 19864 bsr.l _dmem_read_word 19864 bsr.l _dmem_read_word # fetch src operand from memory 19865 19865 19866 tst.l %d1 19866 tst.l %d1 # did dfetch fail? 19867 bne.l facc_in_w 19867 bne.l facc_in_w # yes 19868 19868 19869 load_word_cont: 19869 load_word_cont: 19870 fmov.w %d0, %fp0 19870 fmov.w %d0, %fp0 # read into %fp0;convert to xprec 19871 fmovm.x &0x80, FP_SRC(%a6) 19871 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19872 19872 19873 fbeq.w load_word_zero 19873 fbeq.w load_word_zero # src op is a ZERO 19874 rts 19874 rts 19875 load_word_zero: 19875 load_word_zero: 19876 mov.b &ZERO, STAG(%a6) 19876 mov.b &ZERO, STAG(%a6) # set optype tag to ZERO 19877 rts 19877 rts 19878 19878 19879 load_word_immed: 19879 load_word_immed: 19880 bsr.l _imem_read_word 19880 bsr.l _imem_read_word # fetch src operand immed data 19881 19881 19882 tst.l %d1 19882 tst.l %d1 # did ifetch fail? 19883 bne.l funimp_iacc 19883 bne.l funimp_iacc # yes 19884 bra.b load_word_cont 19884 bra.b load_word_cont 19885 19885 19886 ######################################### 19886 ######################################### 19887 # load a BYTE into %fp0: # 19887 # load a BYTE into %fp0: # 19888 # -number can't fault # 19888 # -number can't fault # 19889 # (1) calc ea # 19889 # (1) calc ea # 19890 # (2) read 1 byte into L_SCR1 # 19890 # (2) read 1 byte into L_SCR1 # 19891 # (3) fmov.b into %fp0 # 19891 # (3) fmov.b into %fp0 # 19892 ######################################### 19892 ######################################### 19893 load_byte: 19893 load_byte: 19894 movq.l &0x1, %d0 19894 movq.l &0x1, %d0 # pass: 1 (byte) 19895 bsr.l _dcalc_ea 19895 bsr.l _dcalc_ea # calc <ea>; <ea> in %a0 19896 19896 19897 cmpi.b SPCOND_FLG(%a6),&imm 19897 cmpi.b SPCOND_FLG(%a6),&immed_flg 19898 beq.b load_byte_immed 19898 beq.b load_byte_immed 19899 19899 19900 bsr.l _dmem_read_byte 19900 bsr.l _dmem_read_byte # fetch src operand from memory 19901 19901 19902 tst.l %d1 19902 tst.l %d1 # did dfetch fail? 19903 bne.l facc_in_b 19903 bne.l facc_in_b # yes 19904 19904 19905 load_byte_cont: 19905 load_byte_cont: 19906 fmov.b %d0, %fp0 19906 fmov.b %d0, %fp0 # read into %fp0;convert to xprec 19907 fmovm.x &0x80, FP_SRC(%a6) 19907 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19908 19908 19909 fbeq.w load_byte_zero 19909 fbeq.w load_byte_zero # src op is a ZERO 19910 rts 19910 rts 19911 load_byte_zero: 19911 load_byte_zero: 19912 mov.b &ZERO, STAG(%a6) 19912 mov.b &ZERO, STAG(%a6) # set optype tag to ZERO 19913 rts 19913 rts 19914 19914 19915 load_byte_immed: 19915 load_byte_immed: 19916 bsr.l _imem_read_word 19916 bsr.l _imem_read_word # fetch src operand immed data 19917 19917 19918 tst.l %d1 19918 tst.l %d1 # did ifetch fail? 19919 bne.l funimp_iacc 19919 bne.l funimp_iacc # yes 19920 bra.b load_byte_cont 19920 bra.b load_byte_cont 19921 19921 19922 ######################################### 19922 ######################################### 19923 # load a SGL into %fp0: # 19923 # load a SGL into %fp0: # 19924 # -number can't fault # 19924 # -number can't fault # 19925 # (1) calc ea # 19925 # (1) calc ea # 19926 # (2) read 4 bytes into L_SCR1 # 19926 # (2) read 4 bytes into L_SCR1 # 19927 # (3) fmov.s into %fp0 # 19927 # (3) fmov.s into %fp0 # 19928 ######################################### 19928 ######################################### 19929 load_sgl: 19929 load_sgl: 19930 movq.l &0x4, %d0 19930 movq.l &0x4, %d0 # pass: 4 (bytes) 19931 bsr.l _dcalc_ea 19931 bsr.l _dcalc_ea # calc <ea>; <ea> in %a0 19932 19932 19933 cmpi.b SPCOND_FLG(%a6),&imm 19933 cmpi.b SPCOND_FLG(%a6),&immed_flg 19934 beq.b load_sgl_immed 19934 beq.b load_sgl_immed 19935 19935 19936 bsr.l _dmem_read_long 19936 bsr.l _dmem_read_long # fetch src operand from memory 19937 mov.l %d0, L_SCR1(%a6) 19937 mov.l %d0, L_SCR1(%a6) # store src op on stack 19938 19938 19939 tst.l %d1 19939 tst.l %d1 # did dfetch fail? 19940 bne.l facc_in_l 19940 bne.l facc_in_l # yes 19941 19941 19942 load_sgl_cont: 19942 load_sgl_cont: 19943 lea L_SCR1(%a6), %a0 19943 lea L_SCR1(%a6), %a0 # pass: ptr to sgl src op 19944 bsr.l set_tag_s 19944 bsr.l set_tag_s # determine src type tag 19945 mov.b %d0, STAG(%a6) 19945 mov.b %d0, STAG(%a6) # save src optype tag on stack 19946 19946 19947 cmpi.b %d0, &DENORM 19947 cmpi.b %d0, &DENORM # is it a sgl DENORM? 19948 beq.w get_sgl_denorm 19948 beq.w get_sgl_denorm # yes 19949 19949 19950 cmpi.b %d0, &SNAN 19950 cmpi.b %d0, &SNAN # is it a sgl SNAN? 19951 beq.w get_sgl_snan 19951 beq.w get_sgl_snan # yes 19952 19952 19953 fmov.s L_SCR1(%a6), %fp0 19953 fmov.s L_SCR1(%a6), %fp0 # read into %fp0;convert to xprec 19954 fmovm.x &0x80, FP_SRC(%a6) 19954 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 19955 rts 19955 rts 19956 19956 19957 load_sgl_immed: 19957 load_sgl_immed: 19958 bsr.l _imem_read_long 19958 bsr.l _imem_read_long # fetch src operand immed data 19959 19959 19960 tst.l %d1 19960 tst.l %d1 # did ifetch fail? 19961 bne.l funimp_iacc 19961 bne.l funimp_iacc # yes 19962 bra.b load_sgl_cont 19962 bra.b load_sgl_cont 19963 19963 19964 # must convert sgl denorm format to an Xprec 19964 # must convert sgl denorm format to an Xprec denorm fmt suitable for 19965 # normalization... 19965 # normalization... 19966 # %a0 : points to sgl denorm 19966 # %a0 : points to sgl denorm 19967 get_sgl_denorm: 19967 get_sgl_denorm: 19968 clr.w FP_SRC_EX(%a6) 19968 clr.w FP_SRC_EX(%a6) 19969 bfextu (%a0){&9:&23}, %d0 19969 bfextu (%a0){&9:&23}, %d0 # fetch sgl hi(_mantissa) 19970 lsl.l &0x8, %d0 19970 lsl.l &0x8, %d0 19971 mov.l %d0, FP_SRC_HI(%a6) 19971 mov.l %d0, FP_SRC_HI(%a6) # set ext hi(_mantissa) 19972 clr.l FP_SRC_LO(%a6) 19972 clr.l FP_SRC_LO(%a6) # set ext lo(_mantissa) 19973 19973 19974 clr.w FP_SRC_EX(%a6) 19974 clr.w FP_SRC_EX(%a6) 19975 btst &0x7, (%a0) 19975 btst &0x7, (%a0) # is sgn bit set? 19976 beq.b sgl_dnrm_norm 19976 beq.b sgl_dnrm_norm 19977 bset &0x7, FP_SRC_EX(%a6) 19977 bset &0x7, FP_SRC_EX(%a6) # set sgn of xprec value 19978 19978 19979 sgl_dnrm_norm: 19979 sgl_dnrm_norm: 19980 lea FP_SRC(%a6), %a0 19980 lea FP_SRC(%a6), %a0 19981 bsr.l norm 19981 bsr.l norm # normalize number 19982 mov.w &0x3f81, %d1 19982 mov.w &0x3f81, %d1 # xprec exp = 0x3f81 19983 sub.w %d0, %d1 19983 sub.w %d0, %d1 # exp = 0x3f81 - shft amt. 19984 or.w %d1, FP_SRC_EX(%a6) 19984 or.w %d1, FP_SRC_EX(%a6) # {sgn,exp} 19985 19985 19986 mov.b &NORM, STAG(%a6) 19986 mov.b &NORM, STAG(%a6) # fix src type tag 19987 rts 19987 rts 19988 19988 19989 # convert sgl to ext SNAN 19989 # convert sgl to ext SNAN 19990 # %a0 : points to sgl SNAN 19990 # %a0 : points to sgl SNAN 19991 get_sgl_snan: 19991 get_sgl_snan: 19992 mov.w &0x7fff, FP_SRC_EX(% 19992 mov.w &0x7fff, FP_SRC_EX(%a6) # set exp of SNAN 19993 bfextu (%a0){&9:&23}, %d0 19993 bfextu (%a0){&9:&23}, %d0 19994 lsl.l &0x8, %d0 19994 lsl.l &0x8, %d0 # extract and insert hi(man) 19995 mov.l %d0, FP_SRC_HI(%a6) 19995 mov.l %d0, FP_SRC_HI(%a6) 19996 clr.l FP_SRC_LO(%a6) 19996 clr.l FP_SRC_LO(%a6) 19997 19997 19998 btst &0x7, (%a0) 19998 btst &0x7, (%a0) # see if sign of SNAN is set 19999 beq.b no_sgl_snan_sgn 19999 beq.b no_sgl_snan_sgn 20000 bset &0x7, FP_SRC_EX(%a6) 20000 bset &0x7, FP_SRC_EX(%a6) 20001 no_sgl_snan_sgn: 20001 no_sgl_snan_sgn: 20002 rts 20002 rts 20003 20003 20004 ######################################### 20004 ######################################### 20005 # load a DBL into %fp0: # 20005 # load a DBL into %fp0: # 20006 # -number can't fault # 20006 # -number can't fault # 20007 # (1) calc ea # 20007 # (1) calc ea # 20008 # (2) read 8 bytes into L_SCR(1,2)# 20008 # (2) read 8 bytes into L_SCR(1,2)# 20009 # (3) fmov.d into %fp0 # 20009 # (3) fmov.d into %fp0 # 20010 ######################################### 20010 ######################################### 20011 load_dbl: 20011 load_dbl: 20012 movq.l &0x8, %d0 20012 movq.l &0x8, %d0 # pass: 8 (bytes) 20013 bsr.l _dcalc_ea 20013 bsr.l _dcalc_ea # calc <ea>; <ea> in %a0 20014 20014 20015 cmpi.b SPCOND_FLG(%a6),&imm 20015 cmpi.b SPCOND_FLG(%a6),&immed_flg 20016 beq.b load_dbl_immed 20016 beq.b load_dbl_immed 20017 20017 20018 lea L_SCR1(%a6), %a1 20018 lea L_SCR1(%a6), %a1 # pass: ptr to input dbl tmp space 20019 movq.l &0x8, %d0 20019 movq.l &0x8, %d0 # pass: # bytes to read 20020 bsr.l _dmem_read 20020 bsr.l _dmem_read # fetch src operand from memory 20021 20021 20022 tst.l %d1 20022 tst.l %d1 # did dfetch fail? 20023 bne.l facc_in_d 20023 bne.l facc_in_d # yes 20024 20024 20025 load_dbl_cont: 20025 load_dbl_cont: 20026 lea L_SCR1(%a6), %a0 20026 lea L_SCR1(%a6), %a0 # pass: ptr to input dbl 20027 bsr.l set_tag_d 20027 bsr.l set_tag_d # determine src type tag 20028 mov.b %d0, STAG(%a6) 20028 mov.b %d0, STAG(%a6) # set src optype tag 20029 20029 20030 cmpi.b %d0, &DENORM 20030 cmpi.b %d0, &DENORM # is it a dbl DENORM? 20031 beq.w get_dbl_denorm 20031 beq.w get_dbl_denorm # yes 20032 20032 20033 cmpi.b %d0, &SNAN 20033 cmpi.b %d0, &SNAN # is it a dbl SNAN? 20034 beq.w get_dbl_snan 20034 beq.w get_dbl_snan # yes 20035 20035 20036 fmov.d L_SCR1(%a6), %fp0 20036 fmov.d L_SCR1(%a6), %fp0 # read into %fp0;convert to xprec 20037 fmovm.x &0x80, FP_SRC(%a6) 20037 fmovm.x &0x80, FP_SRC(%a6) # return src op in FP_SRC 20038 rts 20038 rts 20039 20039 20040 load_dbl_immed: 20040 load_dbl_immed: 20041 lea L_SCR1(%a6), %a1 20041 lea L_SCR1(%a6), %a1 # pass: ptr to input dbl tmp space 20042 movq.l &0x8, %d0 20042 movq.l &0x8, %d0 # pass: # bytes to read 20043 bsr.l _imem_read 20043 bsr.l _imem_read # fetch src operand from memory 20044 20044 20045 tst.l %d1 20045 tst.l %d1 # did ifetch fail? 20046 bne.l funimp_iacc 20046 bne.l funimp_iacc # yes 20047 bra.b load_dbl_cont 20047 bra.b load_dbl_cont 20048 20048 20049 # must convert dbl denorm format to an Xprec 20049 # must convert dbl denorm format to an Xprec denorm fmt suitable for 20050 # normalization... 20050 # normalization... 20051 # %a0 : loc. of dbl denorm 20051 # %a0 : loc. of dbl denorm 20052 get_dbl_denorm: 20052 get_dbl_denorm: 20053 clr.w FP_SRC_EX(%a6) 20053 clr.w FP_SRC_EX(%a6) 20054 bfextu (%a0){&12:&31}, %d0 20054 bfextu (%a0){&12:&31}, %d0 # fetch hi(_mantissa) 20055 mov.l %d0, FP_SRC_HI(%a6) 20055 mov.l %d0, FP_SRC_HI(%a6) 20056 bfextu 4(%a0){&11:&21}, %d0 20056 bfextu 4(%a0){&11:&21}, %d0 # fetch lo(_mantissa) 20057 mov.l &0xb, %d1 20057 mov.l &0xb, %d1 20058 lsl.l %d1, %d0 20058 lsl.l %d1, %d0 20059 mov.l %d0, FP_SRC_LO(%a6) 20059 mov.l %d0, FP_SRC_LO(%a6) 20060 20060 20061 btst &0x7, (%a0) 20061 btst &0x7, (%a0) # is sgn bit set? 20062 beq.b dbl_dnrm_norm 20062 beq.b dbl_dnrm_norm 20063 bset &0x7, FP_SRC_EX(%a6) 20063 bset &0x7, FP_SRC_EX(%a6) # set sgn of xprec value 20064 20064 20065 dbl_dnrm_norm: 20065 dbl_dnrm_norm: 20066 lea FP_SRC(%a6), %a0 20066 lea FP_SRC(%a6), %a0 20067 bsr.l norm 20067 bsr.l norm # normalize number 20068 mov.w &0x3c01, %d1 20068 mov.w &0x3c01, %d1 # xprec exp = 0x3c01 20069 sub.w %d0, %d1 20069 sub.w %d0, %d1 # exp = 0x3c01 - shft amt. 20070 or.w %d1, FP_SRC_EX(%a6) 20070 or.w %d1, FP_SRC_EX(%a6) # {sgn,exp} 20071 20071 20072 mov.b &NORM, STAG(%a6) 20072 mov.b &NORM, STAG(%a6) # fix src type tag 20073 rts 20073 rts 20074 20074 20075 # convert dbl to ext SNAN 20075 # convert dbl to ext SNAN 20076 # %a0 : points to dbl SNAN 20076 # %a0 : points to dbl SNAN 20077 get_dbl_snan: 20077 get_dbl_snan: 20078 mov.w &0x7fff, FP_SRC_EX(% 20078 mov.w &0x7fff, FP_SRC_EX(%a6) # set exp of SNAN 20079 20079 20080 bfextu (%a0){&12:&31}, %d0 20080 bfextu (%a0){&12:&31}, %d0 # fetch hi(_mantissa) 20081 mov.l %d0, FP_SRC_HI(%a6) 20081 mov.l %d0, FP_SRC_HI(%a6) 20082 bfextu 4(%a0){&11:&21}, %d0 20082 bfextu 4(%a0){&11:&21}, %d0 # fetch lo(_mantissa) 20083 mov.l &0xb, %d1 20083 mov.l &0xb, %d1 20084 lsl.l %d1, %d0 20084 lsl.l %d1, %d0 20085 mov.l %d0, FP_SRC_LO(%a6) 20085 mov.l %d0, FP_SRC_LO(%a6) 20086 20086 20087 btst &0x7, (%a0) 20087 btst &0x7, (%a0) # see if sign of SNAN is set 20088 beq.b no_dbl_snan_sgn 20088 beq.b no_dbl_snan_sgn 20089 bset &0x7, FP_SRC_EX(%a6) 20089 bset &0x7, FP_SRC_EX(%a6) 20090 no_dbl_snan_sgn: 20090 no_dbl_snan_sgn: 20091 rts 20091 rts 20092 20092 20093 ############################################ 20093 ################################################# 20094 # load a Xprec into %fp0: 20094 # load a Xprec into %fp0: # 20095 # -number can't fault 20095 # -number can't fault # 20096 # (1) calc ea 20096 # (1) calc ea # 20097 # (2) read 12 bytes into L_SCR(1,2) 20097 # (2) read 12 bytes into L_SCR(1,2) # 20098 # (3) fmov.x into %fp0 20098 # (3) fmov.x into %fp0 # 20099 ############################################ 20099 ################################################# 20100 load_ext: 20100 load_ext: 20101 mov.l &0xc, %d0 20101 mov.l &0xc, %d0 # pass: 12 (bytes) 20102 bsr.l _dcalc_ea 20102 bsr.l _dcalc_ea # calc <ea> 20103 20103 20104 lea FP_SRC(%a6), %a1 20104 lea FP_SRC(%a6), %a1 # pass: ptr to input ext tmp space 20105 mov.l &0xc, %d0 20105 mov.l &0xc, %d0 # pass: # of bytes to read 20106 bsr.l _dmem_read 20106 bsr.l _dmem_read # fetch src operand from memory 20107 20107 20108 tst.l %d1 20108 tst.l %d1 # did dfetch fail? 20109 bne.l facc_in_x 20109 bne.l facc_in_x # yes 20110 20110 20111 lea FP_SRC(%a6), %a0 20111 lea FP_SRC(%a6), %a0 # pass: ptr to src op 20112 bsr.l set_tag_x 20112 bsr.l set_tag_x # determine src type tag 20113 20113 20114 cmpi.b %d0, &UNNORM 20114 cmpi.b %d0, &UNNORM # is the src op an UNNORM? 20115 beq.b load_ext_unnorm 20115 beq.b load_ext_unnorm # yes 20116 20116 20117 mov.b %d0, STAG(%a6) 20117 mov.b %d0, STAG(%a6) # store the src optype tag 20118 rts 20118 rts 20119 20119 20120 load_ext_unnorm: 20120 load_ext_unnorm: 20121 bsr.l unnorm_fix 20121 bsr.l unnorm_fix # fix the src UNNORM 20122 mov.b %d0, STAG(%a6) 20122 mov.b %d0, STAG(%a6) # store the src optype tag 20123 rts 20123 rts 20124 20124 20125 ############################################ 20125 ################################################# 20126 # load a packed into %fp0: 20126 # load a packed into %fp0: # 20127 # -number can't fault 20127 # -number can't fault # 20128 # (1) calc ea 20128 # (1) calc ea # 20129 # (2) read 12 bytes into L_SCR(1,2,3) 20129 # (2) read 12 bytes into L_SCR(1,2,3) # 20130 # (3) fmov.x into %fp0 20130 # (3) fmov.x into %fp0 # 20131 ############################################ 20131 ################################################# 20132 load_packed: 20132 load_packed: 20133 bsr.l get_packed 20133 bsr.l get_packed 20134 20134 20135 lea FP_SRC(%a6),%a0 20135 lea FP_SRC(%a6),%a0 # pass ptr to src op 20136 bsr.l set_tag_x 20136 bsr.l set_tag_x # determine src type tag 20137 cmpi.b %d0,&UNNORM 20137 cmpi.b %d0,&UNNORM # is the src op an UNNORM ZERO? 20138 beq.b load_packed_unnorm 20138 beq.b load_packed_unnorm # yes 20139 20139 20140 mov.b %d0,STAG(%a6) 20140 mov.b %d0,STAG(%a6) # store the src optype tag 20141 rts 20141 rts 20142 20142 20143 load_packed_unnorm: 20143 load_packed_unnorm: 20144 bsr.l unnorm_fix 20144 bsr.l unnorm_fix # fix the UNNORM ZERO 20145 mov.b %d0,STAG(%a6) 20145 mov.b %d0,STAG(%a6) # store the src optype tag 20146 rts 20146 rts 20147 20147 20148 ############################################ 20148 ######################################################################### 20149 # XDEF ************************************* 20149 # XDEF **************************************************************** # 20150 # fout(): move from fp register to mem 20150 # fout(): move from fp register to memory or data register # 20151 # 20151 # # 20152 # XREF ************************************* 20152 # XREF **************************************************************** # 20153 # _round() - needed to create EXOP for 20153 # _round() - needed to create EXOP for sgl/dbl precision # 20154 # norm() - needed to create EXOP for e 20154 # norm() - needed to create EXOP for extended precision # 20155 # ovf_res() - create default overflow 20155 # ovf_res() - create default overflow result for sgl/dbl precision# 20156 # unf_res() - create default underflow 20156 # unf_res() - create default underflow result for sgl/dbl prec. # 20157 # dst_dbl() - create rounded dbl preci 20157 # dst_dbl() - create rounded dbl precision result. # 20158 # dst_sgl() - create rounded sgl preci 20158 # dst_sgl() - create rounded sgl precision result. # 20159 # fetch_dreg() - fetch dynamic k-facto 20159 # fetch_dreg() - fetch dynamic k-factor reg for packed. # 20160 # bindec() - convert FP binary number 20160 # bindec() - convert FP binary number to packed number. # 20161 # _mem_write() - write data to memory. 20161 # _mem_write() - write data to memory. # 20162 # _mem_write2() - write data to memory 20162 # _mem_write2() - write data to memory unless supv mode -(a7) exc.# 20163 # _dmem_write_{byte,word,long}() - wri 20163 # _dmem_write_{byte,word,long}() - write data to memory. # 20164 # store_dreg_{b,w,l}() - store data to 20164 # store_dreg_{b,w,l}() - store data to data register file. # 20165 # facc_out_{b,w,l,d,x}() - data access 20165 # facc_out_{b,w,l,d,x}() - data access error occurred. # 20166 # 20166 # # 20167 # INPUT ************************************ 20167 # INPUT *************************************************************** # 20168 # a0 = pointer to extended precision s 20168 # a0 = pointer to extended precision source operand # 20169 # d0 = round prec,mode 20169 # d0 = round prec,mode # 20170 # 20170 # # 20171 # OUTPUT *********************************** 20171 # OUTPUT ************************************************************** # 20172 # fp0 : intermediate underflow or over 20172 # fp0 : intermediate underflow or overflow result if # 20173 # OVFL/UNFL occurred for a sgl o 20173 # OVFL/UNFL occurred for a sgl or dbl operand # 20174 # 20174 # # 20175 # ALGORITHM ******************************** 20175 # ALGORITHM *********************************************************** # 20176 # This routine is accessed by many han 20176 # This routine is accessed by many handlers that need to do an # 20177 # opclass three move of an operand out to me 20177 # opclass three move of an operand out to memory. # 20178 # Decode an fmove out (opclass 3) inst 20178 # Decode an fmove out (opclass 3) instruction to determine if # 20179 # it's b,w,l,s,d,x, or p in size. b,w,l can 20179 # it's b,w,l,s,d,x, or p in size. b,w,l can be stored to either a data # 20180 # register or memory. The algorithm uses a s 20180 # register or memory. The algorithm uses a standard "fmove" to create # 20181 # the rounded result. Also, since exceptions 20181 # the rounded result. Also, since exceptions are disabled, this also # 20182 # create the correct OPERR default result if 20182 # create the correct OPERR default result if appropriate. # 20183 # For sgl or dbl precision, overflow o 20183 # For sgl or dbl precision, overflow or underflow can occur. If # 20184 # either occurs and is enabled, the EXOP. 20184 # either occurs and is enabled, the EXOP. # 20185 # For extended precision, the stacked 20185 # For extended precision, the stacked <ea> must be fixed along # 20186 # w/ the address index register as appropria 20186 # w/ the address index register as appropriate w/ _calc_ea_fout(). If # 20187 # the source is a denorm and if underflow is 20187 # the source is a denorm and if underflow is enabled, an EXOP must be # 20188 # created. 20188 # created. # 20189 # For packed, the k-factor must be fet 20189 # For packed, the k-factor must be fetched from the instruction # 20190 # word or a data register. The <ea> must be 20190 # word or a data register. The <ea> must be fixed as w/ extended # 20191 # precision. Then, bindec() is called to cre 20191 # precision. Then, bindec() is called to create the appropriate # 20192 # packed result. 20192 # packed result. # 20193 # If at any time an access error is fl 20193 # If at any time an access error is flagged by one of the move- # 20194 # to-memory routines, then a special exit mu 20194 # to-memory routines, then a special exit must be made so that the # 20195 # access error can be handled properly. 20195 # access error can be handled properly. # 20196 # 20196 # # 20197 ############################################ 20197 ######################################################################### 20198 20198 20199 global fout 20199 global fout 20200 fout: 20200 fout: 20201 bfextu EXC_CMDREG(%a6){&3:& 20201 bfextu EXC_CMDREG(%a6){&3:&3},%d1 # extract dst fmt 20202 mov.w (tbl_fout.b,%pc,%d1. 20202 mov.w (tbl_fout.b,%pc,%d1.w*2),%a1 # use as index 20203 jmp (tbl_fout.b,%pc,%a1) 20203 jmp (tbl_fout.b,%pc,%a1) # jump to routine 20204 20204 20205 swbeg &0x8 20205 swbeg &0x8 20206 tbl_fout: 20206 tbl_fout: 20207 short fout_long - 20207 short fout_long - tbl_fout 20208 short fout_sgl - 20208 short fout_sgl - tbl_fout 20209 short fout_ext - 20209 short fout_ext - tbl_fout 20210 short fout_pack - 20210 short fout_pack - tbl_fout 20211 short fout_word - 20211 short fout_word - tbl_fout 20212 short fout_dbl - 20212 short fout_dbl - tbl_fout 20213 short fout_byte - 20213 short fout_byte - tbl_fout 20214 short fout_pack - 20214 short fout_pack - tbl_fout 20215 20215 20216 ############################################ 20216 ################################################################# 20217 # fmove.b out ############################## 20217 # fmove.b out ################################################### 20218 ############################################ 20218 ################################################################# 20219 20219 20220 # Only "Unimplemented Data Type" exceptions 20220 # Only "Unimplemented Data Type" exceptions enter here. The operand 20221 # is either a DENORM or a NORM. 20221 # is either a DENORM or a NORM. 20222 fout_byte: 20222 fout_byte: 20223 tst.b STAG(%a6) 20223 tst.b STAG(%a6) # is operand normalized? 20224 bne.b fout_byte_denorm 20224 bne.b fout_byte_denorm # no 20225 20225 20226 fmovm.x SRC(%a0),&0x80 20226 fmovm.x SRC(%a0),&0x80 # load value 20227 20227 20228 fout_byte_norm: 20228 fout_byte_norm: 20229 fmov.l %d0,%fpcr 20229 fmov.l %d0,%fpcr # insert rnd prec,mode 20230 20230 20231 fmov.b %fp0,%d0 20231 fmov.b %fp0,%d0 # exec move out w/ correct rnd mode 20232 20232 20233 fmov.l &0x0,%fpcr 20233 fmov.l &0x0,%fpcr # clear FPCR 20234 fmov.l %fpsr,%d1 20234 fmov.l %fpsr,%d1 # fetch FPSR 20235 or.w %d1,2+USER_FPSR(%a6) 20235 or.w %d1,2+USER_FPSR(%a6) # save new exc,accrued bits 20236 20236 20237 mov.b 1+EXC_OPWORD(%a6),%d 20237 mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode 20238 andi.b &0x38,%d1 20238 andi.b &0x38,%d1 # is mode == 0? (Dreg dst) 20239 beq.b fout_byte_dn 20239 beq.b fout_byte_dn # must save to integer regfile 20240 20240 20241 mov.l EXC_EA(%a6),%a0 20241 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 20242 bsr.l _dmem_write_byte 20242 bsr.l _dmem_write_byte # write byte 20243 20243 20244 tst.l %d1 20244 tst.l %d1 # did dstore fail? 20245 bne.l facc_out_b 20245 bne.l facc_out_b # yes 20246 20246 20247 rts 20247 rts 20248 20248 20249 fout_byte_dn: 20249 fout_byte_dn: 20250 mov.b 1+EXC_OPWORD(%a6),%d 20250 mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn 20251 andi.w &0x7,%d1 20251 andi.w &0x7,%d1 20252 bsr.l store_dreg_b 20252 bsr.l store_dreg_b 20253 rts 20253 rts 20254 20254 20255 fout_byte_denorm: 20255 fout_byte_denorm: 20256 mov.l SRC_EX(%a0),%d1 20256 mov.l SRC_EX(%a0),%d1 20257 andi.l &0x80000000,%d1 20257 andi.l &0x80000000,%d1 # keep DENORM sign 20258 ori.l &0x00800000,%d1 20258 ori.l &0x00800000,%d1 # make smallest sgl 20259 fmov.s %d1,%fp0 20259 fmov.s %d1,%fp0 20260 bra.b fout_byte_norm 20260 bra.b fout_byte_norm 20261 20261 20262 ############################################ 20262 ################################################################# 20263 # fmove.w out ############################## 20263 # fmove.w out ################################################### 20264 ############################################ 20264 ################################################################# 20265 20265 20266 # Only "Unimplemented Data Type" exceptions 20266 # Only "Unimplemented Data Type" exceptions enter here. The operand 20267 # is either a DENORM or a NORM. 20267 # is either a DENORM or a NORM. 20268 fout_word: 20268 fout_word: 20269 tst.b STAG(%a6) 20269 tst.b STAG(%a6) # is operand normalized? 20270 bne.b fout_word_denorm 20270 bne.b fout_word_denorm # no 20271 20271 20272 fmovm.x SRC(%a0),&0x80 20272 fmovm.x SRC(%a0),&0x80 # load value 20273 20273 20274 fout_word_norm: 20274 fout_word_norm: 20275 fmov.l %d0,%fpcr 20275 fmov.l %d0,%fpcr # insert rnd prec:mode 20276 20276 20277 fmov.w %fp0,%d0 20277 fmov.w %fp0,%d0 # exec move out w/ correct rnd mode 20278 20278 20279 fmov.l &0x0,%fpcr 20279 fmov.l &0x0,%fpcr # clear FPCR 20280 fmov.l %fpsr,%d1 20280 fmov.l %fpsr,%d1 # fetch FPSR 20281 or.w %d1,2+USER_FPSR(%a6) 20281 or.w %d1,2+USER_FPSR(%a6) # save new exc,accrued bits 20282 20282 20283 mov.b 1+EXC_OPWORD(%a6),%d 20283 mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode 20284 andi.b &0x38,%d1 20284 andi.b &0x38,%d1 # is mode == 0? (Dreg dst) 20285 beq.b fout_word_dn 20285 beq.b fout_word_dn # must save to integer regfile 20286 20286 20287 mov.l EXC_EA(%a6),%a0 20287 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 20288 bsr.l _dmem_write_word 20288 bsr.l _dmem_write_word # write word 20289 20289 20290 tst.l %d1 20290 tst.l %d1 # did dstore fail? 20291 bne.l facc_out_w 20291 bne.l facc_out_w # yes 20292 20292 20293 rts 20293 rts 20294 20294 20295 fout_word_dn: 20295 fout_word_dn: 20296 mov.b 1+EXC_OPWORD(%a6),%d 20296 mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn 20297 andi.w &0x7,%d1 20297 andi.w &0x7,%d1 20298 bsr.l store_dreg_w 20298 bsr.l store_dreg_w 20299 rts 20299 rts 20300 20300 20301 fout_word_denorm: 20301 fout_word_denorm: 20302 mov.l SRC_EX(%a0),%d1 20302 mov.l SRC_EX(%a0),%d1 20303 andi.l &0x80000000,%d1 20303 andi.l &0x80000000,%d1 # keep DENORM sign 20304 ori.l &0x00800000,%d1 20304 ori.l &0x00800000,%d1 # make smallest sgl 20305 fmov.s %d1,%fp0 20305 fmov.s %d1,%fp0 20306 bra.b fout_word_norm 20306 bra.b fout_word_norm 20307 20307 20308 ############################################ 20308 ################################################################# 20309 # fmove.l out ############################## 20309 # fmove.l out ################################################### 20310 ############################################ 20310 ################################################################# 20311 20311 20312 # Only "Unimplemented Data Type" exceptions 20312 # Only "Unimplemented Data Type" exceptions enter here. The operand 20313 # is either a DENORM or a NORM. 20313 # is either a DENORM or a NORM. 20314 fout_long: 20314 fout_long: 20315 tst.b STAG(%a6) 20315 tst.b STAG(%a6) # is operand normalized? 20316 bne.b fout_long_denorm 20316 bne.b fout_long_denorm # no 20317 20317 20318 fmovm.x SRC(%a0),&0x80 20318 fmovm.x SRC(%a0),&0x80 # load value 20319 20319 20320 fout_long_norm: 20320 fout_long_norm: 20321 fmov.l %d0,%fpcr 20321 fmov.l %d0,%fpcr # insert rnd prec:mode 20322 20322 20323 fmov.l %fp0,%d0 20323 fmov.l %fp0,%d0 # exec move out w/ correct rnd mode 20324 20324 20325 fmov.l &0x0,%fpcr 20325 fmov.l &0x0,%fpcr # clear FPCR 20326 fmov.l %fpsr,%d1 20326 fmov.l %fpsr,%d1 # fetch FPSR 20327 or.w %d1,2+USER_FPSR(%a6) 20327 or.w %d1,2+USER_FPSR(%a6) # save new exc,accrued bits 20328 20328 20329 fout_long_write: 20329 fout_long_write: 20330 mov.b 1+EXC_OPWORD(%a6),%d 20330 mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode 20331 andi.b &0x38,%d1 20331 andi.b &0x38,%d1 # is mode == 0? (Dreg dst) 20332 beq.b fout_long_dn 20332 beq.b fout_long_dn # must save to integer regfile 20333 20333 20334 mov.l EXC_EA(%a6),%a0 20334 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 20335 bsr.l _dmem_write_long 20335 bsr.l _dmem_write_long # write long 20336 20336 20337 tst.l %d1 20337 tst.l %d1 # did dstore fail? 20338 bne.l facc_out_l 20338 bne.l facc_out_l # yes 20339 20339 20340 rts 20340 rts 20341 20341 20342 fout_long_dn: 20342 fout_long_dn: 20343 mov.b 1+EXC_OPWORD(%a6),%d 20343 mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn 20344 andi.w &0x7,%d1 20344 andi.w &0x7,%d1 20345 bsr.l store_dreg_l 20345 bsr.l store_dreg_l 20346 rts 20346 rts 20347 20347 20348 fout_long_denorm: 20348 fout_long_denorm: 20349 mov.l SRC_EX(%a0),%d1 20349 mov.l SRC_EX(%a0),%d1 20350 andi.l &0x80000000,%d1 20350 andi.l &0x80000000,%d1 # keep DENORM sign 20351 ori.l &0x00800000,%d1 20351 ori.l &0x00800000,%d1 # make smallest sgl 20352 fmov.s %d1,%fp0 20352 fmov.s %d1,%fp0 20353 bra.b fout_long_norm 20353 bra.b fout_long_norm 20354 20354 20355 ############################################ 20355 ################################################################# 20356 # fmove.x out ############################## 20356 # fmove.x out ################################################### 20357 ############################################ 20357 ################################################################# 20358 20358 20359 # Only "Unimplemented Data Type" exceptions 20359 # Only "Unimplemented Data Type" exceptions enter here. The operand 20360 # is either a DENORM or a NORM. 20360 # is either a DENORM or a NORM. 20361 # The DENORM causes an Underflow exception. 20361 # The DENORM causes an Underflow exception. 20362 fout_ext: 20362 fout_ext: 20363 20363 20364 # we copy the extended precision result to F 20364 # we copy the extended precision result to FP_SCR0 so that the reserved 20365 # 16-bit field gets zeroed. we do this since 20365 # 16-bit field gets zeroed. we do this since we promise not to disturb 20366 # what's at SRC(a0). 20366 # what's at SRC(a0). 20367 mov.w SRC_EX(%a0),FP_SCR0_ 20367 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 20368 clr.w 2+FP_SCR0_EX(%a6) 20368 clr.w 2+FP_SCR0_EX(%a6) # clear reserved field 20369 mov.l SRC_HI(%a0),FP_SCR0_ 20369 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 20370 mov.l SRC_LO(%a0),FP_SCR0_ 20370 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 20371 20371 20372 fmovm.x SRC(%a0),&0x80 20372 fmovm.x SRC(%a0),&0x80 # return result 20373 20373 20374 bsr.l _calc_ea_fout 20374 bsr.l _calc_ea_fout # fix stacked <ea> 20375 20375 20376 mov.l %a0,%a1 20376 mov.l %a0,%a1 # pass: dst addr 20377 lea FP_SCR0(%a6),%a0 20377 lea FP_SCR0(%a6),%a0 # pass: src addr 20378 mov.l &0xc,%d0 20378 mov.l &0xc,%d0 # pass: opsize is 12 bytes 20379 20379 20380 # we must not yet write the extended precisi 20380 # we must not yet write the extended precision data to the stack 20381 # in the pre-decrement case from supervisor 20381 # in the pre-decrement case from supervisor mode or else we'll corrupt 20382 # the stack frame. so, leave it in FP_SRC fo 20382 # the stack frame. so, leave it in FP_SRC for now and deal with it later... 20383 cmpi.b SPCOND_FLG(%a6),&mda 20383 cmpi.b SPCOND_FLG(%a6),&mda7_flg 20384 beq.b fout_ext_a7 20384 beq.b fout_ext_a7 20385 20385 20386 bsr.l _dmem_write 20386 bsr.l _dmem_write # write ext prec number to memory 20387 20387 20388 tst.l %d1 20388 tst.l %d1 # did dstore fail? 20389 bne.w fout_ext_err 20389 bne.w fout_ext_err # yes 20390 20390 20391 tst.b STAG(%a6) 20391 tst.b STAG(%a6) # is operand normalized? 20392 bne.b fout_ext_denorm 20392 bne.b fout_ext_denorm # no 20393 rts 20393 rts 20394 20394 20395 # the number is a DENORM. must set the under 20395 # the number is a DENORM. must set the underflow exception bit 20396 fout_ext_denorm: 20396 fout_ext_denorm: 20397 bset &unfl_bit,FPSR_EXCEP 20397 bset &unfl_bit,FPSR_EXCEPT(%a6) # set underflow exc bit 20398 20398 20399 mov.b FPCR_ENABLE(%a6),%d0 20399 mov.b FPCR_ENABLE(%a6),%d0 20400 andi.b &0x0a,%d0 20400 andi.b &0x0a,%d0 # is UNFL or INEX enabled? 20401 bne.b fout_ext_exc 20401 bne.b fout_ext_exc # yes 20402 rts 20402 rts 20403 20403 20404 # we don't want to do the write if the excep 20404 # we don't want to do the write if the exception occurred in supervisor mode 20405 # so _mem_write2() handles this for us. 20405 # so _mem_write2() handles this for us. 20406 fout_ext_a7: 20406 fout_ext_a7: 20407 bsr.l _mem_write2 20407 bsr.l _mem_write2 # write ext prec number to memory 20408 20408 20409 tst.l %d1 20409 tst.l %d1 # did dstore fail? 20410 bne.w fout_ext_err 20410 bne.w fout_ext_err # yes 20411 20411 20412 tst.b STAG(%a6) 20412 tst.b STAG(%a6) # is operand normalized? 20413 bne.b fout_ext_denorm 20413 bne.b fout_ext_denorm # no 20414 rts 20414 rts 20415 20415 20416 fout_ext_exc: 20416 fout_ext_exc: 20417 lea FP_SCR0(%a6),%a0 20417 lea FP_SCR0(%a6),%a0 20418 bsr.l norm 20418 bsr.l norm # normalize the mantissa 20419 neg.w %d0 20419 neg.w %d0 # new exp = -(shft amt) 20420 andi.w &0x7fff,%d0 20420 andi.w &0x7fff,%d0 20421 andi.w &0x8000,FP_SCR0_EX(% 20421 andi.w &0x8000,FP_SCR0_EX(%a6) # keep only old sign 20422 or.w %d0,FP_SCR0_EX(%a6) 20422 or.w %d0,FP_SCR0_EX(%a6) # insert new exponent 20423 fmovm.x FP_SCR0(%a6),&0x40 20423 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 20424 rts 20424 rts 20425 20425 20426 fout_ext_err: 20426 fout_ext_err: 20427 mov.l EXC_A6(%a6),(%a6) 20427 mov.l EXC_A6(%a6),(%a6) # fix stacked a6 20428 bra.l facc_out_x 20428 bra.l facc_out_x 20429 20429 20430 ############################################ 20430 ######################################################################### 20431 # fmove.s out ############################## 20431 # fmove.s out ########################################################### 20432 ############################################ 20432 ######################################################################### 20433 fout_sgl: 20433 fout_sgl: 20434 andi.b &0x30,%d0 20434 andi.b &0x30,%d0 # clear rnd prec 20435 ori.b &s_mode*0x10,%d0 20435 ori.b &s_mode*0x10,%d0 # insert sgl prec 20436 mov.l %d0,L_SCR3(%a6) 20436 mov.l %d0,L_SCR3(%a6) # save rnd prec,mode on stack 20437 20437 20438 # 20438 # 20439 # operand is a normalized number. first, we 20439 # operand is a normalized number. first, we check to see if the move out 20440 # would cause either an underflow or overflo 20440 # would cause either an underflow or overflow. these cases are handled 20441 # separately. otherwise, set the FPCR to the 20441 # separately. otherwise, set the FPCR to the proper rounding mode and 20442 # execute the move. 20442 # execute the move. 20443 # 20443 # 20444 mov.w SRC_EX(%a0),%d0 20444 mov.w SRC_EX(%a0),%d0 # extract exponent 20445 andi.w &0x7fff,%d0 20445 andi.w &0x7fff,%d0 # strip sign 20446 20446 20447 cmpi.w %d0,&SGL_HI 20447 cmpi.w %d0,&SGL_HI # will operand overflow? 20448 bgt.w fout_sgl_ovfl 20448 bgt.w fout_sgl_ovfl # yes; go handle OVFL 20449 beq.w fout_sgl_may_ovfl 20449 beq.w fout_sgl_may_ovfl # maybe; go handle possible OVFL 20450 cmpi.w %d0,&SGL_LO 20450 cmpi.w %d0,&SGL_LO # will operand underflow? 20451 blt.w fout_sgl_unfl 20451 blt.w fout_sgl_unfl # yes; go handle underflow 20452 20452 20453 # 20453 # 20454 # NORMs(in range) can be stored out by a sim 20454 # NORMs(in range) can be stored out by a simple "fmov.s" 20455 # Unnormalized inputs can come through this 20455 # Unnormalized inputs can come through this point. 20456 # 20456 # 20457 fout_sgl_exg: 20457 fout_sgl_exg: 20458 fmovm.x SRC(%a0),&0x80 20458 fmovm.x SRC(%a0),&0x80 # fetch fop from stack 20459 20459 20460 fmov.l L_SCR3(%a6),%fpcr 20460 fmov.l L_SCR3(%a6),%fpcr # set FPCR 20461 fmov.l &0x0,%fpsr 20461 fmov.l &0x0,%fpsr # clear FPSR 20462 20462 20463 fmov.s %fp0,%d0 20463 fmov.s %fp0,%d0 # store does convert and round 20464 20464 20465 fmov.l &0x0,%fpcr 20465 fmov.l &0x0,%fpcr # clear FPCR 20466 fmov.l %fpsr,%d1 20466 fmov.l %fpsr,%d1 # save FPSR 20467 20467 20468 or.w %d1,2+USER_FPSR(%a6) 20468 or.w %d1,2+USER_FPSR(%a6) # set possible inex2/ainex 20469 20469 20470 fout_sgl_exg_write: 20470 fout_sgl_exg_write: 20471 mov.b 1+EXC_OPWORD(%a6),%d 20471 mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode 20472 andi.b &0x38,%d1 20472 andi.b &0x38,%d1 # is mode == 0? (Dreg dst) 20473 beq.b fout_sgl_exg_write_d 20473 beq.b fout_sgl_exg_write_dn # must save to integer regfile 20474 20474 20475 mov.l EXC_EA(%a6),%a0 20475 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 20476 bsr.l _dmem_write_long 20476 bsr.l _dmem_write_long # write long 20477 20477 20478 tst.l %d1 20478 tst.l %d1 # did dstore fail? 20479 bne.l facc_out_l 20479 bne.l facc_out_l # yes 20480 20480 20481 rts 20481 rts 20482 20482 20483 fout_sgl_exg_write_dn: 20483 fout_sgl_exg_write_dn: 20484 mov.b 1+EXC_OPWORD(%a6),%d 20484 mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn 20485 andi.w &0x7,%d1 20485 andi.w &0x7,%d1 20486 bsr.l store_dreg_l 20486 bsr.l store_dreg_l 20487 rts 20487 rts 20488 20488 20489 # 20489 # 20490 # here, we know that the operand would UNFL 20490 # here, we know that the operand would UNFL if moved out to single prec, 20491 # so, denorm and round and then use generic 20491 # so, denorm and round and then use generic store single routine to 20492 # write the value to memory. 20492 # write the value to memory. 20493 # 20493 # 20494 fout_sgl_unfl: 20494 fout_sgl_unfl: 20495 bset &unfl_bit,FPSR_EXCEP 20495 bset &unfl_bit,FPSR_EXCEPT(%a6) # set UNFL 20496 20496 20497 mov.w SRC_EX(%a0),FP_SCR0_ 20497 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 20498 mov.l SRC_HI(%a0),FP_SCR0_ 20498 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 20499 mov.l SRC_LO(%a0),FP_SCR0_ 20499 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 20500 mov.l %a0,-(%sp) 20500 mov.l %a0,-(%sp) 20501 20501 20502 clr.l %d0 20502 clr.l %d0 # pass: S.F. = 0 20503 20503 20504 cmpi.b STAG(%a6),&DENORM 20504 cmpi.b STAG(%a6),&DENORM # fetch src optype tag 20505 bne.b fout_sgl_unfl_cont 20505 bne.b fout_sgl_unfl_cont # let DENORMs fall through 20506 20506 20507 lea FP_SCR0(%a6),%a0 20507 lea FP_SCR0(%a6),%a0 20508 bsr.l norm 20508 bsr.l norm # normalize the DENORM 20509 20509 20510 fout_sgl_unfl_cont: 20510 fout_sgl_unfl_cont: 20511 lea FP_SCR0(%a6),%a0 20511 lea FP_SCR0(%a6),%a0 # pass: ptr to operand 20512 mov.l L_SCR3(%a6),%d1 20512 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 20513 bsr.l unf_res 20513 bsr.l unf_res # calc default underflow result 20514 20514 20515 lea FP_SCR0(%a6),%a0 20515 lea FP_SCR0(%a6),%a0 # pass: ptr to fop 20516 bsr.l dst_sgl 20516 bsr.l dst_sgl # convert to single prec 20517 20517 20518 mov.b 1+EXC_OPWORD(%a6),%d 20518 mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode 20519 andi.b &0x38,%d1 20519 andi.b &0x38,%d1 # is mode == 0? (Dreg dst) 20520 beq.b fout_sgl_unfl_dn 20520 beq.b fout_sgl_unfl_dn # must save to integer regfile 20521 20521 20522 mov.l EXC_EA(%a6),%a0 20522 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 20523 bsr.l _dmem_write_long 20523 bsr.l _dmem_write_long # write long 20524 20524 20525 tst.l %d1 20525 tst.l %d1 # did dstore fail? 20526 bne.l facc_out_l 20526 bne.l facc_out_l # yes 20527 20527 20528 bra.b fout_sgl_unfl_chkexc 20528 bra.b fout_sgl_unfl_chkexc 20529 20529 20530 fout_sgl_unfl_dn: 20530 fout_sgl_unfl_dn: 20531 mov.b 1+EXC_OPWORD(%a6),%d 20531 mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn 20532 andi.w &0x7,%d1 20532 andi.w &0x7,%d1 20533 bsr.l store_dreg_l 20533 bsr.l store_dreg_l 20534 20534 20535 fout_sgl_unfl_chkexc: 20535 fout_sgl_unfl_chkexc: 20536 mov.b FPCR_ENABLE(%a6),%d1 20536 mov.b FPCR_ENABLE(%a6),%d1 20537 andi.b &0x0a,%d1 20537 andi.b &0x0a,%d1 # is UNFL or INEX enabled? 20538 bne.w fout_sd_exc_unfl 20538 bne.w fout_sd_exc_unfl # yes 20539 addq.l &0x4,%sp 20539 addq.l &0x4,%sp 20540 rts 20540 rts 20541 20541 20542 # 20542 # 20543 # it's definitely an overflow so call ovf_re 20543 # it's definitely an overflow so call ovf_res to get the correct answer 20544 # 20544 # 20545 fout_sgl_ovfl: 20545 fout_sgl_ovfl: 20546 tst.b 3+SRC_HI(%a0) 20546 tst.b 3+SRC_HI(%a0) # is result inexact? 20547 bne.b fout_sgl_ovfl_inex2 20547 bne.b fout_sgl_ovfl_inex2 20548 tst.l SRC_LO(%a0) 20548 tst.l SRC_LO(%a0) # is result inexact? 20549 bne.b fout_sgl_ovfl_inex2 20549 bne.b fout_sgl_ovfl_inex2 20550 ori.w &ovfl_inx_mask,2+USE 20550 ori.w &ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex 20551 bra.b fout_sgl_ovfl_cont 20551 bra.b fout_sgl_ovfl_cont 20552 fout_sgl_ovfl_inex2: 20552 fout_sgl_ovfl_inex2: 20553 ori.w &ovfinx_mask,2+USER_ 20553 ori.w &ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2 20554 20554 20555 fout_sgl_ovfl_cont: 20555 fout_sgl_ovfl_cont: 20556 mov.l %a0,-(%sp) 20556 mov.l %a0,-(%sp) 20557 20557 20558 # call ovf_res() w/ sgl prec and the correct 20558 # call ovf_res() w/ sgl prec and the correct rnd mode to create the default 20559 # overflow result. DON'T save the returned c 20559 # overflow result. DON'T save the returned ccodes from ovf_res() since 20560 # fmove out doesn't alter them. 20560 # fmove out doesn't alter them. 20561 tst.b SRC_EX(%a0) 20561 tst.b SRC_EX(%a0) # is operand negative? 20562 smi %d1 20562 smi %d1 # set if so 20563 mov.l L_SCR3(%a6),%d0 20563 mov.l L_SCR3(%a6),%d0 # pass: sgl prec,rnd mode 20564 bsr.l ovf_res 20564 bsr.l ovf_res # calc OVFL result 20565 fmovm.x (%a0),&0x80 20565 fmovm.x (%a0),&0x80 # load default overflow result 20566 fmov.s %fp0,%d0 20566 fmov.s %fp0,%d0 # store to single 20567 20567 20568 mov.b 1+EXC_OPWORD(%a6),%d 20568 mov.b 1+EXC_OPWORD(%a6),%d1 # extract dst mode 20569 andi.b &0x38,%d1 20569 andi.b &0x38,%d1 # is mode == 0? (Dreg dst) 20570 beq.b fout_sgl_ovfl_dn 20570 beq.b fout_sgl_ovfl_dn # must save to integer regfile 20571 20571 20572 mov.l EXC_EA(%a6),%a0 20572 mov.l EXC_EA(%a6),%a0 # stacked <ea> is correct 20573 bsr.l _dmem_write_long 20573 bsr.l _dmem_write_long # write long 20574 20574 20575 tst.l %d1 20575 tst.l %d1 # did dstore fail? 20576 bne.l facc_out_l 20576 bne.l facc_out_l # yes 20577 20577 20578 bra.b fout_sgl_ovfl_chkexc 20578 bra.b fout_sgl_ovfl_chkexc 20579 20579 20580 fout_sgl_ovfl_dn: 20580 fout_sgl_ovfl_dn: 20581 mov.b 1+EXC_OPWORD(%a6),%d 20581 mov.b 1+EXC_OPWORD(%a6),%d1 # extract Dn 20582 andi.w &0x7,%d1 20582 andi.w &0x7,%d1 20583 bsr.l store_dreg_l 20583 bsr.l store_dreg_l 20584 20584 20585 fout_sgl_ovfl_chkexc: 20585 fout_sgl_ovfl_chkexc: 20586 mov.b FPCR_ENABLE(%a6),%d1 20586 mov.b FPCR_ENABLE(%a6),%d1 20587 andi.b &0x0a,%d1 20587 andi.b &0x0a,%d1 # is UNFL or INEX enabled? 20588 bne.w fout_sd_exc_ovfl 20588 bne.w fout_sd_exc_ovfl # yes 20589 addq.l &0x4,%sp 20589 addq.l &0x4,%sp 20590 rts 20590 rts 20591 20591 20592 # 20592 # 20593 # move out MAY overflow: 20593 # move out MAY overflow: 20594 # (1) force the exp to 0x3fff 20594 # (1) force the exp to 0x3fff 20595 # (2) do a move w/ appropriate rnd mode 20595 # (2) do a move w/ appropriate rnd mode 20596 # (3) if exp still equals zero, then insert 20596 # (3) if exp still equals zero, then insert original exponent 20597 # for the correct result. 20597 # for the correct result. 20598 # if exp now equals one, then it overflo 20598 # if exp now equals one, then it overflowed so call ovf_res. 20599 # 20599 # 20600 fout_sgl_may_ovfl: 20600 fout_sgl_may_ovfl: 20601 mov.w SRC_EX(%a0),%d1 20601 mov.w SRC_EX(%a0),%d1 # fetch current sign 20602 andi.w &0x8000,%d1 20602 andi.w &0x8000,%d1 # keep it,clear exp 20603 ori.w &0x3fff,%d1 20603 ori.w &0x3fff,%d1 # insert exp = 0 20604 mov.w %d1,FP_SCR0_EX(%a6) 20604 mov.w %d1,FP_SCR0_EX(%a6) # insert scaled exp 20605 mov.l SRC_HI(%a0),FP_SCR0_ 20605 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man) 20606 mov.l SRC_LO(%a0),FP_SCR0_ 20606 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man) 20607 20607 20608 fmov.l L_SCR3(%a6),%fpcr 20608 fmov.l L_SCR3(%a6),%fpcr # set FPCR 20609 20609 20610 fmov.x FP_SCR0(%a6),%fp0 20610 fmov.x FP_SCR0(%a6),%fp0 # force fop to be rounded 20611 fmov.l &0x0,%fpcr 20611 fmov.l &0x0,%fpcr # clear FPCR 20612 20612 20613 fabs.x %fp0 20613 fabs.x %fp0 # need absolute value 20614 fcmp.b %fp0,&0x2 20614 fcmp.b %fp0,&0x2 # did exponent increase? 20615 fblt.w fout_sgl_exg 20615 fblt.w fout_sgl_exg # no; go finish NORM 20616 bra.w fout_sgl_ovfl 20616 bra.w fout_sgl_ovfl # yes; go handle overflow 20617 20617 20618 ################ 20618 ################ 20619 20619 20620 fout_sd_exc_unfl: 20620 fout_sd_exc_unfl: 20621 mov.l (%sp)+,%a0 20621 mov.l (%sp)+,%a0 20622 20622 20623 mov.w SRC_EX(%a0),FP_SCR0_ 20623 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 20624 mov.l SRC_HI(%a0),FP_SCR0_ 20624 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 20625 mov.l SRC_LO(%a0),FP_SCR0_ 20625 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 20626 20626 20627 cmpi.b STAG(%a6),&DENORM 20627 cmpi.b STAG(%a6),&DENORM # was src a DENORM? 20628 bne.b fout_sd_exc_cont 20628 bne.b fout_sd_exc_cont # no 20629 20629 20630 lea FP_SCR0(%a6),%a0 20630 lea FP_SCR0(%a6),%a0 20631 bsr.l norm 20631 bsr.l norm 20632 neg.l %d0 20632 neg.l %d0 20633 andi.w &0x7fff,%d0 20633 andi.w &0x7fff,%d0 20634 bfins %d0,FP_SCR0_EX(%a6){ 20634 bfins %d0,FP_SCR0_EX(%a6){&1:&15} 20635 bra.b fout_sd_exc_cont 20635 bra.b fout_sd_exc_cont 20636 20636 20637 fout_sd_exc: 20637 fout_sd_exc: 20638 fout_sd_exc_ovfl: 20638 fout_sd_exc_ovfl: 20639 mov.l (%sp)+,%a0 20639 mov.l (%sp)+,%a0 # restore a0 20640 20640 20641 mov.w SRC_EX(%a0),FP_SCR0_ 20641 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 20642 mov.l SRC_HI(%a0),FP_SCR0_ 20642 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 20643 mov.l SRC_LO(%a0),FP_SCR0_ 20643 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 20644 20644 20645 fout_sd_exc_cont: 20645 fout_sd_exc_cont: 20646 bclr &0x7,FP_SCR0_EX(%a6) 20646 bclr &0x7,FP_SCR0_EX(%a6) # clear sign bit 20647 sne.b 2+FP_SCR0_EX(%a6) 20647 sne.b 2+FP_SCR0_EX(%a6) # set internal sign bit 20648 lea FP_SCR0(%a6),%a0 20648 lea FP_SCR0(%a6),%a0 # pass: ptr to DENORM 20649 20649 20650 mov.b 3+L_SCR3(%a6),%d1 20650 mov.b 3+L_SCR3(%a6),%d1 20651 lsr.b &0x4,%d1 20651 lsr.b &0x4,%d1 20652 andi.w &0x0c,%d1 20652 andi.w &0x0c,%d1 20653 swap %d1 20653 swap %d1 20654 mov.b 3+L_SCR3(%a6),%d1 20654 mov.b 3+L_SCR3(%a6),%d1 20655 lsr.b &0x4,%d1 20655 lsr.b &0x4,%d1 20656 andi.w &0x03,%d1 20656 andi.w &0x03,%d1 20657 clr.l %d0 20657 clr.l %d0 # pass: zero g,r,s 20658 bsr.l _round 20658 bsr.l _round # round the DENORM 20659 20659 20660 tst.b 2+FP_SCR0_EX(%a6) 20660 tst.b 2+FP_SCR0_EX(%a6) # is EXOP negative? 20661 beq.b fout_sd_exc_done 20661 beq.b fout_sd_exc_done # no 20662 bset &0x7,FP_SCR0_EX(%a6) 20662 bset &0x7,FP_SCR0_EX(%a6) # yes 20663 20663 20664 fout_sd_exc_done: 20664 fout_sd_exc_done: 20665 fmovm.x FP_SCR0(%a6),&0x40 20665 fmovm.x FP_SCR0(%a6),&0x40 # return EXOP in fp1 20666 rts 20666 rts 20667 20667 20668 ############################################ 20668 ################################################################# 20669 # fmove.d out ############################## 20669 # fmove.d out ################################################### 20670 ############################################ 20670 ################################################################# 20671 fout_dbl: 20671 fout_dbl: 20672 andi.b &0x30,%d0 20672 andi.b &0x30,%d0 # clear rnd prec 20673 ori.b &d_mode*0x10,%d0 20673 ori.b &d_mode*0x10,%d0 # insert dbl prec 20674 mov.l %d0,L_SCR3(%a6) 20674 mov.l %d0,L_SCR3(%a6) # save rnd prec,mode on stack 20675 20675 20676 # 20676 # 20677 # operand is a normalized number. first, we 20677 # operand is a normalized number. first, we check to see if the move out 20678 # would cause either an underflow or overflo 20678 # would cause either an underflow or overflow. these cases are handled 20679 # separately. otherwise, set the FPCR to the 20679 # separately. otherwise, set the FPCR to the proper rounding mode and 20680 # execute the move. 20680 # execute the move. 20681 # 20681 # 20682 mov.w SRC_EX(%a0),%d0 20682 mov.w SRC_EX(%a0),%d0 # extract exponent 20683 andi.w &0x7fff,%d0 20683 andi.w &0x7fff,%d0 # strip sign 20684 20684 20685 cmpi.w %d0,&DBL_HI 20685 cmpi.w %d0,&DBL_HI # will operand overflow? 20686 bgt.w fout_dbl_ovfl 20686 bgt.w fout_dbl_ovfl # yes; go handle OVFL 20687 beq.w fout_dbl_may_ovfl 20687 beq.w fout_dbl_may_ovfl # maybe; go handle possible OVFL 20688 cmpi.w %d0,&DBL_LO 20688 cmpi.w %d0,&DBL_LO # will operand underflow? 20689 blt.w fout_dbl_unfl 20689 blt.w fout_dbl_unfl # yes; go handle underflow 20690 20690 20691 # 20691 # 20692 # NORMs(in range) can be stored out by a sim 20692 # NORMs(in range) can be stored out by a simple "fmov.d" 20693 # Unnormalized inputs can come through this 20693 # Unnormalized inputs can come through this point. 20694 # 20694 # 20695 fout_dbl_exg: 20695 fout_dbl_exg: 20696 fmovm.x SRC(%a0),&0x80 20696 fmovm.x SRC(%a0),&0x80 # fetch fop from stack 20697 20697 20698 fmov.l L_SCR3(%a6),%fpcr 20698 fmov.l L_SCR3(%a6),%fpcr # set FPCR 20699 fmov.l &0x0,%fpsr 20699 fmov.l &0x0,%fpsr # clear FPSR 20700 20700 20701 fmov.d %fp0,L_SCR1(%a6) 20701 fmov.d %fp0,L_SCR1(%a6) # store does convert and round 20702 20702 20703 fmov.l &0x0,%fpcr 20703 fmov.l &0x0,%fpcr # clear FPCR 20704 fmov.l %fpsr,%d0 20704 fmov.l %fpsr,%d0 # save FPSR 20705 20705 20706 or.w %d0,2+USER_FPSR(%a6) 20706 or.w %d0,2+USER_FPSR(%a6) # set possible inex2/ainex 20707 20707 20708 mov.l EXC_EA(%a6),%a1 20708 mov.l EXC_EA(%a6),%a1 # pass: dst addr 20709 lea L_SCR1(%a6),%a0 20709 lea L_SCR1(%a6),%a0 # pass: src addr 20710 movq.l &0x8,%d0 20710 movq.l &0x8,%d0 # pass: opsize is 8 bytes 20711 bsr.l _dmem_write 20711 bsr.l _dmem_write # store dbl fop to memory 20712 20712 20713 tst.l %d1 20713 tst.l %d1 # did dstore fail? 20714 bne.l facc_out_d 20714 bne.l facc_out_d # yes 20715 20715 20716 rts 20716 rts # no; so we're finished 20717 20717 20718 # 20718 # 20719 # here, we know that the operand would UNFL 20719 # here, we know that the operand would UNFL if moved out to double prec, 20720 # so, denorm and round and then use generic 20720 # so, denorm and round and then use generic store double routine to 20721 # write the value to memory. 20721 # write the value to memory. 20722 # 20722 # 20723 fout_dbl_unfl: 20723 fout_dbl_unfl: 20724 bset &unfl_bit,FPSR_EXCEP 20724 bset &unfl_bit,FPSR_EXCEPT(%a6) # set UNFL 20725 20725 20726 mov.w SRC_EX(%a0),FP_SCR0_ 20726 mov.w SRC_EX(%a0),FP_SCR0_EX(%a6) 20727 mov.l SRC_HI(%a0),FP_SCR0_ 20727 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) 20728 mov.l SRC_LO(%a0),FP_SCR0_ 20728 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) 20729 mov.l %a0,-(%sp) 20729 mov.l %a0,-(%sp) 20730 20730 20731 clr.l %d0 20731 clr.l %d0 # pass: S.F. = 0 20732 20732 20733 cmpi.b STAG(%a6),&DENORM 20733 cmpi.b STAG(%a6),&DENORM # fetch src optype tag 20734 bne.b fout_dbl_unfl_cont 20734 bne.b fout_dbl_unfl_cont # let DENORMs fall through 20735 20735 20736 lea FP_SCR0(%a6),%a0 20736 lea FP_SCR0(%a6),%a0 20737 bsr.l norm 20737 bsr.l norm # normalize the DENORM 20738 20738 20739 fout_dbl_unfl_cont: 20739 fout_dbl_unfl_cont: 20740 lea FP_SCR0(%a6),%a0 20740 lea FP_SCR0(%a6),%a0 # pass: ptr to operand 20741 mov.l L_SCR3(%a6),%d1 20741 mov.l L_SCR3(%a6),%d1 # pass: rnd prec,mode 20742 bsr.l unf_res 20742 bsr.l unf_res # calc default underflow result 20743 20743 20744 lea FP_SCR0(%a6),%a0 20744 lea FP_SCR0(%a6),%a0 # pass: ptr to fop 20745 bsr.l dst_dbl 20745 bsr.l dst_dbl # convert to single prec 20746 mov.l %d0,L_SCR1(%a6) 20746 mov.l %d0,L_SCR1(%a6) 20747 mov.l %d1,L_SCR2(%a6) 20747 mov.l %d1,L_SCR2(%a6) 20748 20748 20749 mov.l EXC_EA(%a6),%a1 20749 mov.l EXC_EA(%a6),%a1 # pass: dst addr 20750 lea L_SCR1(%a6),%a0 20750 lea L_SCR1(%a6),%a0 # pass: src addr 20751 movq.l &0x8,%d0 20751 movq.l &0x8,%d0 # pass: opsize is 8 bytes 20752 bsr.l _dmem_write 20752 bsr.l _dmem_write # store dbl fop to memory 20753 20753 20754 tst.l %d1 20754 tst.l %d1 # did dstore fail? 20755 bne.l facc_out_d 20755 bne.l facc_out_d # yes 20756 20756 20757 mov.b FPCR_ENABLE(%a6),%d1 20757 mov.b FPCR_ENABLE(%a6),%d1 20758 andi.b &0x0a,%d1 20758 andi.b &0x0a,%d1 # is UNFL or INEX enabled? 20759 bne.w fout_sd_exc_unfl 20759 bne.w fout_sd_exc_unfl # yes 20760 addq.l &0x4,%sp 20760 addq.l &0x4,%sp 20761 rts 20761 rts 20762 20762 20763 # 20763 # 20764 # it's definitely an overflow so call ovf_re 20764 # it's definitely an overflow so call ovf_res to get the correct answer 20765 # 20765 # 20766 fout_dbl_ovfl: 20766 fout_dbl_ovfl: 20767 mov.w 2+SRC_LO(%a0),%d0 20767 mov.w 2+SRC_LO(%a0),%d0 20768 andi.w &0x7ff,%d0 20768 andi.w &0x7ff,%d0 20769 bne.b fout_dbl_ovfl_inex2 20769 bne.b fout_dbl_ovfl_inex2 20770 20770 20771 ori.w &ovfl_inx_mask,2+USE 20771 ori.w &ovfl_inx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex 20772 bra.b fout_dbl_ovfl_cont 20772 bra.b fout_dbl_ovfl_cont 20773 fout_dbl_ovfl_inex2: 20773 fout_dbl_ovfl_inex2: 20774 ori.w &ovfinx_mask,2+USER_ 20774 ori.w &ovfinx_mask,2+USER_FPSR(%a6) # set ovfl/aovfl/ainex/inex2 20775 20775 20776 fout_dbl_ovfl_cont: 20776 fout_dbl_ovfl_cont: 20777 mov.l %a0,-(%sp) 20777 mov.l %a0,-(%sp) 20778 20778 20779 # call ovf_res() w/ dbl prec and the correct 20779 # call ovf_res() w/ dbl prec and the correct rnd mode to create the default 20780 # overflow result. DON'T save the returned c 20780 # overflow result. DON'T save the returned ccodes from ovf_res() since 20781 # fmove out doesn't alter them. 20781 # fmove out doesn't alter them. 20782 tst.b SRC_EX(%a0) 20782 tst.b SRC_EX(%a0) # is operand negative? 20783 smi %d1 20783 smi %d1 # set if so 20784 mov.l L_SCR3(%a6),%d0 20784 mov.l L_SCR3(%a6),%d0 # pass: dbl prec,rnd mode 20785 bsr.l ovf_res 20785 bsr.l ovf_res # calc OVFL result 20786 fmovm.x (%a0),&0x80 20786 fmovm.x (%a0),&0x80 # load default overflow result 20787 fmov.d %fp0,L_SCR1(%a6) 20787 fmov.d %fp0,L_SCR1(%a6) # store to double 20788 20788 20789 mov.l EXC_EA(%a6),%a1 20789 mov.l EXC_EA(%a6),%a1 # pass: dst addr 20790 lea L_SCR1(%a6),%a0 20790 lea L_SCR1(%a6),%a0 # pass: src addr 20791 movq.l &0x8,%d0 20791 movq.l &0x8,%d0 # pass: opsize is 8 bytes 20792 bsr.l _dmem_write 20792 bsr.l _dmem_write # store dbl fop to memory 20793 20793 20794 tst.l %d1 20794 tst.l %d1 # did dstore fail? 20795 bne.l facc_out_d 20795 bne.l facc_out_d # yes 20796 20796 20797 mov.b FPCR_ENABLE(%a6),%d1 20797 mov.b FPCR_ENABLE(%a6),%d1 20798 andi.b &0x0a,%d1 20798 andi.b &0x0a,%d1 # is UNFL or INEX enabled? 20799 bne.w fout_sd_exc_ovfl 20799 bne.w fout_sd_exc_ovfl # yes 20800 addq.l &0x4,%sp 20800 addq.l &0x4,%sp 20801 rts 20801 rts 20802 20802 20803 # 20803 # 20804 # move out MAY overflow: 20804 # move out MAY overflow: 20805 # (1) force the exp to 0x3fff 20805 # (1) force the exp to 0x3fff 20806 # (2) do a move w/ appropriate rnd mode 20806 # (2) do a move w/ appropriate rnd mode 20807 # (3) if exp still equals zero, then insert 20807 # (3) if exp still equals zero, then insert original exponent 20808 # for the correct result. 20808 # for the correct result. 20809 # if exp now equals one, then it overflo 20809 # if exp now equals one, then it overflowed so call ovf_res. 20810 # 20810 # 20811 fout_dbl_may_ovfl: 20811 fout_dbl_may_ovfl: 20812 mov.w SRC_EX(%a0),%d1 20812 mov.w SRC_EX(%a0),%d1 # fetch current sign 20813 andi.w &0x8000,%d1 20813 andi.w &0x8000,%d1 # keep it,clear exp 20814 ori.w &0x3fff,%d1 20814 ori.w &0x3fff,%d1 # insert exp = 0 20815 mov.w %d1,FP_SCR0_EX(%a6) 20815 mov.w %d1,FP_SCR0_EX(%a6) # insert scaled exp 20816 mov.l SRC_HI(%a0),FP_SCR0_ 20816 mov.l SRC_HI(%a0),FP_SCR0_HI(%a6) # copy hi(man) 20817 mov.l SRC_LO(%a0),FP_SCR0_ 20817 mov.l SRC_LO(%a0),FP_SCR0_LO(%a6) # copy lo(man) 20818 20818 20819 fmov.l L_SCR3(%a6),%fpcr 20819 fmov.l L_SCR3(%a6),%fpcr # set FPCR 20820 20820 20821 fmov.x FP_SCR0(%a6),%fp0 20821 fmov.x FP_SCR0(%a6),%fp0 # force fop to be rounded 20822 fmov.l &0x0,%fpcr 20822 fmov.l &0x0,%fpcr # clear FPCR 20823 20823 20824 fabs.x %fp0 20824 fabs.x %fp0 # need absolute value 20825 fcmp.b %fp0,&0x2 20825 fcmp.b %fp0,&0x2 # did exponent increase? 20826 fblt.w fout_dbl_exg 20826 fblt.w fout_dbl_exg # no; go finish NORM 20827 bra.w fout_dbl_ovfl 20827 bra.w fout_dbl_ovfl # yes; go handle overflow 20828 20828 20829 ############################################ 20829 ######################################################################### 20830 # XDEF ************************************* 20830 # XDEF **************************************************************** # 20831 # dst_dbl(): create double precision v 20831 # dst_dbl(): create double precision value from extended prec. # 20832 # 20832 # # 20833 # XREF ************************************* 20833 # XREF **************************************************************** # 20834 # None 20834 # None # 20835 # 20835 # # 20836 # INPUT ************************************ 20836 # INPUT *************************************************************** # 20837 # a0 = pointer to source operand in ex 20837 # a0 = pointer to source operand in extended precision # 20838 # 20838 # # 20839 # OUTPUT *********************************** 20839 # OUTPUT ************************************************************** # 20840 # d0 = hi(double precision result) 20840 # d0 = hi(double precision result) # 20841 # d1 = lo(double precision result) 20841 # d1 = lo(double precision result) # 20842 # 20842 # # 20843 # ALGORITHM ******************************** 20843 # ALGORITHM *********************************************************** # 20844 # 20844 # # 20845 # Changes extended precision to double prec 20845 # Changes extended precision to double precision. # 20846 # Note: no attempt is made to round the ext 20846 # Note: no attempt is made to round the extended value to double. # 20847 # dbl_sign = ext_sign 20847 # dbl_sign = ext_sign # 20848 # dbl_exp = ext_exp - $3fff(ext bias) 20848 # dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias) # 20849 # get rid of ext integer bit 20849 # get rid of ext integer bit # 20850 # dbl_mant = ext_mant{62:12} 20850 # dbl_mant = ext_mant{62:12} # 20851 # 20851 # # 20852 # --------------- ---------- 20852 # --------------- --------------- --------------- # 20853 # extended -> |s| exp | |1| ms man 20853 # extended -> |s| exp | |1| ms mant | | ls mant | # 20854 # --------------- ---------- 20854 # --------------- --------------- --------------- # 20855 # 95 64 63 62 20855 # 95 64 63 62 32 31 11 0 # 20856 # | 20856 # | | # 20857 # | 20857 # | | # 20858 # | 20858 # | | # 20859 # v 20859 # v v # 20860 # -------------- 20860 # --------------- --------------- # 20861 # double -> |s|exp| mant 20861 # double -> |s|exp| mant | | mant | # 20862 # -------------- 20862 # --------------- --------------- # 20863 # 63 51 32 20863 # 63 51 32 31 0 # 20864 # 20864 # # 20865 ############################################ 20865 ######################################################################### 20866 20866 20867 dst_dbl: 20867 dst_dbl: 20868 clr.l %d0 20868 clr.l %d0 # clear d0 20869 mov.w FTEMP_EX(%a0),%d0 20869 mov.w FTEMP_EX(%a0),%d0 # get exponent 20870 subi.w &EXT_BIAS,%d0 20870 subi.w &EXT_BIAS,%d0 # subtract extended precision bias 20871 addi.w &DBL_BIAS,%d0 20871 addi.w &DBL_BIAS,%d0 # add double precision bias 20872 tst.b FTEMP_HI(%a0) 20872 tst.b FTEMP_HI(%a0) # is number a denorm? 20873 bmi.b dst_get_dupper 20873 bmi.b dst_get_dupper # no 20874 subq.w &0x1,%d0 20874 subq.w &0x1,%d0 # yes; denorm bias = DBL_BIAS - 1 20875 dst_get_dupper: 20875 dst_get_dupper: 20876 swap %d0 20876 swap %d0 # d0 now in upper word 20877 lsl.l &0x4,%d0 20877 lsl.l &0x4,%d0 # d0 in proper place for dbl prec exp 20878 tst.b FTEMP_EX(%a0) 20878 tst.b FTEMP_EX(%a0) # test sign 20879 bpl.b dst_get_dman 20879 bpl.b dst_get_dman # if positive, go process mantissa 20880 bset &0x1f,%d0 20880 bset &0x1f,%d0 # if negative, set sign 20881 dst_get_dman: 20881 dst_get_dman: 20882 mov.l FTEMP_HI(%a0),%d1 20882 mov.l FTEMP_HI(%a0),%d1 # get ms mantissa 20883 bfextu %d1{&1:&20},%d1 20883 bfextu %d1{&1:&20},%d1 # get upper 20 bits of ms 20884 or.l %d1,%d0 20884 or.l %d1,%d0 # put these bits in ms word of double 20885 mov.l %d0,L_SCR1(%a6) 20885 mov.l %d0,L_SCR1(%a6) # put the new exp back on the stack 20886 mov.l FTEMP_HI(%a0),%d1 20886 mov.l FTEMP_HI(%a0),%d1 # get ms mantissa 20887 mov.l &21,%d0 20887 mov.l &21,%d0 # load shift count 20888 lsl.l %d0,%d1 20888 lsl.l %d0,%d1 # put lower 11 bits in upper bits 20889 mov.l %d1,L_SCR2(%a6) 20889 mov.l %d1,L_SCR2(%a6) # build lower lword in memory 20890 mov.l FTEMP_LO(%a0),%d1 20890 mov.l FTEMP_LO(%a0),%d1 # get ls mantissa 20891 bfextu %d1{&0:&21},%d0 20891 bfextu %d1{&0:&21},%d0 # get ls 21 bits of double 20892 mov.l L_SCR2(%a6),%d1 20892 mov.l L_SCR2(%a6),%d1 20893 or.l %d0,%d1 20893 or.l %d0,%d1 # put them in double result 20894 mov.l L_SCR1(%a6),%d0 20894 mov.l L_SCR1(%a6),%d0 20895 rts 20895 rts 20896 20896 20897 ############################################ 20897 ######################################################################### 20898 # XDEF ************************************* 20898 # XDEF **************************************************************** # 20899 # dst_sgl(): create single precision v 20899 # dst_sgl(): create single precision value from extended prec # 20900 # 20900 # # 20901 # XREF ************************************* 20901 # XREF **************************************************************** # 20902 # 20902 # # 20903 # INPUT ************************************ 20903 # INPUT *************************************************************** # 20904 # a0 = pointer to source operand in ex 20904 # a0 = pointer to source operand in extended precision # 20905 # 20905 # # 20906 # OUTPUT *********************************** 20906 # OUTPUT ************************************************************** # 20907 # d0 = single precision result 20907 # d0 = single precision result # 20908 # 20908 # # 20909 # ALGORITHM ******************************** 20909 # ALGORITHM *********************************************************** # 20910 # 20910 # # 20911 # Changes extended precision to single preci 20911 # Changes extended precision to single precision. # 20912 # sgl_sign = ext_sign 20912 # sgl_sign = ext_sign # 20913 # sgl_exp = ext_exp - $3fff(ext bias) 20913 # sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias) # 20914 # get rid of ext integer bit 20914 # get rid of ext integer bit # 20915 # sgl_mant = ext_mant{62:12} 20915 # sgl_mant = ext_mant{62:12} # 20916 # 20916 # # 20917 # --------------- ---------- 20917 # --------------- --------------- --------------- # 20918 # extended -> |s| exp | |1| ms man 20918 # extended -> |s| exp | |1| ms mant | | ls mant | # 20919 # --------------- ---------- 20919 # --------------- --------------- --------------- # 20920 # 95 64 63 62 4 20920 # 95 64 63 62 40 32 31 12 0 # 20921 # | | 20921 # | | # 20922 # | | 20922 # | | # 20923 # | | 20923 # | | # 20924 # v v 20924 # v v # 20925 # -------------- 20925 # --------------- # 20926 # single -> |s|exp| mant 20926 # single -> |s|exp| mant | # 20927 # -------------- 20927 # --------------- # 20928 # 31 22 20928 # 31 22 0 # 20929 # 20929 # # 20930 ############################################ 20930 ######################################################################### 20931 20931 20932 dst_sgl: 20932 dst_sgl: 20933 clr.l %d0 20933 clr.l %d0 20934 mov.w FTEMP_EX(%a0),%d0 20934 mov.w FTEMP_EX(%a0),%d0 # get exponent 20935 subi.w &EXT_BIAS,%d0 20935 subi.w &EXT_BIAS,%d0 # subtract extended precision bias 20936 addi.w &SGL_BIAS,%d0 20936 addi.w &SGL_BIAS,%d0 # add single precision bias 20937 tst.b FTEMP_HI(%a0) 20937 tst.b FTEMP_HI(%a0) # is number a denorm? 20938 bmi.b dst_get_supper 20938 bmi.b dst_get_supper # no 20939 subq.w &0x1,%d0 20939 subq.w &0x1,%d0 # yes; denorm bias = SGL_BIAS - 1 20940 dst_get_supper: 20940 dst_get_supper: 20941 swap %d0 20941 swap %d0 # put exp in upper word of d0 20942 lsl.l &0x7,%d0 20942 lsl.l &0x7,%d0 # shift it into single exp bits 20943 tst.b FTEMP_EX(%a0) 20943 tst.b FTEMP_EX(%a0) # test sign 20944 bpl.b dst_get_sman 20944 bpl.b dst_get_sman # if positive, continue 20945 bset &0x1f,%d0 20945 bset &0x1f,%d0 # if negative, put in sign first 20946 dst_get_sman: 20946 dst_get_sman: 20947 mov.l FTEMP_HI(%a0),%d1 20947 mov.l FTEMP_HI(%a0),%d1 # get ms mantissa 20948 andi.l &0x7fffff00,%d1 20948 andi.l &0x7fffff00,%d1 # get upper 23 bits of ms 20949 lsr.l &0x8,%d1 20949 lsr.l &0x8,%d1 # and put them flush right 20950 or.l %d1,%d0 20950 or.l %d1,%d0 # put these bits in ms word of single 20951 rts 20951 rts 20952 20952 20953 ############################################ 20953 ############################################################################## 20954 fout_pack: 20954 fout_pack: 20955 bsr.l _calc_ea_fout 20955 bsr.l _calc_ea_fout # fetch the <ea> 20956 mov.l %a0,-(%sp) 20956 mov.l %a0,-(%sp) 20957 20957 20958 mov.b STAG(%a6),%d0 20958 mov.b STAG(%a6),%d0 # fetch input type 20959 bne.w fout_pack_not_norm 20959 bne.w fout_pack_not_norm # input is not NORM 20960 20960 20961 fout_pack_norm: 20961 fout_pack_norm: 20962 btst &0x4,EXC_CMDREG(%a6) 20962 btst &0x4,EXC_CMDREG(%a6) # static or dynamic? 20963 beq.b fout_pack_s 20963 beq.b fout_pack_s # static 20964 20964 20965 fout_pack_d: 20965 fout_pack_d: 20966 mov.b 1+EXC_CMDREG(%a6),%d 20966 mov.b 1+EXC_CMDREG(%a6),%d1 # fetch dynamic reg 20967 lsr.b &0x4,%d1 20967 lsr.b &0x4,%d1 20968 andi.w &0x7,%d1 20968 andi.w &0x7,%d1 20969 20969 20970 bsr.l fetch_dreg 20970 bsr.l fetch_dreg # fetch Dn w/ k-factor 20971 20971 20972 bra.b fout_pack_type 20972 bra.b fout_pack_type 20973 fout_pack_s: 20973 fout_pack_s: 20974 mov.b 1+EXC_CMDREG(%a6),%d 20974 mov.b 1+EXC_CMDREG(%a6),%d0 # fetch static field 20975 20975 20976 fout_pack_type: 20976 fout_pack_type: 20977 bfexts %d0{&25:&7},%d0 20977 bfexts %d0{&25:&7},%d0 # extract k-factor 20978 mov.l %d0,-(%sp) 20978 mov.l %d0,-(%sp) 20979 20979 20980 lea FP_SRC(%a6),%a0 20980 lea FP_SRC(%a6),%a0 # pass: ptr to input 20981 20981 20982 # bindec is currently scrambling FP_SRC for 20982 # bindec is currently scrambling FP_SRC for denorm inputs. 20983 # we'll have to change this, but for now, to 20983 # we'll have to change this, but for now, tough luck!!! 20984 bsr.l bindec 20984 bsr.l bindec # convert xprec to packed 20985 20985 20986 # andi.l &0xcfff000f,FP_SCR0( 20986 # andi.l &0xcfff000f,FP_SCR0(%a6) # clear unused fields 20987 andi.l &0xcffff00f,FP_SCR0( 20987 andi.l &0xcffff00f,FP_SCR0(%a6) # clear unused fields 20988 20988 20989 mov.l (%sp)+,%d0 20989 mov.l (%sp)+,%d0 20990 20990 20991 tst.b 3+FP_SCR0_EX(%a6) 20991 tst.b 3+FP_SCR0_EX(%a6) 20992 bne.b fout_pack_set 20992 bne.b fout_pack_set 20993 tst.l FP_SCR0_HI(%a6) 20993 tst.l FP_SCR0_HI(%a6) 20994 bne.b fout_pack_set 20994 bne.b fout_pack_set 20995 tst.l FP_SCR0_LO(%a6) 20995 tst.l FP_SCR0_LO(%a6) 20996 bne.b fout_pack_set 20996 bne.b fout_pack_set 20997 20997 20998 # add the extra condition that only if the k 20998 # add the extra condition that only if the k-factor was zero, too, should 20999 # we zero the exponent 20999 # we zero the exponent 21000 tst.l %d0 21000 tst.l %d0 21001 bne.b fout_pack_set 21001 bne.b fout_pack_set 21002 # "mantissa" is all zero which means that th 21002 # "mantissa" is all zero which means that the answer is zero. but, the '040 21003 # algorithm allows the exponent to be non-ze 21003 # algorithm allows the exponent to be non-zero. the 881/2 do not. Therefore, 21004 # if the mantissa is zero, I will zero the e 21004 # if the mantissa is zero, I will zero the exponent, too. 21005 # the question now is whether the exponents 21005 # the question now is whether the exponents sign bit is allowed to be non-zero 21006 # for a zero, also... 21006 # for a zero, also... 21007 andi.w &0xf000,FP_SCR0(%a6) 21007 andi.w &0xf000,FP_SCR0(%a6) 21008 21008 21009 fout_pack_set: 21009 fout_pack_set: 21010 21010 21011 lea FP_SCR0(%a6),%a0 21011 lea FP_SCR0(%a6),%a0 # pass: src addr 21012 21012 21013 fout_pack_write: 21013 fout_pack_write: 21014 mov.l (%sp)+,%a1 21014 mov.l (%sp)+,%a1 # pass: dst addr 21015 mov.l &0xc,%d0 21015 mov.l &0xc,%d0 # pass: opsize is 12 bytes 21016 21016 21017 cmpi.b SPCOND_FLG(%a6),&mda 21017 cmpi.b SPCOND_FLG(%a6),&mda7_flg 21018 beq.b fout_pack_a7 21018 beq.b fout_pack_a7 21019 21019 21020 bsr.l _dmem_write 21020 bsr.l _dmem_write # write ext prec number to memory 21021 21021 21022 tst.l %d1 21022 tst.l %d1 # did dstore fail? 21023 bne.w fout_ext_err 21023 bne.w fout_ext_err # yes 21024 21024 21025 rts 21025 rts 21026 21026 21027 # we don't want to do the write if the excep 21027 # we don't want to do the write if the exception occurred in supervisor mode 21028 # so _mem_write2() handles this for us. 21028 # so _mem_write2() handles this for us. 21029 fout_pack_a7: 21029 fout_pack_a7: 21030 bsr.l _mem_write2 21030 bsr.l _mem_write2 # write ext prec number to memory 21031 21031 21032 tst.l %d1 21032 tst.l %d1 # did dstore fail? 21033 bne.w fout_ext_err 21033 bne.w fout_ext_err # yes 21034 21034 21035 rts 21035 rts 21036 21036 21037 fout_pack_not_norm: 21037 fout_pack_not_norm: 21038 cmpi.b %d0,&DENORM 21038 cmpi.b %d0,&DENORM # is it a DENORM? 21039 beq.w fout_pack_norm 21039 beq.w fout_pack_norm # yes 21040 lea FP_SRC(%a6),%a0 21040 lea FP_SRC(%a6),%a0 21041 clr.w 2+FP_SRC_EX(%a6) 21041 clr.w 2+FP_SRC_EX(%a6) 21042 cmpi.b %d0,&SNAN 21042 cmpi.b %d0,&SNAN # is it an SNAN? 21043 beq.b fout_pack_snan 21043 beq.b fout_pack_snan # yes 21044 bra.b fout_pack_write 21044 bra.b fout_pack_write # no 21045 21045 21046 fout_pack_snan: 21046 fout_pack_snan: 21047 ori.w &snaniop2_mask,FPSR_ 21047 ori.w &snaniop2_mask,FPSR_EXCEPT(%a6) # set SNAN/AIOP 21048 bset &0x6,FP_SRC_HI(%a6) 21048 bset &0x6,FP_SRC_HI(%a6) # set snan bit 21049 bra.b fout_pack_write 21049 bra.b fout_pack_write 21050 21050 21051 ############################################ 21051 ######################################################################### 21052 # XDEF ************************************* 21052 # XDEF **************************************************************** # 21053 # fetch_dreg(): fetch register accordi 21053 # fetch_dreg(): fetch register according to index in d1 # 21054 # 21054 # # 21055 # XREF ************************************* 21055 # XREF **************************************************************** # 21056 # None 21056 # None # 21057 # 21057 # # 21058 # INPUT ************************************ 21058 # INPUT *************************************************************** # 21059 # d1 = index of register to fetch from 21059 # d1 = index of register to fetch from # 21060 # 21060 # # 21061 # OUTPUT *********************************** 21061 # OUTPUT ************************************************************** # 21062 # d0 = value of register fetched 21062 # d0 = value of register fetched # 21063 # 21063 # # 21064 # ALGORITHM ******************************** 21064 # ALGORITHM *********************************************************** # 21065 # According to the index value in d1 w 21065 # According to the index value in d1 which can range from zero # 21066 # to fifteen, load the corresponding registe 21066 # to fifteen, load the corresponding register file value (where # 21067 # address register indexes start at 8). D0/D 21067 # address register indexes start at 8). D0/D1/A0/A1/A6/A7 are on the # 21068 # stack. The rest should still be in their o 21068 # stack. The rest should still be in their original places. # 21069 # 21069 # # 21070 ############################################ 21070 ######################################################################### 21071 21071 21072 # this routine leaves d1 intact for subseque 21072 # this routine leaves d1 intact for subsequent store_dreg calls. 21073 global fetch_dreg 21073 global fetch_dreg 21074 fetch_dreg: 21074 fetch_dreg: 21075 mov.w (tbl_fdreg.b,%pc,%d1 21075 mov.w (tbl_fdreg.b,%pc,%d1.w*2),%d0 21076 jmp (tbl_fdreg.b,%pc,%d0 21076 jmp (tbl_fdreg.b,%pc,%d0.w*1) 21077 21077 21078 tbl_fdreg: 21078 tbl_fdreg: 21079 short fdreg0 - tbl_fdreg 21079 short fdreg0 - tbl_fdreg 21080 short fdreg1 - tbl_fdreg 21080 short fdreg1 - tbl_fdreg 21081 short fdreg2 - tbl_fdreg 21081 short fdreg2 - tbl_fdreg 21082 short fdreg3 - tbl_fdreg 21082 short fdreg3 - tbl_fdreg 21083 short fdreg4 - tbl_fdreg 21083 short fdreg4 - tbl_fdreg 21084 short fdreg5 - tbl_fdreg 21084 short fdreg5 - tbl_fdreg 21085 short fdreg6 - tbl_fdreg 21085 short fdreg6 - tbl_fdreg 21086 short fdreg7 - tbl_fdreg 21086 short fdreg7 - tbl_fdreg 21087 short fdreg8 - tbl_fdreg 21087 short fdreg8 - tbl_fdreg 21088 short fdreg9 - tbl_fdreg 21088 short fdreg9 - tbl_fdreg 21089 short fdrega - tbl_fdreg 21089 short fdrega - tbl_fdreg 21090 short fdregb - tbl_fdreg 21090 short fdregb - tbl_fdreg 21091 short fdregc - tbl_fdreg 21091 short fdregc - tbl_fdreg 21092 short fdregd - tbl_fdreg 21092 short fdregd - tbl_fdreg 21093 short fdrege - tbl_fdreg 21093 short fdrege - tbl_fdreg 21094 short fdregf - tbl_fdreg 21094 short fdregf - tbl_fdreg 21095 21095 21096 fdreg0: 21096 fdreg0: 21097 mov.l EXC_DREGS+0x0(%a6),% 21097 mov.l EXC_DREGS+0x0(%a6),%d0 21098 rts 21098 rts 21099 fdreg1: 21099 fdreg1: 21100 mov.l EXC_DREGS+0x4(%a6),% 21100 mov.l EXC_DREGS+0x4(%a6),%d0 21101 rts 21101 rts 21102 fdreg2: 21102 fdreg2: 21103 mov.l %d2,%d0 21103 mov.l %d2,%d0 21104 rts 21104 rts 21105 fdreg3: 21105 fdreg3: 21106 mov.l %d3,%d0 21106 mov.l %d3,%d0 21107 rts 21107 rts 21108 fdreg4: 21108 fdreg4: 21109 mov.l %d4,%d0 21109 mov.l %d4,%d0 21110 rts 21110 rts 21111 fdreg5: 21111 fdreg5: 21112 mov.l %d5,%d0 21112 mov.l %d5,%d0 21113 rts 21113 rts 21114 fdreg6: 21114 fdreg6: 21115 mov.l %d6,%d0 21115 mov.l %d6,%d0 21116 rts 21116 rts 21117 fdreg7: 21117 fdreg7: 21118 mov.l %d7,%d0 21118 mov.l %d7,%d0 21119 rts 21119 rts 21120 fdreg8: 21120 fdreg8: 21121 mov.l EXC_DREGS+0x8(%a6),% 21121 mov.l EXC_DREGS+0x8(%a6),%d0 21122 rts 21122 rts 21123 fdreg9: 21123 fdreg9: 21124 mov.l EXC_DREGS+0xc(%a6),% 21124 mov.l EXC_DREGS+0xc(%a6),%d0 21125 rts 21125 rts 21126 fdrega: 21126 fdrega: 21127 mov.l %a2,%d0 21127 mov.l %a2,%d0 21128 rts 21128 rts 21129 fdregb: 21129 fdregb: 21130 mov.l %a3,%d0 21130 mov.l %a3,%d0 21131 rts 21131 rts 21132 fdregc: 21132 fdregc: 21133 mov.l %a4,%d0 21133 mov.l %a4,%d0 21134 rts 21134 rts 21135 fdregd: 21135 fdregd: 21136 mov.l %a5,%d0 21136 mov.l %a5,%d0 21137 rts 21137 rts 21138 fdrege: 21138 fdrege: 21139 mov.l (%a6),%d0 21139 mov.l (%a6),%d0 21140 rts 21140 rts 21141 fdregf: 21141 fdregf: 21142 mov.l EXC_A7(%a6),%d0 21142 mov.l EXC_A7(%a6),%d0 21143 rts 21143 rts 21144 21144 21145 ############################################ 21145 ######################################################################### 21146 # XDEF ************************************* 21146 # XDEF **************************************************************** # 21147 # store_dreg_l(): store longword to da 21147 # store_dreg_l(): store longword to data register specified by d1 # 21148 # 21148 # # 21149 # XREF ************************************* 21149 # XREF **************************************************************** # 21150 # None 21150 # None # 21151 # 21151 # # 21152 # INPUT ************************************ 21152 # INPUT *************************************************************** # 21153 # d0 = longowrd value to store 21153 # d0 = longowrd value to store # 21154 # d1 = index of register to fetch from 21154 # d1 = index of register to fetch from # 21155 # 21155 # # 21156 # OUTPUT *********************************** 21156 # OUTPUT ************************************************************** # 21157 # (data register is updated) 21157 # (data register is updated) # 21158 # 21158 # # 21159 # ALGORITHM ******************************** 21159 # ALGORITHM *********************************************************** # 21160 # According to the index value in d1, 21160 # According to the index value in d1, store the longword value # 21161 # in d0 to the corresponding data register. 21161 # in d0 to the corresponding data register. D0/D1 are on the stack # 21162 # while the rest are in their initial places 21162 # while the rest are in their initial places. # 21163 # 21163 # # 21164 ############################################ 21164 ######################################################################### 21165 21165 21166 global store_dreg_l 21166 global store_dreg_l 21167 store_dreg_l: 21167 store_dreg_l: 21168 mov.w (tbl_sdregl.b,%pc,%d 21168 mov.w (tbl_sdregl.b,%pc,%d1.w*2),%d1 21169 jmp (tbl_sdregl.b,%pc,%d 21169 jmp (tbl_sdregl.b,%pc,%d1.w*1) 21170 21170 21171 tbl_sdregl: 21171 tbl_sdregl: 21172 short sdregl0 - tbl_sdregl 21172 short sdregl0 - tbl_sdregl 21173 short sdregl1 - tbl_sdregl 21173 short sdregl1 - tbl_sdregl 21174 short sdregl2 - tbl_sdregl 21174 short sdregl2 - tbl_sdregl 21175 short sdregl3 - tbl_sdregl 21175 short sdregl3 - tbl_sdregl 21176 short sdregl4 - tbl_sdregl 21176 short sdregl4 - tbl_sdregl 21177 short sdregl5 - tbl_sdregl 21177 short sdregl5 - tbl_sdregl 21178 short sdregl6 - tbl_sdregl 21178 short sdregl6 - tbl_sdregl 21179 short sdregl7 - tbl_sdregl 21179 short sdregl7 - tbl_sdregl 21180 21180 21181 sdregl0: 21181 sdregl0: 21182 mov.l %d0,EXC_DREGS+0x0(%a 21182 mov.l %d0,EXC_DREGS+0x0(%a6) 21183 rts 21183 rts 21184 sdregl1: 21184 sdregl1: 21185 mov.l %d0,EXC_DREGS+0x4(%a 21185 mov.l %d0,EXC_DREGS+0x4(%a6) 21186 rts 21186 rts 21187 sdregl2: 21187 sdregl2: 21188 mov.l %d0,%d2 21188 mov.l %d0,%d2 21189 rts 21189 rts 21190 sdregl3: 21190 sdregl3: 21191 mov.l %d0,%d3 21191 mov.l %d0,%d3 21192 rts 21192 rts 21193 sdregl4: 21193 sdregl4: 21194 mov.l %d0,%d4 21194 mov.l %d0,%d4 21195 rts 21195 rts 21196 sdregl5: 21196 sdregl5: 21197 mov.l %d0,%d5 21197 mov.l %d0,%d5 21198 rts 21198 rts 21199 sdregl6: 21199 sdregl6: 21200 mov.l %d0,%d6 21200 mov.l %d0,%d6 21201 rts 21201 rts 21202 sdregl7: 21202 sdregl7: 21203 mov.l %d0,%d7 21203 mov.l %d0,%d7 21204 rts 21204 rts 21205 21205 21206 ############################################ 21206 ######################################################################### 21207 # XDEF ************************************* 21207 # XDEF **************************************************************** # 21208 # store_dreg_w(): store word to data r 21208 # store_dreg_w(): store word to data register specified by d1 # 21209 # 21209 # # 21210 # XREF ************************************* 21210 # XREF **************************************************************** # 21211 # None 21211 # None # 21212 # 21212 # # 21213 # INPUT ************************************ 21213 # INPUT *************************************************************** # 21214 # d0 = word value to store 21214 # d0 = word value to store # 21215 # d1 = index of register to fetch from 21215 # d1 = index of register to fetch from # 21216 # 21216 # # 21217 # OUTPUT *********************************** 21217 # OUTPUT ************************************************************** # 21218 # (data register is updated) 21218 # (data register is updated) # 21219 # 21219 # # 21220 # ALGORITHM ******************************** 21220 # ALGORITHM *********************************************************** # 21221 # According to the index value in d1, 21221 # According to the index value in d1, store the word value # 21222 # in d0 to the corresponding data register. 21222 # in d0 to the corresponding data register. D0/D1 are on the stack # 21223 # while the rest are in their initial places 21223 # while the rest are in their initial places. # 21224 # 21224 # # 21225 ############################################ 21225 ######################################################################### 21226 21226 21227 global store_dreg_w 21227 global store_dreg_w 21228 store_dreg_w: 21228 store_dreg_w: 21229 mov.w (tbl_sdregw.b,%pc,%d 21229 mov.w (tbl_sdregw.b,%pc,%d1.w*2),%d1 21230 jmp (tbl_sdregw.b,%pc,%d 21230 jmp (tbl_sdregw.b,%pc,%d1.w*1) 21231 21231 21232 tbl_sdregw: 21232 tbl_sdregw: 21233 short sdregw0 - tbl_sdregw 21233 short sdregw0 - tbl_sdregw 21234 short sdregw1 - tbl_sdregw 21234 short sdregw1 - tbl_sdregw 21235 short sdregw2 - tbl_sdregw 21235 short sdregw2 - tbl_sdregw 21236 short sdregw3 - tbl_sdregw 21236 short sdregw3 - tbl_sdregw 21237 short sdregw4 - tbl_sdregw 21237 short sdregw4 - tbl_sdregw 21238 short sdregw5 - tbl_sdregw 21238 short sdregw5 - tbl_sdregw 21239 short sdregw6 - tbl_sdregw 21239 short sdregw6 - tbl_sdregw 21240 short sdregw7 - tbl_sdregw 21240 short sdregw7 - tbl_sdregw 21241 21241 21242 sdregw0: 21242 sdregw0: 21243 mov.w %d0,2+EXC_DREGS+0x0( 21243 mov.w %d0,2+EXC_DREGS+0x0(%a6) 21244 rts 21244 rts 21245 sdregw1: 21245 sdregw1: 21246 mov.w %d0,2+EXC_DREGS+0x4( 21246 mov.w %d0,2+EXC_DREGS+0x4(%a6) 21247 rts 21247 rts 21248 sdregw2: 21248 sdregw2: 21249 mov.w %d0,%d2 21249 mov.w %d0,%d2 21250 rts 21250 rts 21251 sdregw3: 21251 sdregw3: 21252 mov.w %d0,%d3 21252 mov.w %d0,%d3 21253 rts 21253 rts 21254 sdregw4: 21254 sdregw4: 21255 mov.w %d0,%d4 21255 mov.w %d0,%d4 21256 rts 21256 rts 21257 sdregw5: 21257 sdregw5: 21258 mov.w %d0,%d5 21258 mov.w %d0,%d5 21259 rts 21259 rts 21260 sdregw6: 21260 sdregw6: 21261 mov.w %d0,%d6 21261 mov.w %d0,%d6 21262 rts 21262 rts 21263 sdregw7: 21263 sdregw7: 21264 mov.w %d0,%d7 21264 mov.w %d0,%d7 21265 rts 21265 rts 21266 21266 21267 ############################################ 21267 ######################################################################### 21268 # XDEF ************************************* 21268 # XDEF **************************************************************** # 21269 # store_dreg_b(): store byte to data r 21269 # store_dreg_b(): store byte to data register specified by d1 # 21270 # 21270 # # 21271 # XREF ************************************* 21271 # XREF **************************************************************** # 21272 # None 21272 # None # 21273 # 21273 # # 21274 # INPUT ************************************ 21274 # INPUT *************************************************************** # 21275 # d0 = byte value to store 21275 # d0 = byte value to store # 21276 # d1 = index of register to fetch from 21276 # d1 = index of register to fetch from # 21277 # 21277 # # 21278 # OUTPUT *********************************** 21278 # OUTPUT ************************************************************** # 21279 # (data register is updated) 21279 # (data register is updated) # 21280 # 21280 # # 21281 # ALGORITHM ******************************** 21281 # ALGORITHM *********************************************************** # 21282 # According to the index value in d1, 21282 # According to the index value in d1, store the byte value # 21283 # in d0 to the corresponding data register. 21283 # in d0 to the corresponding data register. D0/D1 are on the stack # 21284 # while the rest are in their initial places 21284 # while the rest are in their initial places. # 21285 # 21285 # # 21286 ############################################ 21286 ######################################################################### 21287 21287 21288 global store_dreg_b 21288 global store_dreg_b 21289 store_dreg_b: 21289 store_dreg_b: 21290 mov.w (tbl_sdregb.b,%pc,%d 21290 mov.w (tbl_sdregb.b,%pc,%d1.w*2),%d1 21291 jmp (tbl_sdregb.b,%pc,%d 21291 jmp (tbl_sdregb.b,%pc,%d1.w*1) 21292 21292 21293 tbl_sdregb: 21293 tbl_sdregb: 21294 short sdregb0 - tbl_sdregb 21294 short sdregb0 - tbl_sdregb 21295 short sdregb1 - tbl_sdregb 21295 short sdregb1 - tbl_sdregb 21296 short sdregb2 - tbl_sdregb 21296 short sdregb2 - tbl_sdregb 21297 short sdregb3 - tbl_sdregb 21297 short sdregb3 - tbl_sdregb 21298 short sdregb4 - tbl_sdregb 21298 short sdregb4 - tbl_sdregb 21299 short sdregb5 - tbl_sdregb 21299 short sdregb5 - tbl_sdregb 21300 short sdregb6 - tbl_sdregb 21300 short sdregb6 - tbl_sdregb 21301 short sdregb7 - tbl_sdregb 21301 short sdregb7 - tbl_sdregb 21302 21302 21303 sdregb0: 21303 sdregb0: 21304 mov.b %d0,3+EXC_DREGS+0x0( 21304 mov.b %d0,3+EXC_DREGS+0x0(%a6) 21305 rts 21305 rts 21306 sdregb1: 21306 sdregb1: 21307 mov.b %d0,3+EXC_DREGS+0x4( 21307 mov.b %d0,3+EXC_DREGS+0x4(%a6) 21308 rts 21308 rts 21309 sdregb2: 21309 sdregb2: 21310 mov.b %d0,%d2 21310 mov.b %d0,%d2 21311 rts 21311 rts 21312 sdregb3: 21312 sdregb3: 21313 mov.b %d0,%d3 21313 mov.b %d0,%d3 21314 rts 21314 rts 21315 sdregb4: 21315 sdregb4: 21316 mov.b %d0,%d4 21316 mov.b %d0,%d4 21317 rts 21317 rts 21318 sdregb5: 21318 sdregb5: 21319 mov.b %d0,%d5 21319 mov.b %d0,%d5 21320 rts 21320 rts 21321 sdregb6: 21321 sdregb6: 21322 mov.b %d0,%d6 21322 mov.b %d0,%d6 21323 rts 21323 rts 21324 sdregb7: 21324 sdregb7: 21325 mov.b %d0,%d7 21325 mov.b %d0,%d7 21326 rts 21326 rts 21327 21327 21328 ############################################ 21328 ######################################################################### 21329 # XDEF ************************************* 21329 # XDEF **************************************************************** # 21330 # inc_areg(): increment an address reg 21330 # inc_areg(): increment an address register by the value in d0 # 21331 # 21331 # # 21332 # XREF ************************************* 21332 # XREF **************************************************************** # 21333 # None 21333 # None # 21334 # 21334 # # 21335 # INPUT ************************************ 21335 # INPUT *************************************************************** # 21336 # d0 = amount to increment by 21336 # d0 = amount to increment by # 21337 # d1 = index of address register to in 21337 # d1 = index of address register to increment # 21338 # 21338 # # 21339 # OUTPUT *********************************** 21339 # OUTPUT ************************************************************** # 21340 # (address register is updated) 21340 # (address register is updated) # 21341 # 21341 # # 21342 # ALGORITHM ******************************** 21342 # ALGORITHM *********************************************************** # 21343 # Typically used for an instruction w/ 21343 # Typically used for an instruction w/ a post-increment <ea>, # 21344 # this routine adds the increment value in d 21344 # this routine adds the increment value in d0 to the address register # 21345 # specified by d1. A0/A1/A6/A7 reside on the 21345 # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside # 21346 # in their original places. 21346 # in their original places. # 21347 # For a7, if the increment amount is o 21347 # For a7, if the increment amount is one, then we have to # 21348 # increment by two. For any a7 update, set t 21348 # increment by two. For any a7 update, set the mia7_flag so that if # 21349 # an access error exception occurs later in 21349 # an access error exception occurs later in emulation, this address # 21350 # register update can be undone. 21350 # register update can be undone. # 21351 # 21351 # # 21352 ############################################ 21352 ######################################################################### 21353 21353 21354 global inc_areg 21354 global inc_areg 21355 inc_areg: 21355 inc_areg: 21356 mov.w (tbl_iareg.b,%pc,%d1 21356 mov.w (tbl_iareg.b,%pc,%d1.w*2),%d1 21357 jmp (tbl_iareg.b,%pc,%d1 21357 jmp (tbl_iareg.b,%pc,%d1.w*1) 21358 21358 21359 tbl_iareg: 21359 tbl_iareg: 21360 short iareg0 - tbl_iareg 21360 short iareg0 - tbl_iareg 21361 short iareg1 - tbl_iareg 21361 short iareg1 - tbl_iareg 21362 short iareg2 - tbl_iareg 21362 short iareg2 - tbl_iareg 21363 short iareg3 - tbl_iareg 21363 short iareg3 - tbl_iareg 21364 short iareg4 - tbl_iareg 21364 short iareg4 - tbl_iareg 21365 short iareg5 - tbl_iareg 21365 short iareg5 - tbl_iareg 21366 short iareg6 - tbl_iareg 21366 short iareg6 - tbl_iareg 21367 short iareg7 - tbl_iareg 21367 short iareg7 - tbl_iareg 21368 21368 21369 iareg0: add.l %d0,EXC_DREGS+0x8(%a 21369 iareg0: add.l %d0,EXC_DREGS+0x8(%a6) 21370 rts 21370 rts 21371 iareg1: add.l %d0,EXC_DREGS+0xc(%a 21371 iareg1: add.l %d0,EXC_DREGS+0xc(%a6) 21372 rts 21372 rts 21373 iareg2: add.l %d0,%a2 21373 iareg2: add.l %d0,%a2 21374 rts 21374 rts 21375 iareg3: add.l %d0,%a3 21375 iareg3: add.l %d0,%a3 21376 rts 21376 rts 21377 iareg4: add.l %d0,%a4 21377 iareg4: add.l %d0,%a4 21378 rts 21378 rts 21379 iareg5: add.l %d0,%a5 21379 iareg5: add.l %d0,%a5 21380 rts 21380 rts 21381 iareg6: add.l %d0,(%a6) 21381 iareg6: add.l %d0,(%a6) 21382 rts 21382 rts 21383 iareg7: mov.b &mia7_flg,SPCOND_FLG 21383 iareg7: mov.b &mia7_flg,SPCOND_FLG(%a6) 21384 cmpi.b %d0,&0x1 21384 cmpi.b %d0,&0x1 21385 beq.b iareg7b 21385 beq.b iareg7b 21386 add.l %d0,EXC_A7(%a6) 21386 add.l %d0,EXC_A7(%a6) 21387 rts 21387 rts 21388 iareg7b: 21388 iareg7b: 21389 addq.l &0x2,EXC_A7(%a6) 21389 addq.l &0x2,EXC_A7(%a6) 21390 rts 21390 rts 21391 21391 21392 ############################################ 21392 ######################################################################### 21393 # XDEF ************************************* 21393 # XDEF **************************************************************** # 21394 # dec_areg(): decrement an address reg 21394 # dec_areg(): decrement an address register by the value in d0 # 21395 # 21395 # # 21396 # XREF ************************************* 21396 # XREF **************************************************************** # 21397 # None 21397 # None # 21398 # 21398 # # 21399 # INPUT ************************************ 21399 # INPUT *************************************************************** # 21400 # d0 = amount to decrement by 21400 # d0 = amount to decrement by # 21401 # d1 = index of address register to de 21401 # d1 = index of address register to decrement # 21402 # 21402 # # 21403 # OUTPUT *********************************** 21403 # OUTPUT ************************************************************** # 21404 # (address register is updated) 21404 # (address register is updated) # 21405 # 21405 # # 21406 # ALGORITHM ******************************** 21406 # ALGORITHM *********************************************************** # 21407 # Typically used for an instruction w/ 21407 # Typically used for an instruction w/ a pre-decrement <ea>, # 21408 # this routine adds the decrement value in d 21408 # this routine adds the decrement value in d0 to the address register # 21409 # specified by d1. A0/A1/A6/A7 reside on the 21409 # specified by d1. A0/A1/A6/A7 reside on the stack. The rest reside # 21410 # in their original places. 21410 # in their original places. # 21411 # For a7, if the decrement amount is o 21411 # For a7, if the decrement amount is one, then we have to # 21412 # decrement by two. For any a7 update, set t 21412 # decrement by two. For any a7 update, set the mda7_flag so that if # 21413 # an access error exception occurs later in 21413 # an access error exception occurs later in emulation, this address # 21414 # register update can be undone. 21414 # register update can be undone. # 21415 # 21415 # # 21416 ############################################ 21416 ######################################################################### 21417 21417 21418 global dec_areg 21418 global dec_areg 21419 dec_areg: 21419 dec_areg: 21420 mov.w (tbl_dareg.b,%pc,%d1 21420 mov.w (tbl_dareg.b,%pc,%d1.w*2),%d1 21421 jmp (tbl_dareg.b,%pc,%d1 21421 jmp (tbl_dareg.b,%pc,%d1.w*1) 21422 21422 21423 tbl_dareg: 21423 tbl_dareg: 21424 short dareg0 - tbl_dareg 21424 short dareg0 - tbl_dareg 21425 short dareg1 - tbl_dareg 21425 short dareg1 - tbl_dareg 21426 short dareg2 - tbl_dareg 21426 short dareg2 - tbl_dareg 21427 short dareg3 - tbl_dareg 21427 short dareg3 - tbl_dareg 21428 short dareg4 - tbl_dareg 21428 short dareg4 - tbl_dareg 21429 short dareg5 - tbl_dareg 21429 short dareg5 - tbl_dareg 21430 short dareg6 - tbl_dareg 21430 short dareg6 - tbl_dareg 21431 short dareg7 - tbl_dareg 21431 short dareg7 - tbl_dareg 21432 21432 21433 dareg0: sub.l %d0,EXC_DREGS+0x8(%a 21433 dareg0: sub.l %d0,EXC_DREGS+0x8(%a6) 21434 rts 21434 rts 21435 dareg1: sub.l %d0,EXC_DREGS+0xc(%a 21435 dareg1: sub.l %d0,EXC_DREGS+0xc(%a6) 21436 rts 21436 rts 21437 dareg2: sub.l %d0,%a2 21437 dareg2: sub.l %d0,%a2 21438 rts 21438 rts 21439 dareg3: sub.l %d0,%a3 21439 dareg3: sub.l %d0,%a3 21440 rts 21440 rts 21441 dareg4: sub.l %d0,%a4 21441 dareg4: sub.l %d0,%a4 21442 rts 21442 rts 21443 dareg5: sub.l %d0,%a5 21443 dareg5: sub.l %d0,%a5 21444 rts 21444 rts 21445 dareg6: sub.l %d0,(%a6) 21445 dareg6: sub.l %d0,(%a6) 21446 rts 21446 rts 21447 dareg7: mov.b &mda7_flg,SPCOND_FLG 21447 dareg7: mov.b &mda7_flg,SPCOND_FLG(%a6) 21448 cmpi.b %d0,&0x1 21448 cmpi.b %d0,&0x1 21449 beq.b dareg7b 21449 beq.b dareg7b 21450 sub.l %d0,EXC_A7(%a6) 21450 sub.l %d0,EXC_A7(%a6) 21451 rts 21451 rts 21452 dareg7b: 21452 dareg7b: 21453 subq.l &0x2,EXC_A7(%a6) 21453 subq.l &0x2,EXC_A7(%a6) 21454 rts 21454 rts 21455 21455 21456 ############################################ 21456 ############################################################################## 21457 21457 21458 ############################################ 21458 ######################################################################### 21459 # XDEF ************************************* 21459 # XDEF **************************************************************** # 21460 # load_fpn1(): load FP register value 21460 # load_fpn1(): load FP register value into FP_SRC(a6). # 21461 # 21461 # # 21462 # XREF ************************************* 21462 # XREF **************************************************************** # 21463 # None 21463 # None # 21464 # 21464 # # 21465 # INPUT ************************************ 21465 # INPUT *************************************************************** # 21466 # d0 = index of FP register to load 21466 # d0 = index of FP register to load # 21467 # 21467 # # 21468 # OUTPUT *********************************** 21468 # OUTPUT ************************************************************** # 21469 # FP_SRC(a6) = value loaded from FP re 21469 # FP_SRC(a6) = value loaded from FP register file # 21470 # 21470 # # 21471 # ALGORITHM ******************************** 21471 # ALGORITHM *********************************************************** # 21472 # Using the index in d0, load FP_SRC(a 21472 # Using the index in d0, load FP_SRC(a6) with a number from the # 21473 # FP register file. 21473 # FP register file. # 21474 # 21474 # # 21475 ############################################ 21475 ######################################################################### 21476 21476 21477 global load_fpn1 21477 global load_fpn1 21478 load_fpn1: 21478 load_fpn1: 21479 mov.w (tbl_load_fpn1.b,%pc 21479 mov.w (tbl_load_fpn1.b,%pc,%d0.w*2), %d0 21480 jmp (tbl_load_fpn1.b,%pc 21480 jmp (tbl_load_fpn1.b,%pc,%d0.w*1) 21481 21481 21482 tbl_load_fpn1: 21482 tbl_load_fpn1: 21483 short load_fpn1_0 - tbl_lo 21483 short load_fpn1_0 - tbl_load_fpn1 21484 short load_fpn1_1 - tbl_lo 21484 short load_fpn1_1 - tbl_load_fpn1 21485 short load_fpn1_2 - tbl_lo 21485 short load_fpn1_2 - tbl_load_fpn1 21486 short load_fpn1_3 - tbl_lo 21486 short load_fpn1_3 - tbl_load_fpn1 21487 short load_fpn1_4 - tbl_lo 21487 short load_fpn1_4 - tbl_load_fpn1 21488 short load_fpn1_5 - tbl_lo 21488 short load_fpn1_5 - tbl_load_fpn1 21489 short load_fpn1_6 - tbl_lo 21489 short load_fpn1_6 - tbl_load_fpn1 21490 short load_fpn1_7 - tbl_lo 21490 short load_fpn1_7 - tbl_load_fpn1 21491 21491 21492 load_fpn1_0: 21492 load_fpn1_0: 21493 mov.l 0+EXC_FP0(%a6), 0+FP 21493 mov.l 0+EXC_FP0(%a6), 0+FP_SRC(%a6) 21494 mov.l 4+EXC_FP0(%a6), 4+FP 21494 mov.l 4+EXC_FP0(%a6), 4+FP_SRC(%a6) 21495 mov.l 8+EXC_FP0(%a6), 8+FP 21495 mov.l 8+EXC_FP0(%a6), 8+FP_SRC(%a6) 21496 lea FP_SRC(%a6), %a0 21496 lea FP_SRC(%a6), %a0 21497 rts 21497 rts 21498 load_fpn1_1: 21498 load_fpn1_1: 21499 mov.l 0+EXC_FP1(%a6), 0+FP 21499 mov.l 0+EXC_FP1(%a6), 0+FP_SRC(%a6) 21500 mov.l 4+EXC_FP1(%a6), 4+FP 21500 mov.l 4+EXC_FP1(%a6), 4+FP_SRC(%a6) 21501 mov.l 8+EXC_FP1(%a6), 8+FP 21501 mov.l 8+EXC_FP1(%a6), 8+FP_SRC(%a6) 21502 lea FP_SRC(%a6), %a0 21502 lea FP_SRC(%a6), %a0 21503 rts 21503 rts 21504 load_fpn1_2: 21504 load_fpn1_2: 21505 fmovm.x &0x20, FP_SRC(%a6) 21505 fmovm.x &0x20, FP_SRC(%a6) 21506 lea FP_SRC(%a6), %a0 21506 lea FP_SRC(%a6), %a0 21507 rts 21507 rts 21508 load_fpn1_3: 21508 load_fpn1_3: 21509 fmovm.x &0x10, FP_SRC(%a6) 21509 fmovm.x &0x10, FP_SRC(%a6) 21510 lea FP_SRC(%a6), %a0 21510 lea FP_SRC(%a6), %a0 21511 rts 21511 rts 21512 load_fpn1_4: 21512 load_fpn1_4: 21513 fmovm.x &0x08, FP_SRC(%a6) 21513 fmovm.x &0x08, FP_SRC(%a6) 21514 lea FP_SRC(%a6), %a0 21514 lea FP_SRC(%a6), %a0 21515 rts 21515 rts 21516 load_fpn1_5: 21516 load_fpn1_5: 21517 fmovm.x &0x04, FP_SRC(%a6) 21517 fmovm.x &0x04, FP_SRC(%a6) 21518 lea FP_SRC(%a6), %a0 21518 lea FP_SRC(%a6), %a0 21519 rts 21519 rts 21520 load_fpn1_6: 21520 load_fpn1_6: 21521 fmovm.x &0x02, FP_SRC(%a6) 21521 fmovm.x &0x02, FP_SRC(%a6) 21522 lea FP_SRC(%a6), %a0 21522 lea FP_SRC(%a6), %a0 21523 rts 21523 rts 21524 load_fpn1_7: 21524 load_fpn1_7: 21525 fmovm.x &0x01, FP_SRC(%a6) 21525 fmovm.x &0x01, FP_SRC(%a6) 21526 lea FP_SRC(%a6), %a0 21526 lea FP_SRC(%a6), %a0 21527 rts 21527 rts 21528 21528 21529 ############################################ 21529 ############################################################################# 21530 21530 21531 ############################################ 21531 ######################################################################### 21532 # XDEF ************************************* 21532 # XDEF **************************************************************** # 21533 # load_fpn2(): load FP register value 21533 # load_fpn2(): load FP register value into FP_DST(a6). # 21534 # 21534 # # 21535 # XREF ************************************* 21535 # XREF **************************************************************** # 21536 # None 21536 # None # 21537 # 21537 # # 21538 # INPUT ************************************ 21538 # INPUT *************************************************************** # 21539 # d0 = index of FP register to load 21539 # d0 = index of FP register to load # 21540 # 21540 # # 21541 # OUTPUT *********************************** 21541 # OUTPUT ************************************************************** # 21542 # FP_DST(a6) = value loaded from FP re 21542 # FP_DST(a6) = value loaded from FP register file # 21543 # 21543 # # 21544 # ALGORITHM ******************************** 21544 # ALGORITHM *********************************************************** # 21545 # Using the index in d0, load FP_DST(a 21545 # Using the index in d0, load FP_DST(a6) with a number from the # 21546 # FP register file. 21546 # FP register file. # 21547 # 21547 # # 21548 ############################################ 21548 ######################################################################### 21549 21549 21550 global load_fpn2 21550 global load_fpn2 21551 load_fpn2: 21551 load_fpn2: 21552 mov.w (tbl_load_fpn2.b,%pc 21552 mov.w (tbl_load_fpn2.b,%pc,%d0.w*2), %d0 21553 jmp (tbl_load_fpn2.b,%pc 21553 jmp (tbl_load_fpn2.b,%pc,%d0.w*1) 21554 21554 21555 tbl_load_fpn2: 21555 tbl_load_fpn2: 21556 short load_fpn2_0 - tbl_lo 21556 short load_fpn2_0 - tbl_load_fpn2 21557 short load_fpn2_1 - tbl_lo 21557 short load_fpn2_1 - tbl_load_fpn2 21558 short load_fpn2_2 - tbl_lo 21558 short load_fpn2_2 - tbl_load_fpn2 21559 short load_fpn2_3 - tbl_lo 21559 short load_fpn2_3 - tbl_load_fpn2 21560 short load_fpn2_4 - tbl_lo 21560 short load_fpn2_4 - tbl_load_fpn2 21561 short load_fpn2_5 - tbl_lo 21561 short load_fpn2_5 - tbl_load_fpn2 21562 short load_fpn2_6 - tbl_lo 21562 short load_fpn2_6 - tbl_load_fpn2 21563 short load_fpn2_7 - tbl_lo 21563 short load_fpn2_7 - tbl_load_fpn2 21564 21564 21565 load_fpn2_0: 21565 load_fpn2_0: 21566 mov.l 0+EXC_FP0(%a6), 0+FP 21566 mov.l 0+EXC_FP0(%a6), 0+FP_DST(%a6) 21567 mov.l 4+EXC_FP0(%a6), 4+FP 21567 mov.l 4+EXC_FP0(%a6), 4+FP_DST(%a6) 21568 mov.l 8+EXC_FP0(%a6), 8+FP 21568 mov.l 8+EXC_FP0(%a6), 8+FP_DST(%a6) 21569 lea FP_DST(%a6), %a0 21569 lea FP_DST(%a6), %a0 21570 rts 21570 rts 21571 load_fpn2_1: 21571 load_fpn2_1: 21572 mov.l 0+EXC_FP1(%a6), 0+FP 21572 mov.l 0+EXC_FP1(%a6), 0+FP_DST(%a6) 21573 mov.l 4+EXC_FP1(%a6), 4+FP 21573 mov.l 4+EXC_FP1(%a6), 4+FP_DST(%a6) 21574 mov.l 8+EXC_FP1(%a6), 8+FP 21574 mov.l 8+EXC_FP1(%a6), 8+FP_DST(%a6) 21575 lea FP_DST(%a6), %a0 21575 lea FP_DST(%a6), %a0 21576 rts 21576 rts 21577 load_fpn2_2: 21577 load_fpn2_2: 21578 fmovm.x &0x20, FP_DST(%a6) 21578 fmovm.x &0x20, FP_DST(%a6) 21579 lea FP_DST(%a6), %a0 21579 lea FP_DST(%a6), %a0 21580 rts 21580 rts 21581 load_fpn2_3: 21581 load_fpn2_3: 21582 fmovm.x &0x10, FP_DST(%a6) 21582 fmovm.x &0x10, FP_DST(%a6) 21583 lea FP_DST(%a6), %a0 21583 lea FP_DST(%a6), %a0 21584 rts 21584 rts 21585 load_fpn2_4: 21585 load_fpn2_4: 21586 fmovm.x &0x08, FP_DST(%a6) 21586 fmovm.x &0x08, FP_DST(%a6) 21587 lea FP_DST(%a6), %a0 21587 lea FP_DST(%a6), %a0 21588 rts 21588 rts 21589 load_fpn2_5: 21589 load_fpn2_5: 21590 fmovm.x &0x04, FP_DST(%a6) 21590 fmovm.x &0x04, FP_DST(%a6) 21591 lea FP_DST(%a6), %a0 21591 lea FP_DST(%a6), %a0 21592 rts 21592 rts 21593 load_fpn2_6: 21593 load_fpn2_6: 21594 fmovm.x &0x02, FP_DST(%a6) 21594 fmovm.x &0x02, FP_DST(%a6) 21595 lea FP_DST(%a6), %a0 21595 lea FP_DST(%a6), %a0 21596 rts 21596 rts 21597 load_fpn2_7: 21597 load_fpn2_7: 21598 fmovm.x &0x01, FP_DST(%a6) 21598 fmovm.x &0x01, FP_DST(%a6) 21599 lea FP_DST(%a6), %a0 21599 lea FP_DST(%a6), %a0 21600 rts 21600 rts 21601 21601 21602 ############################################ 21602 ############################################################################# 21603 21603 21604 ############################################ 21604 ######################################################################### 21605 # XDEF ************************************* 21605 # XDEF **************************************************************** # 21606 # store_fpreg(): store an fp value to 21606 # store_fpreg(): store an fp value to the fpreg designated d0. # 21607 # 21607 # # 21608 # XREF ************************************* 21608 # XREF **************************************************************** # 21609 # None 21609 # None # 21610 # 21610 # # 21611 # INPUT ************************************ 21611 # INPUT *************************************************************** # 21612 # fp0 = extended precision value to st 21612 # fp0 = extended precision value to store # 21613 # d0 = index of floating-point regist 21613 # d0 = index of floating-point register # 21614 # 21614 # # 21615 # OUTPUT *********************************** 21615 # OUTPUT ************************************************************** # 21616 # None 21616 # None # 21617 # 21617 # # 21618 # ALGORITHM ******************************** 21618 # ALGORITHM *********************************************************** # 21619 # Store the value in fp0 to the FP reg 21619 # Store the value in fp0 to the FP register designated by the # 21620 # value in d0. The FP number can be DENORM o 21620 # value in d0. The FP number can be DENORM or SNAN so we have to be # 21621 # careful that we don't take an exception he 21621 # careful that we don't take an exception here. # 21622 # 21622 # # 21623 ############################################ 21623 ######################################################################### 21624 21624 21625 global store_fpreg 21625 global store_fpreg 21626 store_fpreg: 21626 store_fpreg: 21627 mov.w (tbl_store_fpreg.b,% 21627 mov.w (tbl_store_fpreg.b,%pc,%d0.w*2), %d0 21628 jmp (tbl_store_fpreg.b,% 21628 jmp (tbl_store_fpreg.b,%pc,%d0.w*1) 21629 21629 21630 tbl_store_fpreg: 21630 tbl_store_fpreg: 21631 short store_fpreg_0 - tbl_ 21631 short store_fpreg_0 - tbl_store_fpreg 21632 short store_fpreg_1 - tbl_ 21632 short store_fpreg_1 - tbl_store_fpreg 21633 short store_fpreg_2 - tbl_ 21633 short store_fpreg_2 - tbl_store_fpreg 21634 short store_fpreg_3 - tbl_ 21634 short store_fpreg_3 - tbl_store_fpreg 21635 short store_fpreg_4 - tbl_ 21635 short store_fpreg_4 - tbl_store_fpreg 21636 short store_fpreg_5 - tbl_ 21636 short store_fpreg_5 - tbl_store_fpreg 21637 short store_fpreg_6 - tbl_ 21637 short store_fpreg_6 - tbl_store_fpreg 21638 short store_fpreg_7 - tbl_ 21638 short store_fpreg_7 - tbl_store_fpreg 21639 21639 21640 store_fpreg_0: 21640 store_fpreg_0: 21641 fmovm.x &0x80, EXC_FP0(%a6) 21641 fmovm.x &0x80, EXC_FP0(%a6) 21642 rts 21642 rts 21643 store_fpreg_1: 21643 store_fpreg_1: 21644 fmovm.x &0x80, EXC_FP1(%a6) 21644 fmovm.x &0x80, EXC_FP1(%a6) 21645 rts 21645 rts 21646 store_fpreg_2: 21646 store_fpreg_2: 21647 fmovm.x &0x01, -(%sp) 21647 fmovm.x &0x01, -(%sp) 21648 fmovm.x (%sp)+, &0x20 21648 fmovm.x (%sp)+, &0x20 21649 rts 21649 rts 21650 store_fpreg_3: 21650 store_fpreg_3: 21651 fmovm.x &0x01, -(%sp) 21651 fmovm.x &0x01, -(%sp) 21652 fmovm.x (%sp)+, &0x10 21652 fmovm.x (%sp)+, &0x10 21653 rts 21653 rts 21654 store_fpreg_4: 21654 store_fpreg_4: 21655 fmovm.x &0x01, -(%sp) 21655 fmovm.x &0x01, -(%sp) 21656 fmovm.x (%sp)+, &0x08 21656 fmovm.x (%sp)+, &0x08 21657 rts 21657 rts 21658 store_fpreg_5: 21658 store_fpreg_5: 21659 fmovm.x &0x01, -(%sp) 21659 fmovm.x &0x01, -(%sp) 21660 fmovm.x (%sp)+, &0x04 21660 fmovm.x (%sp)+, &0x04 21661 rts 21661 rts 21662 store_fpreg_6: 21662 store_fpreg_6: 21663 fmovm.x &0x01, -(%sp) 21663 fmovm.x &0x01, -(%sp) 21664 fmovm.x (%sp)+, &0x02 21664 fmovm.x (%sp)+, &0x02 21665 rts 21665 rts 21666 store_fpreg_7: 21666 store_fpreg_7: 21667 fmovm.x &0x01, -(%sp) 21667 fmovm.x &0x01, -(%sp) 21668 fmovm.x (%sp)+, &0x01 21668 fmovm.x (%sp)+, &0x01 21669 rts 21669 rts 21670 21670 21671 ############################################ 21671 ######################################################################### 21672 # XDEF ************************************* 21672 # XDEF **************************************************************** # 21673 # _denorm(): denormalize an intermedia 21673 # _denorm(): denormalize an intermediate result # 21674 # 21674 # # 21675 # XREF ************************************* 21675 # XREF **************************************************************** # 21676 # None 21676 # None # 21677 # 21677 # # 21678 # INPUT ************************************ 21678 # INPUT *************************************************************** # 21679 # a0 = points to the operand to be den 21679 # a0 = points to the operand to be denormalized # 21680 # (in the internal extended fo 21680 # (in the internal extended format) # 21681 # 21681 # # 21682 # d0 = rounding precision 21682 # d0 = rounding precision # 21683 # 21683 # # 21684 # OUTPUT *********************************** 21684 # OUTPUT ************************************************************** # 21685 # a0 = pointer to the denormalized res 21685 # a0 = pointer to the denormalized result # 21686 # (in the internal extended fo 21686 # (in the internal extended format) # 21687 # 21687 # # 21688 # d0 = guard,round,sticky 21688 # d0 = guard,round,sticky # 21689 # 21689 # # 21690 # ALGORITHM ******************************** 21690 # ALGORITHM *********************************************************** # 21691 # According to the exponent underflow 21691 # According to the exponent underflow threshold for the given # 21692 # precision, shift the mantissa bits to the 21692 # precision, shift the mantissa bits to the right in order raise the # 21693 # exponent of the operand to the threshold v 21693 # exponent of the operand to the threshold value. While shifting the # 21694 # mantissa bits right, maintain the value of 21694 # mantissa bits right, maintain the value of the guard, round, and # 21695 # sticky bits. 21695 # sticky bits. # 21696 # other notes: 21696 # other notes: # 21697 # (1) _denorm() is called by the under 21697 # (1) _denorm() is called by the underflow routines # 21698 # (2) _denorm() does NOT affect the st 21698 # (2) _denorm() does NOT affect the status register # 21699 # 21699 # # 21700 ############################################ 21700 ######################################################################### 21701 21701 21702 # 21702 # 21703 # table of exponent threshold values for eac 21703 # table of exponent threshold values for each precision 21704 # 21704 # 21705 tbl_thresh: 21705 tbl_thresh: 21706 short 0x0 21706 short 0x0 21707 short sgl_thresh 21707 short sgl_thresh 21708 short dbl_thresh 21708 short dbl_thresh 21709 21709 21710 global _denorm 21710 global _denorm 21711 _denorm: 21711 _denorm: 21712 # 21712 # 21713 # Load the exponent threshold for the precis 21713 # Load the exponent threshold for the precision selected and check 21714 # to see if (threshold - exponent) is > 65 i 21714 # to see if (threshold - exponent) is > 65 in which case we can 21715 # simply calculate the sticky bit and zero t 21715 # simply calculate the sticky bit and zero the mantissa. otherwise 21716 # we have to call the denormalization routin 21716 # we have to call the denormalization routine. 21717 # 21717 # 21718 lsr.b &0x2, %d0 21718 lsr.b &0x2, %d0 # shift prec to lo bits 21719 mov.w (tbl_thresh.b,%pc,%d 21719 mov.w (tbl_thresh.b,%pc,%d0.w*2), %d1 # load prec threshold 21720 mov.w %d1, %d0 21720 mov.w %d1, %d0 # copy d1 into d0 21721 sub.w FTEMP_EX(%a0), %d0 21721 sub.w FTEMP_EX(%a0), %d0 # diff = threshold - exp 21722 cmpi.w %d0, &66 21722 cmpi.w %d0, &66 # is diff > 65? (mant + g,r bits) 21723 bpl.b denorm_set_stky 21723 bpl.b denorm_set_stky # yes; just calc sticky 21724 21724 21725 clr.l %d0 21725 clr.l %d0 # clear g,r,s 21726 btst &inex2_bit, FPSR_EXC 21726 btst &inex2_bit, FPSR_EXCEPT(%a6) # yes; was INEX2 set? 21727 beq.b denorm_call 21727 beq.b denorm_call # no; don't change anything 21728 bset &29, %d0 21728 bset &29, %d0 # yes; set sticky bit 21729 21729 21730 denorm_call: 21730 denorm_call: 21731 bsr.l dnrm_lp 21731 bsr.l dnrm_lp # denormalize the number 21732 rts 21732 rts 21733 21733 21734 # 21734 # 21735 # all bit would have been shifted off during 21735 # all bit would have been shifted off during the denorm so simply 21736 # calculate if the sticky should be set and 21736 # calculate if the sticky should be set and clear the entire mantissa. 21737 # 21737 # 21738 denorm_set_stky: 21738 denorm_set_stky: 21739 mov.l &0x20000000, %d0 21739 mov.l &0x20000000, %d0 # set sticky bit in return value 21740 mov.w %d1, FTEMP_EX(%a0) 21740 mov.w %d1, FTEMP_EX(%a0) # load exp with threshold 21741 clr.l FTEMP_HI(%a0) 21741 clr.l FTEMP_HI(%a0) # set d1 = 0 (ms mantissa) 21742 clr.l FTEMP_LO(%a0) 21742 clr.l FTEMP_LO(%a0) # set d2 = 0 (ms mantissa) 21743 rts 21743 rts 21744 21744 21745 # 21745 # # 21746 # dnrm_lp(): normalize exponent/mantissa to 21746 # dnrm_lp(): normalize exponent/mantissa to specified threshold # 21747 # 21747 # # 21748 # INPUT: 21748 # INPUT: # 21749 # %a0 : points to the operand t 21749 # %a0 : points to the operand to be denormalized # 21750 # %d0{31:29} : initial guard,round,sti 21750 # %d0{31:29} : initial guard,round,sticky # 21751 # %d1{15:0} : denormalization thresho 21751 # %d1{15:0} : denormalization threshold # 21752 # OUTPUT: 21752 # OUTPUT: # 21753 # %a0 : points to the denormali 21753 # %a0 : points to the denormalized operand # 21754 # %d0{31:29} : final guard,round,stick 21754 # %d0{31:29} : final guard,round,sticky # 21755 # 21755 # # 21756 21756 21757 # *** Local Equates *** # 21757 # *** Local Equates *** # 21758 set GRS, L_SCR2 21758 set GRS, L_SCR2 # g,r,s temp storage 21759 set FTEMP_LO2, L_SCR1 21759 set FTEMP_LO2, L_SCR1 # FTEMP_LO copy 21760 21760 21761 global dnrm_lp 21761 global dnrm_lp 21762 dnrm_lp: 21762 dnrm_lp: 21763 21763 21764 # 21764 # 21765 # make a copy of FTEMP_LO and place the g,r, 21765 # make a copy of FTEMP_LO and place the g,r,s bits directly after it 21766 # in memory so as to make the bitfield extra 21766 # in memory so as to make the bitfield extraction for denormalization easier. 21767 # 21767 # 21768 mov.l FTEMP_LO(%a0), FTEMP 21768 mov.l FTEMP_LO(%a0), FTEMP_LO2(%a6) # make FTEMP_LO copy 21769 mov.l %d0, GRS(%a6) 21769 mov.l %d0, GRS(%a6) # place g,r,s after it 21770 21770 21771 # 21771 # 21772 # check to see how much less than the underf 21772 # check to see how much less than the underflow threshold the operand 21773 # exponent is. 21773 # exponent is. 21774 # 21774 # 21775 mov.l %d1, %d0 21775 mov.l %d1, %d0 # copy the denorm threshold 21776 sub.w FTEMP_EX(%a0), %d1 21776 sub.w FTEMP_EX(%a0), %d1 # d1 = threshold - uns exponent 21777 ble.b dnrm_no_lp 21777 ble.b dnrm_no_lp # d1 <= 0 21778 cmpi.w %d1, &0x20 21778 cmpi.w %d1, &0x20 # is ( 0 <= d1 < 32) ? 21779 blt.b case_1 21779 blt.b case_1 # yes 21780 cmpi.w %d1, &0x40 21780 cmpi.w %d1, &0x40 # is (32 <= d1 < 64) ? 21781 blt.b case_2 21781 blt.b case_2 # yes 21782 bra.w case_3 21782 bra.w case_3 # (d1 >= 64) 21783 21783 21784 # 21784 # 21785 # No normalization necessary 21785 # No normalization necessary 21786 # 21786 # 21787 dnrm_no_lp: 21787 dnrm_no_lp: 21788 mov.l GRS(%a6), %d0 21788 mov.l GRS(%a6), %d0 # restore original g,r,s 21789 rts 21789 rts 21790 21790 21791 # 21791 # 21792 # case (0<d1<32) 21792 # case (0<d1<32) 21793 # 21793 # 21794 # %d0 = denorm threshold 21794 # %d0 = denorm threshold 21795 # %d1 = "n" = amt to shift 21795 # %d1 = "n" = amt to shift 21796 # 21796 # 21797 # ------------------------------------ 21797 # --------------------------------------------------------- 21798 # | FTEMP_HI | FTEMP_LO 21798 # | FTEMP_HI | FTEMP_LO |grs000.........000| 21799 # ------------------------------------ 21799 # --------------------------------------------------------- 21800 # <-(32 - n)-><-(n)-><-(32 - n)-><-(n) 21800 # <-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)-> 21801 # \ \ \ 21801 # \ \ \ \ 21802 # \ \ \ 21802 # \ \ \ \ 21803 # \ \ \ 21803 # \ \ \ \ 21804 # \ \ \ 21804 # \ \ \ \ 21805 # \ \ \ 21805 # \ \ \ \ 21806 # \ \ \ 21806 # \ \ \ \ 21807 # \ \ 21807 # \ \ \ \ 21808 # \ \ 21808 # \ \ \ \ 21809 # <-(n)-><-(32 - n)-><------(32)------ 21809 # <-(n)-><-(32 - n)-><------(32)-------><------(32)-------> 21810 # ------------------------------------ 21810 # --------------------------------------------------------- 21811 # |0.....0| NEW_HI | NEW_FTEMP_LO 21811 # |0.....0| NEW_HI | NEW_FTEMP_LO |grs | 21812 # ------------------------------------ 21812 # --------------------------------------------------------- 21813 # 21813 # 21814 case_1: 21814 case_1: 21815 mov.l %d2, -(%sp) 21815 mov.l %d2, -(%sp) # create temp storage 21816 21816 21817 mov.w %d0, FTEMP_EX(%a0) 21817 mov.w %d0, FTEMP_EX(%a0) # exponent = denorm threshold 21818 mov.l &32, %d0 21818 mov.l &32, %d0 21819 sub.w %d1, %d0 21819 sub.w %d1, %d0 # %d0 = 32 - %d1 21820 21820 21821 cmpi.w %d1, &29 21821 cmpi.w %d1, &29 # is shft amt >= 29 21822 blt.b case1_extract 21822 blt.b case1_extract # no; no fix needed 21823 mov.b GRS(%a6), %d2 21823 mov.b GRS(%a6), %d2 21824 or.b %d2, 3+FTEMP_LO2(%a6 21824 or.b %d2, 3+FTEMP_LO2(%a6) 21825 21825 21826 case1_extract: 21826 case1_extract: 21827 bfextu FTEMP_HI(%a0){&0:%d0 21827 bfextu FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_HI 21828 bfextu FTEMP_HI(%a0){%d0:&3 21828 bfextu FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new FTEMP_LO 21829 bfextu FTEMP_LO2(%a6){%d0:& 21829 bfextu FTEMP_LO2(%a6){%d0:&32}, %d0 # %d0 = new G,R,S 21830 21830 21831 mov.l %d2, FTEMP_HI(%a0) 21831 mov.l %d2, FTEMP_HI(%a0) # store new FTEMP_HI 21832 mov.l %d1, FTEMP_LO(%a0) 21832 mov.l %d1, FTEMP_LO(%a0) # store new FTEMP_LO 21833 21833 21834 bftst %d0{&2:&30} 21834 bftst %d0{&2:&30} # were bits shifted off? 21835 beq.b case1_sticky_clear 21835 beq.b case1_sticky_clear # no; go finish 21836 bset &rnd_stky_bit, %d0 21836 bset &rnd_stky_bit, %d0 # yes; set sticky bit 21837 21837 21838 case1_sticky_clear: 21838 case1_sticky_clear: 21839 and.l &0xe0000000, %d0 21839 and.l &0xe0000000, %d0 # clear all but G,R,S 21840 mov.l (%sp)+, %d2 21840 mov.l (%sp)+, %d2 # restore temp register 21841 rts 21841 rts 21842 21842 21843 # 21843 # 21844 # case (32<=d1<64) 21844 # case (32<=d1<64) 21845 # 21845 # 21846 # %d0 = denorm threshold 21846 # %d0 = denorm threshold 21847 # %d1 = "n" = amt to shift 21847 # %d1 = "n" = amt to shift 21848 # 21848 # 21849 # ------------------------------------ 21849 # --------------------------------------------------------- 21850 # | FTEMP_HI | FTEMP_LO 21850 # | FTEMP_HI | FTEMP_LO |grs000.........000| 21851 # ------------------------------------ 21851 # --------------------------------------------------------- 21852 # <-(32 - n)-><-(n)-><-(32 - n)-><-(n) 21852 # <-(32 - n)-><-(n)-><-(32 - n)-><-(n)-><-(32 - n)-><-(n)-> 21853 # \ \ \ 21853 # \ \ \ 21854 # \ \ \ 21854 # \ \ \ 21855 # \ \ ---- 21855 # \ \ ------------------- 21856 # \ -------------------- 21856 # \ -------------------- \ 21857 # ------------------- \ 21857 # ------------------- \ \ 21858 # \ \ 21858 # \ \ \ 21859 # \ 21859 # \ \ \ 21860 # \ 21860 # \ \ \ 21861 # <-------(32)------><-(n)-><-(32 - n) 21861 # <-------(32)------><-(n)-><-(32 - n)-><------(32)-------> 21862 # ------------------------------------ 21862 # --------------------------------------------------------- 21863 # |0...............0|0....0| NEW_LO 21863 # |0...............0|0....0| NEW_LO |grs | 21864 # ------------------------------------ 21864 # --------------------------------------------------------- 21865 # 21865 # 21866 case_2: 21866 case_2: 21867 mov.l %d2, -(%sp) 21867 mov.l %d2, -(%sp) # create temp storage 21868 21868 21869 mov.w %d0, FTEMP_EX(%a0) 21869 mov.w %d0, FTEMP_EX(%a0) # exponent = denorm threshold 21870 subi.w &0x20, %d1 21870 subi.w &0x20, %d1 # %d1 now between 0 and 32 21871 mov.l &0x20, %d0 21871 mov.l &0x20, %d0 21872 sub.w %d1, %d0 21872 sub.w %d1, %d0 # %d0 = 32 - %d1 21873 21873 21874 # subtle step here; or in the g,r,s at the b 21874 # subtle step here; or in the g,r,s at the bottom of FTEMP_LO to minimize 21875 # the number of bits to check for the sticky 21875 # the number of bits to check for the sticky detect. 21876 # it only plays a role in shift amounts of 6 21876 # it only plays a role in shift amounts of 61-63. 21877 mov.b GRS(%a6), %d2 21877 mov.b GRS(%a6), %d2 21878 or.b %d2, 3+FTEMP_LO2(%a6 21878 or.b %d2, 3+FTEMP_LO2(%a6) 21879 21879 21880 bfextu FTEMP_HI(%a0){&0:%d0 21880 bfextu FTEMP_HI(%a0){&0:%d0}, %d2 # %d2 = new FTEMP_LO 21881 bfextu FTEMP_HI(%a0){%d0:&3 21881 bfextu FTEMP_HI(%a0){%d0:&32}, %d1 # %d1 = new G,R,S 21882 21882 21883 bftst %d1{&2:&30} 21883 bftst %d1{&2:&30} # were any bits shifted off? 21884 bne.b case2_set_sticky 21884 bne.b case2_set_sticky # yes; set sticky bit 21885 bftst FTEMP_LO2(%a6){%d0:& 21885 bftst FTEMP_LO2(%a6){%d0:&31} # were any bits shifted off? 21886 bne.b case2_set_sticky 21886 bne.b case2_set_sticky # yes; set sticky bit 21887 21887 21888 mov.l %d1, %d0 21888 mov.l %d1, %d0 # move new G,R,S to %d0 21889 bra.b case2_end 21889 bra.b case2_end 21890 21890 21891 case2_set_sticky: 21891 case2_set_sticky: 21892 mov.l %d1, %d0 21892 mov.l %d1, %d0 # move new G,R,S to %d0 21893 bset &rnd_stky_bit, %d0 21893 bset &rnd_stky_bit, %d0 # set sticky bit 21894 21894 21895 case2_end: 21895 case2_end: 21896 clr.l FTEMP_HI(%a0) 21896 clr.l FTEMP_HI(%a0) # store FTEMP_HI = 0 21897 mov.l %d2, FTEMP_LO(%a0) 21897 mov.l %d2, FTEMP_LO(%a0) # store FTEMP_LO 21898 and.l &0xe0000000, %d0 21898 and.l &0xe0000000, %d0 # clear all but G,R,S 21899 21899 21900 mov.l (%sp)+,%d2 21900 mov.l (%sp)+,%d2 # restore temp register 21901 rts 21901 rts 21902 21902 21903 # 21903 # 21904 # case (d1>=64) 21904 # case (d1>=64) 21905 # 21905 # 21906 # %d0 = denorm threshold 21906 # %d0 = denorm threshold 21907 # %d1 = amt to shift 21907 # %d1 = amt to shift 21908 # 21908 # 21909 case_3: 21909 case_3: 21910 mov.w %d0, FTEMP_EX(%a0) 21910 mov.w %d0, FTEMP_EX(%a0) # insert denorm threshold 21911 21911 21912 cmpi.w %d1, &65 21912 cmpi.w %d1, &65 # is shift amt > 65? 21913 blt.b case3_64 21913 blt.b case3_64 # no; it's == 64 21914 beq.b case3_65 21914 beq.b case3_65 # no; it's == 65 21915 21915 21916 # 21916 # 21917 # case (d1>65) 21917 # case (d1>65) 21918 # 21918 # 21919 # Shift value is > 65 and out of range. All 21919 # Shift value is > 65 and out of range. All bits are shifted off. 21920 # Return a zero mantissa with the sticky bit 21920 # Return a zero mantissa with the sticky bit set 21921 # 21921 # 21922 clr.l FTEMP_HI(%a0) 21922 clr.l FTEMP_HI(%a0) # clear hi(mantissa) 21923 clr.l FTEMP_LO(%a0) 21923 clr.l FTEMP_LO(%a0) # clear lo(mantissa) 21924 mov.l &0x20000000, %d0 21924 mov.l &0x20000000, %d0 # set sticky bit 21925 rts 21925 rts 21926 21926 21927 # 21927 # 21928 # case (d1 == 64) 21928 # case (d1 == 64) 21929 # 21929 # 21930 # ------------------------------------ 21930 # --------------------------------------------------------- 21931 # | FTEMP_HI | FTEMP_LO 21931 # | FTEMP_HI | FTEMP_LO |grs000.........000| 21932 # ------------------------------------ 21932 # --------------------------------------------------------- 21933 # <-------(32)------> 21933 # <-------(32)------> 21934 # \ \ 21934 # \ \ 21935 # \ \ 21935 # \ \ 21936 # \ \ 21936 # \ \ 21937 # \ -------------- 21937 # \ ------------------------------ 21938 # ------------------------------- 21938 # ------------------------------- \ 21939 # \ 21939 # \ \ 21940 # 21940 # \ \ 21941 # 21941 # \ \ 21942 # 21942 # <-------(32)------> 21943 # ------------------------------------ 21943 # --------------------------------------------------------- 21944 # |0...............0|0................ 21944 # |0...............0|0................0|grs | 21945 # ------------------------------------ 21945 # --------------------------------------------------------- 21946 # 21946 # 21947 case3_64: 21947 case3_64: 21948 mov.l FTEMP_HI(%a0), %d0 21948 mov.l FTEMP_HI(%a0), %d0 # fetch hi(mantissa) 21949 mov.l %d0, %d1 21949 mov.l %d0, %d1 # make a copy 21950 and.l &0xc0000000, %d0 21950 and.l &0xc0000000, %d0 # extract G,R 21951 and.l &0x3fffffff, %d1 21951 and.l &0x3fffffff, %d1 # extract other bits 21952 21952 21953 bra.b case3_complete 21953 bra.b case3_complete 21954 21954 21955 # 21955 # 21956 # case (d1 == 65) 21956 # case (d1 == 65) 21957 # 21957 # 21958 # ------------------------------------ 21958 # --------------------------------------------------------- 21959 # | FTEMP_HI | FTEMP_LO 21959 # | FTEMP_HI | FTEMP_LO |grs000.........000| 21960 # ------------------------------------ 21960 # --------------------------------------------------------- 21961 # <-------(32)------> 21961 # <-------(32)------> 21962 # \ \ 21962 # \ \ 21963 # \ \ 21963 # \ \ 21964 # \ \ 21964 # \ \ 21965 # \ -------------- 21965 # \ ------------------------------ 21966 # -------------------------------- 21966 # -------------------------------- \ 21967 # 21967 # \ \ 21968 # 21968 # \ \ 21969 # 21969 # \ \ 21970 # 21970 # <-------(31)-----> 21971 # ------------------------------------ 21971 # --------------------------------------------------------- 21972 # |0...............0|0................ 21972 # |0...............0|0................0|0rs | 21973 # ------------------------------------ 21973 # --------------------------------------------------------- 21974 # 21974 # 21975 case3_65: 21975 case3_65: 21976 mov.l FTEMP_HI(%a0), %d0 21976 mov.l FTEMP_HI(%a0), %d0 # fetch hi(mantissa) 21977 and.l &0x80000000, %d0 21977 and.l &0x80000000, %d0 # extract R bit 21978 lsr.l &0x1, %d0 21978 lsr.l &0x1, %d0 # shift high bit into R bit 21979 and.l &0x7fffffff, %d1 21979 and.l &0x7fffffff, %d1 # extract other bits 21980 21980 21981 case3_complete: 21981 case3_complete: 21982 # last operation done was an "and" of the bi 21982 # last operation done was an "and" of the bits shifted off so the condition 21983 # codes are already set so branch accordingl 21983 # codes are already set so branch accordingly. 21984 bne.b case3_set_sticky 21984 bne.b case3_set_sticky # yes; go set new sticky 21985 tst.l FTEMP_LO(%a0) 21985 tst.l FTEMP_LO(%a0) # were any bits shifted off? 21986 bne.b case3_set_sticky 21986 bne.b case3_set_sticky # yes; go set new sticky 21987 tst.b GRS(%a6) 21987 tst.b GRS(%a6) # were any bits shifted off? 21988 bne.b case3_set_sticky 21988 bne.b case3_set_sticky # yes; go set new sticky 21989 21989 21990 # 21990 # 21991 # no bits were shifted off so don't set the 21991 # no bits were shifted off so don't set the sticky bit. 21992 # the guard and 21992 # the guard and 21993 # the entire mantissa is zero. 21993 # the entire mantissa is zero. 21994 # 21994 # 21995 clr.l FTEMP_HI(%a0) 21995 clr.l FTEMP_HI(%a0) # clear hi(mantissa) 21996 clr.l FTEMP_LO(%a0) 21996 clr.l FTEMP_LO(%a0) # clear lo(mantissa) 21997 rts 21997 rts 21998 21998 21999 # 21999 # 22000 # some bits were shifted off so set the stic 22000 # some bits were shifted off so set the sticky bit. 22001 # the entire mantissa is zero. 22001 # the entire mantissa is zero. 22002 # 22002 # 22003 case3_set_sticky: 22003 case3_set_sticky: 22004 bset &rnd_stky_bit,%d0 22004 bset &rnd_stky_bit,%d0 # set new sticky bit 22005 clr.l FTEMP_HI(%a0) 22005 clr.l FTEMP_HI(%a0) # clear hi(mantissa) 22006 clr.l FTEMP_LO(%a0) 22006 clr.l FTEMP_LO(%a0) # clear lo(mantissa) 22007 rts 22007 rts 22008 22008 22009 ############################################ 22009 ######################################################################### 22010 # XDEF ************************************* 22010 # XDEF **************************************************************** # 22011 # _round(): round result according to 22011 # _round(): round result according to precision/mode # 22012 # 22012 # # 22013 # XREF ************************************* 22013 # XREF **************************************************************** # 22014 # None 22014 # None # 22015 # 22015 # # 22016 # INPUT ************************************ 22016 # INPUT *************************************************************** # 22017 # a0 = ptr to input operand in 22017 # a0 = ptr to input operand in internal extended format # 22018 # d1(hi) = contains rounding precis 22018 # d1(hi) = contains rounding precision: # 22019 # ext = $0000xxxx 22019 # ext = $0000xxxx # 22020 # sgl = $0004xxxx 22020 # sgl = $0004xxxx # 22021 # dbl = $0008xxxx 22021 # dbl = $0008xxxx # 22022 # d1(lo) = contains rounding mode: 22022 # d1(lo) = contains rounding mode: # 22023 # RN = $xxxx0000 22023 # RN = $xxxx0000 # 22024 # RZ = $xxxx0001 22024 # RZ = $xxxx0001 # 22025 # RM = $xxxx0002 22025 # RM = $xxxx0002 # 22026 # RP = $xxxx0003 22026 # RP = $xxxx0003 # 22027 # d0{31:29} = contains the g,r,s bits 22027 # d0{31:29} = contains the g,r,s bits (extended) # 22028 # 22028 # # 22029 # OUTPUT *********************************** 22029 # OUTPUT ************************************************************** # 22030 # a0 = pointer to rounded result 22030 # a0 = pointer to rounded result # 22031 # 22031 # # 22032 # ALGORITHM ******************************** 22032 # ALGORITHM *********************************************************** # 22033 # On return the value pointed to by a0 22033 # On return the value pointed to by a0 is correctly rounded, # 22034 # a0 is preserved and the g-r-s bits i 22034 # a0 is preserved and the g-r-s bits in d0 are cleared. # 22035 # The result is not typed - the tag fi 22035 # The result is not typed - the tag field is invalid. The # 22036 # result is still in the internal exte 22036 # result is still in the internal extended format. # 22037 # 22037 # # 22038 # The INEX bit of USER_FPSR will be se 22038 # The INEX bit of USER_FPSR will be set if the rounded result was # 22039 # inexact (i.e. if any of the g-r-s bi 22039 # inexact (i.e. if any of the g-r-s bits were set). # 22040 # 22040 # # 22041 ############################################ 22041 ######################################################################### 22042 22042 22043 global _round 22043 global _round 22044 _round: 22044 _round: 22045 # 22045 # 22046 # ext_grs() looks at the rounding precision 22046 # ext_grs() looks at the rounding precision and sets the appropriate 22047 # G,R,S bits. 22047 # G,R,S bits. 22048 # If (G,R,S == 0) then result is exact and r 22048 # If (G,R,S == 0) then result is exact and round is done, else set 22049 # the inex flag in status reg and continue. 22049 # the inex flag in status reg and continue. 22050 # 22050 # 22051 bsr.l ext_grs 22051 bsr.l ext_grs # extract G,R,S 22052 22052 22053 tst.l %d0 22053 tst.l %d0 # are G,R,S zero? 22054 beq.w truncate 22054 beq.w truncate # yes; round is complete 22055 22055 22056 or.w &inx2a_mask, 2+USER_ 22056 or.w &inx2a_mask, 2+USER_FPSR(%a6) # set inex2/ainex 22057 22057 22058 # 22058 # 22059 # Use rounding mode as an index into a jump 22059 # Use rounding mode as an index into a jump table for these modes. 22060 # All of the following assumes grs != 0. 22060 # All of the following assumes grs != 0. 22061 # 22061 # 22062 mov.w (tbl_mode.b,%pc,%d1. 22062 mov.w (tbl_mode.b,%pc,%d1.w*2), %a1 # load jump offset 22063 jmp (tbl_mode.b,%pc,%a1) 22063 jmp (tbl_mode.b,%pc,%a1) # jmp to rnd mode handler 22064 22064 22065 tbl_mode: 22065 tbl_mode: 22066 short rnd_near - tbl_mode 22066 short rnd_near - tbl_mode 22067 short truncate - tbl_mode 22067 short truncate - tbl_mode # RZ always truncates 22068 short rnd_mnus - tbl_mode 22068 short rnd_mnus - tbl_mode 22069 short rnd_plus - tbl_mode 22069 short rnd_plus - tbl_mode 22070 22070 22071 ############################################ 22071 ################################################################# 22072 # ROUND PLUS INFINITY 22072 # ROUND PLUS INFINITY # 22073 # 22073 # # 22074 # If sign of fp number = 0 (positive), 22074 # If sign of fp number = 0 (positive), then add 1 to l. # 22075 ############################################ 22075 ################################################################# 22076 rnd_plus: 22076 rnd_plus: 22077 tst.b FTEMP_SGN(%a0) 22077 tst.b FTEMP_SGN(%a0) # check for sign 22078 bmi.w truncate 22078 bmi.w truncate # if positive then truncate 22079 22079 22080 mov.l &0xffffffff, %d0 22080 mov.l &0xffffffff, %d0 # force g,r,s to be all f's 22081 swap %d1 22081 swap %d1 # set up d1 for round prec. 22082 22082 22083 cmpi.b %d1, &s_mode 22083 cmpi.b %d1, &s_mode # is prec = sgl? 22084 beq.w add_sgl 22084 beq.w add_sgl # yes 22085 bgt.w add_dbl 22085 bgt.w add_dbl # no; it's dbl 22086 bra.w add_ext 22086 bra.w add_ext # no; it's ext 22087 22087 22088 ############################################ 22088 ################################################################# 22089 # ROUND MINUS INFINITY 22089 # ROUND MINUS INFINITY # 22090 # 22090 # # 22091 # If sign of fp number = 1 (negative), 22091 # If sign of fp number = 1 (negative), then add 1 to l. # 22092 ############################################ 22092 ################################################################# 22093 rnd_mnus: 22093 rnd_mnus: 22094 tst.b FTEMP_SGN(%a0) 22094 tst.b FTEMP_SGN(%a0) # check for sign 22095 bpl.w truncate 22095 bpl.w truncate # if negative then truncate 22096 22096 22097 mov.l &0xffffffff, %d0 22097 mov.l &0xffffffff, %d0 # force g,r,s to be all f's 22098 swap %d1 22098 swap %d1 # set up d1 for round prec. 22099 22099 22100 cmpi.b %d1, &s_mode 22100 cmpi.b %d1, &s_mode # is prec = sgl? 22101 beq.w add_sgl 22101 beq.w add_sgl # yes 22102 bgt.w add_dbl 22102 bgt.w add_dbl # no; it's dbl 22103 bra.w add_ext 22103 bra.w add_ext # no; it's ext 22104 22104 22105 ############################################ 22105 ################################################################# 22106 # ROUND NEAREST 22106 # ROUND NEAREST # 22107 # 22107 # # 22108 # If (g=1), then add 1 to l and if (r= 22108 # If (g=1), then add 1 to l and if (r=s=0), then clear l # 22109 # Note that this will round to even in 22109 # Note that this will round to even in case of a tie. # 22110 ############################################ 22110 ################################################################# 22111 rnd_near: 22111 rnd_near: 22112 asl.l &0x1, %d0 22112 asl.l &0x1, %d0 # shift g-bit to c-bit 22113 bcc.w truncate 22113 bcc.w truncate # if (g=1) then 22114 22114 22115 swap %d1 22115 swap %d1 # set up d1 for round prec. 22116 22116 22117 cmpi.b %d1, &s_mode 22117 cmpi.b %d1, &s_mode # is prec = sgl? 22118 beq.w add_sgl 22118 beq.w add_sgl # yes 22119 bgt.w add_dbl 22119 bgt.w add_dbl # no; it's dbl 22120 bra.w add_ext 22120 bra.w add_ext # no; it's ext 22121 22121 22122 # *** LOCAL EQUATES *** 22122 # *** LOCAL EQUATES *** 22123 set ad_1_sgl, 0x00000100 # co 22123 set ad_1_sgl, 0x00000100 # constant to add 1 to l-bit in sgl prec 22124 set ad_1_dbl, 0x00000800 # co 22124 set ad_1_dbl, 0x00000800 # constant to add 1 to l-bit in dbl prec 22125 22125 22126 ######################### 22126 ######################### 22127 # ADD SINGLE # 22127 # ADD SINGLE # 22128 ######################### 22128 ######################### 22129 add_sgl: 22129 add_sgl: 22130 add.l &ad_1_sgl, FTEMP_HI( 22130 add.l &ad_1_sgl, FTEMP_HI(%a0) 22131 bcc.b scc_clr 22131 bcc.b scc_clr # no mantissa overflow 22132 roxr.w FTEMP_HI(%a0) 22132 roxr.w FTEMP_HI(%a0) # shift v-bit back in 22133 roxr.w FTEMP_HI+2(%a0) 22133 roxr.w FTEMP_HI+2(%a0) # shift v-bit back in 22134 add.w &0x1, FTEMP_EX(%a0) 22134 add.w &0x1, FTEMP_EX(%a0) # and incr exponent 22135 scc_clr: 22135 scc_clr: 22136 tst.l %d0 22136 tst.l %d0 # test for rs = 0 22137 bne.b sgl_done 22137 bne.b sgl_done 22138 and.w &0xfe00, FTEMP_HI+2( 22138 and.w &0xfe00, FTEMP_HI+2(%a0) # clear the l-bit 22139 sgl_done: 22139 sgl_done: 22140 and.l &0xffffff00, FTEMP_H 22140 and.l &0xffffff00, FTEMP_HI(%a0) # truncate bits beyond sgl limit 22141 clr.l FTEMP_LO(%a0) 22141 clr.l FTEMP_LO(%a0) # clear d2 22142 rts 22142 rts 22143 22143 22144 ######################### 22144 ######################### 22145 # ADD EXTENDED # 22145 # ADD EXTENDED # 22146 ######################### 22146 ######################### 22147 add_ext: 22147 add_ext: 22148 addq.l &1,FTEMP_LO(%a0) 22148 addq.l &1,FTEMP_LO(%a0) # add 1 to l-bit 22149 bcc.b xcc_clr 22149 bcc.b xcc_clr # test for carry out 22150 addq.l &1,FTEMP_HI(%a0) 22150 addq.l &1,FTEMP_HI(%a0) # propagate carry 22151 bcc.b xcc_clr 22151 bcc.b xcc_clr 22152 roxr.w FTEMP_HI(%a0) 22152 roxr.w FTEMP_HI(%a0) # mant is 0 so restore v-bit 22153 roxr.w FTEMP_HI+2(%a0) 22153 roxr.w FTEMP_HI+2(%a0) # mant is 0 so restore v-bit 22154 roxr.w FTEMP_LO(%a0) 22154 roxr.w FTEMP_LO(%a0) 22155 roxr.w FTEMP_LO+2(%a0) 22155 roxr.w FTEMP_LO+2(%a0) 22156 add.w &0x1,FTEMP_EX(%a0) 22156 add.w &0x1,FTEMP_EX(%a0) # and inc exp 22157 xcc_clr: 22157 xcc_clr: 22158 tst.l %d0 22158 tst.l %d0 # test rs = 0 22159 bne.b add_ext_done 22159 bne.b add_ext_done 22160 and.b &0xfe,FTEMP_LO+3(%a0 22160 and.b &0xfe,FTEMP_LO+3(%a0) # clear the l bit 22161 add_ext_done: 22161 add_ext_done: 22162 rts 22162 rts 22163 22163 22164 ######################### 22164 ######################### 22165 # ADD DOUBLE # 22165 # ADD DOUBLE # 22166 ######################### 22166 ######################### 22167 add_dbl: 22167 add_dbl: 22168 add.l &ad_1_dbl, FTEMP_LO( 22168 add.l &ad_1_dbl, FTEMP_LO(%a0) # add 1 to lsb 22169 bcc.b dcc_clr 22169 bcc.b dcc_clr # no carry 22170 addq.l &0x1, FTEMP_HI(%a0) 22170 addq.l &0x1, FTEMP_HI(%a0) # propagate carry 22171 bcc.b dcc_clr 22171 bcc.b dcc_clr # no carry 22172 22172 22173 roxr.w FTEMP_HI(%a0) 22173 roxr.w FTEMP_HI(%a0) # mant is 0 so restore v-bit 22174 roxr.w FTEMP_HI+2(%a0) 22174 roxr.w FTEMP_HI+2(%a0) # mant is 0 so restore v-bit 22175 roxr.w FTEMP_LO(%a0) 22175 roxr.w FTEMP_LO(%a0) 22176 roxr.w FTEMP_LO+2(%a0) 22176 roxr.w FTEMP_LO+2(%a0) 22177 addq.w &0x1, FTEMP_EX(%a0) 22177 addq.w &0x1, FTEMP_EX(%a0) # incr exponent 22178 dcc_clr: 22178 dcc_clr: 22179 tst.l %d0 22179 tst.l %d0 # test for rs = 0 22180 bne.b dbl_done 22180 bne.b dbl_done 22181 and.w &0xf000, FTEMP_LO+2( 22181 and.w &0xf000, FTEMP_LO+2(%a0) # clear the l-bit 22182 22182 22183 dbl_done: 22183 dbl_done: 22184 and.l &0xfffff800,FTEMP_LO 22184 and.l &0xfffff800,FTEMP_LO(%a0) # truncate bits beyond dbl limit 22185 rts 22185 rts 22186 22186 22187 ########################### 22187 ########################### 22188 # Truncate all other bits # 22188 # Truncate all other bits # 22189 ########################### 22189 ########################### 22190 truncate: 22190 truncate: 22191 swap %d1 22191 swap %d1 # select rnd prec 22192 22192 22193 cmpi.b %d1, &s_mode 22193 cmpi.b %d1, &s_mode # is prec sgl? 22194 beq.w sgl_done 22194 beq.w sgl_done # yes 22195 bgt.b dbl_done 22195 bgt.b dbl_done # no; it's dbl 22196 rts 22196 rts # no; it's ext 22197 22197 22198 22198 22199 # 22199 # 22200 # ext_grs(): extract guard, round and sticky 22200 # ext_grs(): extract guard, round and sticky bits according to 22201 # rounding precision. 22201 # rounding precision. 22202 # 22202 # 22203 # INPUT 22203 # INPUT 22204 # d0 = extended precision g,r, 22204 # d0 = extended precision g,r,s (in d0{31:29}) 22205 # d1 = {PREC,ROUND} 22205 # d1 = {PREC,ROUND} 22206 # OUTPUT 22206 # OUTPUT 22207 # d0{31:29} = guard, round, sticky 22207 # d0{31:29} = guard, round, sticky 22208 # 22208 # 22209 # The ext_grs extract the guard/round/sticky 22209 # The ext_grs extract the guard/round/sticky bits according to the 22210 # selected rounding precision. It is called 22210 # selected rounding precision. It is called by the round subroutine 22211 # only. All registers except d0 are kept in 22211 # only. All registers except d0 are kept intact. d0 becomes an 22212 # updated guard,round,sticky in d0{31:29} 22212 # updated guard,round,sticky in d0{31:29} 22213 # 22213 # 22214 # Notes: the ext_grs uses the round PREC, an 22214 # Notes: the ext_grs uses the round PREC, and therefore has to swap d1 22215 # prior to usage, and needs to restor 22215 # prior to usage, and needs to restore d1 to original. this 22216 # routine is tightly tied to the roun 22216 # routine is tightly tied to the round routine and not meant to 22217 # uphold standard subroutine calling 22217 # uphold standard subroutine calling practices. 22218 # 22218 # 22219 22219 22220 ext_grs: 22220 ext_grs: 22221 swap %d1 22221 swap %d1 # have d1.w point to round precision 22222 tst.b %d1 22222 tst.b %d1 # is rnd prec = extended? 22223 bne.b ext_grs_not_ext 22223 bne.b ext_grs_not_ext # no; go handle sgl or dbl 22224 22224 22225 # 22225 # 22226 # %d0 actually already hold g,r,s since _rou 22226 # %d0 actually already hold g,r,s since _round() had it before calling 22227 # this function. so, as long as we don't dis 22227 # this function. so, as long as we don't disturb it, we are "returning" it. 22228 # 22228 # 22229 ext_grs_ext: 22229 ext_grs_ext: 22230 swap %d1 22230 swap %d1 # yes; return to correct positions 22231 rts 22231 rts 22232 22232 22233 ext_grs_not_ext: 22233 ext_grs_not_ext: 22234 movm.l &0x3000, -(%sp) 22234 movm.l &0x3000, -(%sp) # make some temp registers {d2/d3} 22235 22235 22236 cmpi.b %d1, &s_mode 22236 cmpi.b %d1, &s_mode # is rnd prec = sgl? 22237 bne.b ext_grs_dbl 22237 bne.b ext_grs_dbl # no; go handle dbl 22238 22238 22239 # 22239 # 22240 # sgl: 22240 # sgl: 22241 # 96 64 40 32 22241 # 96 64 40 32 0 22242 # ------------------------------------ 22242 # ----------------------------------------------------- 22243 # | EXP |XXXXXXX| |xx | 22243 # | EXP |XXXXXXX| |xx | |grs| 22244 # ------------------------------------ 22244 # ----------------------------------------------------- 22245 # <--(24)--->nn\ 22245 # <--(24)--->nn\ / 22246 # ee ------ 22246 # ee --------------------- 22247 # ww 22247 # ww | 22248 # 22248 # v 22249 # gr n 22249 # gr new sticky 22250 # 22250 # 22251 ext_grs_sgl: 22251 ext_grs_sgl: 22252 bfextu FTEMP_HI(%a0){&24:&2 22252 bfextu FTEMP_HI(%a0){&24:&2}, %d3 # sgl prec. g-r are 2 bits right 22253 mov.l &30, %d2 22253 mov.l &30, %d2 # of the sgl prec. limits 22254 lsl.l %d2, %d3 22254 lsl.l %d2, %d3 # shift g-r bits to MSB of d3 22255 mov.l FTEMP_HI(%a0), %d2 22255 mov.l FTEMP_HI(%a0), %d2 # get word 2 for s-bit test 22256 and.l &0x0000003f, %d2 22256 and.l &0x0000003f, %d2 # s bit is the or of all other 22257 bne.b ext_grs_st_stky 22257 bne.b ext_grs_st_stky # bits to the right of g-r 22258 tst.l FTEMP_LO(%a0) 22258 tst.l FTEMP_LO(%a0) # test lower mantissa 22259 bne.b ext_grs_st_stky 22259 bne.b ext_grs_st_stky # if any are set, set sticky 22260 tst.l %d0 22260 tst.l %d0 # test original g,r,s 22261 bne.b ext_grs_st_stky 22261 bne.b ext_grs_st_stky # if any are set, set sticky 22262 bra.b ext_grs_end_sd 22262 bra.b ext_grs_end_sd # if words 3 and 4 are clr, exit 22263 22263 22264 # 22264 # 22265 # dbl: 22265 # dbl: 22266 # 96 64 32 22266 # 96 64 32 11 0 22267 # ------------------------------------ 22267 # ----------------------------------------------------- 22268 # | EXP |XXXXXXX| | 22268 # | EXP |XXXXXXX| | |xx |grs| 22269 # ------------------------------------ 22269 # ----------------------------------------------------- 22270 # 22270 # nn\ / 22271 # 22271 # ee ------- 22272 # 22272 # ww | 22273 # 22273 # v 22274 # 22274 # gr new sticky 22275 # 22275 # 22276 ext_grs_dbl: 22276 ext_grs_dbl: 22277 bfextu FTEMP_LO(%a0){&21:&2 22277 bfextu FTEMP_LO(%a0){&21:&2}, %d3 # dbl-prec. g-r are 2 bits right 22278 mov.l &30, %d2 22278 mov.l &30, %d2 # of the dbl prec. limits 22279 lsl.l %d2, %d3 22279 lsl.l %d2, %d3 # shift g-r bits to the MSB of d3 22280 mov.l FTEMP_LO(%a0), %d2 22280 mov.l FTEMP_LO(%a0), %d2 # get lower mantissa for s-bit test 22281 and.l &0x000001ff, %d2 22281 and.l &0x000001ff, %d2 # s bit is the or-ing of all 22282 bne.b ext_grs_st_stky 22282 bne.b ext_grs_st_stky # other bits to the right of g-r 22283 tst.l %d0 22283 tst.l %d0 # test word original g,r,s 22284 bne.b ext_grs_st_stky 22284 bne.b ext_grs_st_stky # if any are set, set sticky 22285 bra.b ext_grs_end_sd 22285 bra.b ext_grs_end_sd # if clear, exit 22286 22286 22287 ext_grs_st_stky: 22287 ext_grs_st_stky: 22288 bset &rnd_stky_bit, %d3 22288 bset &rnd_stky_bit, %d3 # set sticky bit 22289 ext_grs_end_sd: 22289 ext_grs_end_sd: 22290 mov.l %d3, %d0 22290 mov.l %d3, %d0 # return grs to d0 22291 22291 22292 movm.l (%sp)+, &0xc 22292 movm.l (%sp)+, &0xc # restore scratch registers {d2/d3} 22293 22293 22294 swap %d1 22294 swap %d1 # restore d1 to original 22295 rts 22295 rts 22296 22296 22297 ############################################ 22297 ######################################################################### 22298 # norm(): normalize the mantissa of an exten 22298 # norm(): normalize the mantissa of an extended precision input. the # 22299 # input operand should not be normal 22299 # input operand should not be normalized already. # 22300 # 22300 # # 22301 # XDEF ************************************* 22301 # XDEF **************************************************************** # 22302 # norm() 22302 # norm() # 22303 # 22303 # # 22304 # XREF ************************************* 22304 # XREF **************************************************************** # 22305 # none 22305 # none # 22306 # 22306 # # 22307 # INPUT ************************************ 22307 # INPUT *************************************************************** # 22308 # a0 = pointer fp extended precision o 22308 # a0 = pointer fp extended precision operand to normalize # 22309 # 22309 # # 22310 # OUTPUT *********************************** 22310 # OUTPUT ************************************************************** # 22311 # d0 = number of bit positions the man 22311 # d0 = number of bit positions the mantissa was shifted # 22312 # a0 = the input operand's mantissa is 22312 # a0 = the input operand's mantissa is normalized; the exponent # 22313 # is unchanged. 22313 # is unchanged. # 22314 # 22314 # # 22315 ############################################ 22315 ######################################################################### 22316 global norm 22316 global norm 22317 norm: 22317 norm: 22318 mov.l %d2, -(%sp) 22318 mov.l %d2, -(%sp) # create some temp regs 22319 mov.l %d3, -(%sp) 22319 mov.l %d3, -(%sp) 22320 22320 22321 mov.l FTEMP_HI(%a0), %d0 22321 mov.l FTEMP_HI(%a0), %d0 # load hi(mantissa) 22322 mov.l FTEMP_LO(%a0), %d1 22322 mov.l FTEMP_LO(%a0), %d1 # load lo(mantissa) 22323 22323 22324 bfffo %d0{&0:&32}, %d2 22324 bfffo %d0{&0:&32}, %d2 # how many places to shift? 22325 beq.b norm_lo 22325 beq.b norm_lo # hi(man) is all zeroes! 22326 22326 22327 norm_hi: 22327 norm_hi: 22328 lsl.l %d2, %d0 22328 lsl.l %d2, %d0 # left shift hi(man) 22329 bfextu %d1{&0:%d2}, %d3 22329 bfextu %d1{&0:%d2}, %d3 # extract lo bits 22330 22330 22331 or.l %d3, %d0 22331 or.l %d3, %d0 # create hi(man) 22332 lsl.l %d2, %d1 22332 lsl.l %d2, %d1 # create lo(man) 22333 22333 22334 mov.l %d0, FTEMP_HI(%a0) 22334 mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 22335 mov.l %d1, FTEMP_LO(%a0) 22335 mov.l %d1, FTEMP_LO(%a0) # store new lo(man) 22336 22336 22337 mov.l %d2, %d0 22337 mov.l %d2, %d0 # return shift amount 22338 22338 22339 mov.l (%sp)+, %d3 22339 mov.l (%sp)+, %d3 # restore temp regs 22340 mov.l (%sp)+, %d2 22340 mov.l (%sp)+, %d2 22341 22341 22342 rts 22342 rts 22343 22343 22344 norm_lo: 22344 norm_lo: 22345 bfffo %d1{&0:&32}, %d2 22345 bfffo %d1{&0:&32}, %d2 # how many places to shift? 22346 lsl.l %d2, %d1 22346 lsl.l %d2, %d1 # shift lo(man) 22347 add.l &32, %d2 22347 add.l &32, %d2 # add 32 to shft amount 22348 22348 22349 mov.l %d1, FTEMP_HI(%a0) 22349 mov.l %d1, FTEMP_HI(%a0) # store hi(man) 22350 clr.l FTEMP_LO(%a0) 22350 clr.l FTEMP_LO(%a0) # lo(man) is now zero 22351 22351 22352 mov.l %d2, %d0 22352 mov.l %d2, %d0 # return shift amount 22353 22353 22354 mov.l (%sp)+, %d3 22354 mov.l (%sp)+, %d3 # restore temp regs 22355 mov.l (%sp)+, %d2 22355 mov.l (%sp)+, %d2 22356 22356 22357 rts 22357 rts 22358 22358 22359 ############################################ 22359 ######################################################################### 22360 # unnorm_fix(): - changes an UNNORM to one o 22360 # unnorm_fix(): - changes an UNNORM to one of NORM, DENORM, or ZERO # 22361 # - returns corresponding opty 22361 # - returns corresponding optype tag # 22362 # 22362 # # 22363 # XDEF ************************************* 22363 # XDEF **************************************************************** # 22364 # unnorm_fix() 22364 # unnorm_fix() # 22365 # 22365 # # 22366 # XREF ************************************* 22366 # XREF **************************************************************** # 22367 # norm() - normalize the mantissa 22367 # norm() - normalize the mantissa # 22368 # 22368 # # 22369 # INPUT ************************************ 22369 # INPUT *************************************************************** # 22370 # a0 = pointer to unnormalized extende 22370 # a0 = pointer to unnormalized extended precision number # 22371 # 22371 # # 22372 # OUTPUT *********************************** 22372 # OUTPUT ************************************************************** # 22373 # d0 = optype tag - is corrected to on 22373 # d0 = optype tag - is corrected to one of NORM, DENORM, or ZERO # 22374 # a0 = input operand has been converte 22374 # a0 = input operand has been converted to a norm, denorm, or # 22375 # zero; both the exponent and man 22375 # zero; both the exponent and mantissa are changed. # 22376 # 22376 # # 22377 ############################################ 22377 ######################################################################### 22378 22378 22379 global unnorm_fix 22379 global unnorm_fix 22380 unnorm_fix: 22380 unnorm_fix: 22381 bfffo FTEMP_HI(%a0){&0:&32 22381 bfffo FTEMP_HI(%a0){&0:&32}, %d0 # how many shifts are needed? 22382 bne.b unnorm_shift 22382 bne.b unnorm_shift # hi(man) is not all zeroes 22383 22383 22384 # 22384 # 22385 # hi(man) is all zeroes so see if any bits i 22385 # hi(man) is all zeroes so see if any bits in lo(man) are set 22386 # 22386 # 22387 unnorm_chk_lo: 22387 unnorm_chk_lo: 22388 bfffo FTEMP_LO(%a0){&0:&32 22388 bfffo FTEMP_LO(%a0){&0:&32}, %d0 # is operand really a zero? 22389 beq.w unnorm_zero 22389 beq.w unnorm_zero # yes 22390 22390 22391 add.w &32, %d0 22391 add.w &32, %d0 # no; fix shift distance 22392 22392 22393 # 22393 # 22394 # d0 = # shifts needed for complete normaliz 22394 # d0 = # shifts needed for complete normalization 22395 # 22395 # 22396 unnorm_shift: 22396 unnorm_shift: 22397 clr.l %d1 22397 clr.l %d1 # clear top word 22398 mov.w FTEMP_EX(%a0), %d1 22398 mov.w FTEMP_EX(%a0), %d1 # extract exponent 22399 and.w &0x7fff, %d1 22399 and.w &0x7fff, %d1 # strip off sgn 22400 22400 22401 cmp.w %d0, %d1 22401 cmp.w %d0, %d1 # will denorm push exp < 0? 22402 bgt.b unnorm_nrm_zero 22402 bgt.b unnorm_nrm_zero # yes; denorm only until exp = 0 22403 22403 22404 # 22404 # 22405 # exponent would not go < 0. Therefore, numb 22405 # exponent would not go < 0. Therefore, number stays normalized 22406 # 22406 # 22407 sub.w %d0, %d1 22407 sub.w %d0, %d1 # shift exponent value 22408 mov.w FTEMP_EX(%a0), %d0 22408 mov.w FTEMP_EX(%a0), %d0 # load old exponent 22409 and.w &0x8000, %d0 22409 and.w &0x8000, %d0 # save old sign 22410 or.w %d0, %d1 22410 or.w %d0, %d1 # {sgn,new exp} 22411 mov.w %d1, FTEMP_EX(%a0) 22411 mov.w %d1, FTEMP_EX(%a0) # insert new exponent 22412 22412 22413 bsr.l norm 22413 bsr.l norm # normalize UNNORM 22414 22414 22415 mov.b &NORM, %d0 22415 mov.b &NORM, %d0 # return new optype tag 22416 rts 22416 rts 22417 22417 22418 # 22418 # 22419 # exponent would go < 0, so only denormalize 22419 # exponent would go < 0, so only denormalize until exp = 0 22420 # 22420 # 22421 unnorm_nrm_zero: 22421 unnorm_nrm_zero: 22422 cmp.b %d1, &32 22422 cmp.b %d1, &32 # is exp <= 32? 22423 bgt.b unnorm_nrm_zero_lrg 22423 bgt.b unnorm_nrm_zero_lrg # no; go handle large exponent 22424 22424 22425 bfextu FTEMP_HI(%a0){%d1:&3 22425 bfextu FTEMP_HI(%a0){%d1:&32}, %d0 # extract new hi(man) 22426 mov.l %d0, FTEMP_HI(%a0) 22426 mov.l %d0, FTEMP_HI(%a0) # save new hi(man) 22427 22427 22428 mov.l FTEMP_LO(%a0), %d0 22428 mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 22429 lsl.l %d1, %d0 22429 lsl.l %d1, %d0 # extract new lo(man) 22430 mov.l %d0, FTEMP_LO(%a0) 22430 mov.l %d0, FTEMP_LO(%a0) # save new lo(man) 22431 22431 22432 and.w &0x8000, FTEMP_EX(%a 22432 and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 22433 22433 22434 mov.b &DENORM, %d0 22434 mov.b &DENORM, %d0 # return new optype tag 22435 rts 22435 rts 22436 22436 22437 # 22437 # 22438 # only mantissa bits set are in lo(man) 22438 # only mantissa bits set are in lo(man) 22439 # 22439 # 22440 unnorm_nrm_zero_lrg: 22440 unnorm_nrm_zero_lrg: 22441 sub.w &32, %d1 22441 sub.w &32, %d1 # adjust shft amt by 32 22442 22442 22443 mov.l FTEMP_LO(%a0), %d0 22443 mov.l FTEMP_LO(%a0), %d0 # fetch old lo(man) 22444 lsl.l %d1, %d0 22444 lsl.l %d1, %d0 # left shift lo(man) 22445 22445 22446 mov.l %d0, FTEMP_HI(%a0) 22446 mov.l %d0, FTEMP_HI(%a0) # store new hi(man) 22447 clr.l FTEMP_LO(%a0) 22447 clr.l FTEMP_LO(%a0) # lo(man) = 0 22448 22448 22449 and.w &0x8000, FTEMP_EX(%a 22449 and.w &0x8000, FTEMP_EX(%a0) # set exp = 0 22450 22450 22451 mov.b &DENORM, %d0 22451 mov.b &DENORM, %d0 # return new optype tag 22452 rts 22452 rts 22453 22453 22454 # 22454 # 22455 # whole mantissa is zero so this UNNORM is a 22455 # whole mantissa is zero so this UNNORM is actually a zero 22456 # 22456 # 22457 unnorm_zero: 22457 unnorm_zero: 22458 and.w &0x8000, FTEMP_EX(%a 22458 and.w &0x8000, FTEMP_EX(%a0) # force exponent to zero 22459 22459 22460 mov.b &ZERO, %d0 22460 mov.b &ZERO, %d0 # fix optype tag 22461 rts 22461 rts 22462 22462 22463 ############################################ 22463 ######################################################################### 22464 # XDEF ************************************* 22464 # XDEF **************************************************************** # 22465 # set_tag_x(): return the optype of th 22465 # set_tag_x(): return the optype of the input ext fp number # 22466 # 22466 # # 22467 # XREF ************************************* 22467 # XREF **************************************************************** # 22468 # None 22468 # None # 22469 # 22469 # # 22470 # INPUT ************************************ 22470 # INPUT *************************************************************** # 22471 # a0 = pointer to extended precision o 22471 # a0 = pointer to extended precision operand # 22472 # 22472 # # 22473 # OUTPUT *********************************** 22473 # OUTPUT ************************************************************** # 22474 # d0 = value of type tag 22474 # d0 = value of type tag # 22475 # one of: NORM, INF, QNAN, SNA 22475 # one of: NORM, INF, QNAN, SNAN, DENORM, UNNORM, ZERO # 22476 # 22476 # # 22477 # ALGORITHM ******************************** 22477 # ALGORITHM *********************************************************** # 22478 # Simply test the exponent, j-bit, and 22478 # Simply test the exponent, j-bit, and mantissa values to # 22479 # determine the type of operand. 22479 # determine the type of operand. # 22480 # If it's an unnormalized zero, alter 22480 # If it's an unnormalized zero, alter the operand and force it # 22481 # to be a normal zero. 22481 # to be a normal zero. # 22482 # 22482 # # 22483 ############################################ 22483 ######################################################################### 22484 22484 22485 global set_tag_x 22485 global set_tag_x 22486 set_tag_x: 22486 set_tag_x: 22487 mov.w FTEMP_EX(%a0), %d0 22487 mov.w FTEMP_EX(%a0), %d0 # extract exponent 22488 andi.w &0x7fff, %d0 22488 andi.w &0x7fff, %d0 # strip off sign 22489 cmpi.w %d0, &0x7fff 22489 cmpi.w %d0, &0x7fff # is (EXP == MAX)? 22490 beq.b inf_or_nan_x 22490 beq.b inf_or_nan_x 22491 not_inf_or_nan_x: 22491 not_inf_or_nan_x: 22492 btst &0x7,FTEMP_HI(%a0) 22492 btst &0x7,FTEMP_HI(%a0) 22493 beq.b not_norm_x 22493 beq.b not_norm_x 22494 is_norm_x: 22494 is_norm_x: 22495 mov.b &NORM, %d0 22495 mov.b &NORM, %d0 22496 rts 22496 rts 22497 not_norm_x: 22497 not_norm_x: 22498 tst.w %d0 22498 tst.w %d0 # is exponent = 0? 22499 bne.b is_unnorm_x 22499 bne.b is_unnorm_x 22500 not_unnorm_x: 22500 not_unnorm_x: 22501 tst.l FTEMP_HI(%a0) 22501 tst.l FTEMP_HI(%a0) 22502 bne.b is_denorm_x 22502 bne.b is_denorm_x 22503 tst.l FTEMP_LO(%a0) 22503 tst.l FTEMP_LO(%a0) 22504 bne.b is_denorm_x 22504 bne.b is_denorm_x 22505 is_zero_x: 22505 is_zero_x: 22506 mov.b &ZERO, %d0 22506 mov.b &ZERO, %d0 22507 rts 22507 rts 22508 is_denorm_x: 22508 is_denorm_x: 22509 mov.b &DENORM, %d0 22509 mov.b &DENORM, %d0 22510 rts 22510 rts 22511 # must distinguish now "Unnormalized zeroes" 22511 # must distinguish now "Unnormalized zeroes" which we 22512 # must convert to zero. 22512 # must convert to zero. 22513 is_unnorm_x: 22513 is_unnorm_x: 22514 tst.l FTEMP_HI(%a0) 22514 tst.l FTEMP_HI(%a0) 22515 bne.b is_unnorm_reg_x 22515 bne.b is_unnorm_reg_x 22516 tst.l FTEMP_LO(%a0) 22516 tst.l FTEMP_LO(%a0) 22517 bne.b is_unnorm_reg_x 22517 bne.b is_unnorm_reg_x 22518 # it's an "unnormalized zero". let's convert 22518 # it's an "unnormalized zero". let's convert it to an actual zero... 22519 andi.w &0x8000,FTEMP_EX(%a0 22519 andi.w &0x8000,FTEMP_EX(%a0) # clear exponent 22520 mov.b &ZERO, %d0 22520 mov.b &ZERO, %d0 22521 rts 22521 rts 22522 is_unnorm_reg_x: 22522 is_unnorm_reg_x: 22523 mov.b &UNNORM, %d0 22523 mov.b &UNNORM, %d0 22524 rts 22524 rts 22525 inf_or_nan_x: 22525 inf_or_nan_x: 22526 tst.l FTEMP_LO(%a0) 22526 tst.l FTEMP_LO(%a0) 22527 bne.b is_nan_x 22527 bne.b is_nan_x 22528 mov.l FTEMP_HI(%a0), %d0 22528 mov.l FTEMP_HI(%a0), %d0 22529 and.l &0x7fffffff, %d0 22529 and.l &0x7fffffff, %d0 # msb is a don't care! 22530 bne.b is_nan_x 22530 bne.b is_nan_x 22531 is_inf_x: 22531 is_inf_x: 22532 mov.b &INF, %d0 22532 mov.b &INF, %d0 22533 rts 22533 rts 22534 is_nan_x: 22534 is_nan_x: 22535 btst &0x6, FTEMP_HI(%a0) 22535 btst &0x6, FTEMP_HI(%a0) 22536 beq.b is_snan_x 22536 beq.b is_snan_x 22537 mov.b &QNAN, %d0 22537 mov.b &QNAN, %d0 22538 rts 22538 rts 22539 is_snan_x: 22539 is_snan_x: 22540 mov.b &SNAN, %d0 22540 mov.b &SNAN, %d0 22541 rts 22541 rts 22542 22542 22543 ############################################ 22543 ######################################################################### 22544 # XDEF ************************************* 22544 # XDEF **************************************************************** # 22545 # set_tag_d(): return the optype of th 22545 # set_tag_d(): return the optype of the input dbl fp number # 22546 # 22546 # # 22547 # XREF ************************************* 22547 # XREF **************************************************************** # 22548 # None 22548 # None # 22549 # 22549 # # 22550 # INPUT ************************************ 22550 # INPUT *************************************************************** # 22551 # a0 = points to double precision oper 22551 # a0 = points to double precision operand # 22552 # 22552 # # 22553 # OUTPUT *********************************** 22553 # OUTPUT ************************************************************** # 22554 # d0 = value of type tag 22554 # d0 = value of type tag # 22555 # one of: NORM, INF, QNAN, SNA 22555 # one of: NORM, INF, QNAN, SNAN, DENORM, ZERO # 22556 # 22556 # # 22557 # ALGORITHM ******************************** 22557 # ALGORITHM *********************************************************** # 22558 # Simply test the exponent, j-bit, and 22558 # Simply test the exponent, j-bit, and mantissa values to # 22559 # determine the type of operand. 22559 # determine the type of operand. # 22560 # 22560 # # 22561 ############################################ 22561 ######################################################################### 22562 22562 22563 global set_tag_d 22563 global set_tag_d 22564 set_tag_d: 22564 set_tag_d: 22565 mov.l FTEMP(%a0), %d0 22565 mov.l FTEMP(%a0), %d0 22566 mov.l %d0, %d1 22566 mov.l %d0, %d1 22567 22567 22568 andi.l &0x7ff00000, %d0 22568 andi.l &0x7ff00000, %d0 22569 beq.b zero_or_denorm_d 22569 beq.b zero_or_denorm_d 22570 22570 22571 cmpi.l %d0, &0x7ff00000 22571 cmpi.l %d0, &0x7ff00000 22572 beq.b inf_or_nan_d 22572 beq.b inf_or_nan_d 22573 22573 22574 is_norm_d: 22574 is_norm_d: 22575 mov.b &NORM, %d0 22575 mov.b &NORM, %d0 22576 rts 22576 rts 22577 zero_or_denorm_d: 22577 zero_or_denorm_d: 22578 and.l &0x000fffff, %d1 22578 and.l &0x000fffff, %d1 22579 bne is_denorm_d 22579 bne is_denorm_d 22580 tst.l 4+FTEMP(%a0) 22580 tst.l 4+FTEMP(%a0) 22581 bne is_denorm_d 22581 bne is_denorm_d 22582 is_zero_d: 22582 is_zero_d: 22583 mov.b &ZERO, %d0 22583 mov.b &ZERO, %d0 22584 rts 22584 rts 22585 is_denorm_d: 22585 is_denorm_d: 22586 mov.b &DENORM, %d0 22586 mov.b &DENORM, %d0 22587 rts 22587 rts 22588 inf_or_nan_d: 22588 inf_or_nan_d: 22589 and.l &0x000fffff, %d1 22589 and.l &0x000fffff, %d1 22590 bne is_nan_d 22590 bne is_nan_d 22591 tst.l 4+FTEMP(%a0) 22591 tst.l 4+FTEMP(%a0) 22592 bne is_nan_d 22592 bne is_nan_d 22593 is_inf_d: 22593 is_inf_d: 22594 mov.b &INF, %d0 22594 mov.b &INF, %d0 22595 rts 22595 rts 22596 is_nan_d: 22596 is_nan_d: 22597 btst &19, %d1 22597 btst &19, %d1 22598 bne is_qnan_d 22598 bne is_qnan_d 22599 is_snan_d: 22599 is_snan_d: 22600 mov.b &SNAN, %d0 22600 mov.b &SNAN, %d0 22601 rts 22601 rts 22602 is_qnan_d: 22602 is_qnan_d: 22603 mov.b &QNAN, %d0 22603 mov.b &QNAN, %d0 22604 rts 22604 rts 22605 22605 22606 ############################################ 22606 ######################################################################### 22607 # XDEF ************************************* 22607 # XDEF **************************************************************** # 22608 # set_tag_s(): return the optype of th 22608 # set_tag_s(): return the optype of the input sgl fp number # 22609 # 22609 # # 22610 # XREF ************************************* 22610 # XREF **************************************************************** # 22611 # None 22611 # None # 22612 # 22612 # # 22613 # INPUT ************************************ 22613 # INPUT *************************************************************** # 22614 # a0 = pointer to single precision ope 22614 # a0 = pointer to single precision operand # 22615 # 22615 # # 22616 # OUTPUT *********************************** 22616 # OUTPUT ************************************************************** # 22617 # d0 = value of type tag 22617 # d0 = value of type tag # 22618 # one of: NORM, INF, QNAN, SNA 22618 # one of: NORM, INF, QNAN, SNAN, DENORM, ZERO # 22619 # 22619 # # 22620 # ALGORITHM ******************************** 22620 # ALGORITHM *********************************************************** # 22621 # Simply test the exponent, j-bit, and 22621 # Simply test the exponent, j-bit, and mantissa values to # 22622 # determine the type of operand. 22622 # determine the type of operand. # 22623 # 22623 # # 22624 ############################################ 22624 ######################################################################### 22625 22625 22626 global set_tag_s 22626 global set_tag_s 22627 set_tag_s: 22627 set_tag_s: 22628 mov.l FTEMP(%a0), %d0 22628 mov.l FTEMP(%a0), %d0 22629 mov.l %d0, %d1 22629 mov.l %d0, %d1 22630 22630 22631 andi.l &0x7f800000, %d0 22631 andi.l &0x7f800000, %d0 22632 beq.b zero_or_denorm_s 22632 beq.b zero_or_denorm_s 22633 22633 22634 cmpi.l %d0, &0x7f800000 22634 cmpi.l %d0, &0x7f800000 22635 beq.b inf_or_nan_s 22635 beq.b inf_or_nan_s 22636 22636 22637 is_norm_s: 22637 is_norm_s: 22638 mov.b &NORM, %d0 22638 mov.b &NORM, %d0 22639 rts 22639 rts 22640 zero_or_denorm_s: 22640 zero_or_denorm_s: 22641 and.l &0x007fffff, %d1 22641 and.l &0x007fffff, %d1 22642 bne is_denorm_s 22642 bne is_denorm_s 22643 is_zero_s: 22643 is_zero_s: 22644 mov.b &ZERO, %d0 22644 mov.b &ZERO, %d0 22645 rts 22645 rts 22646 is_denorm_s: 22646 is_denorm_s: 22647 mov.b &DENORM, %d0 22647 mov.b &DENORM, %d0 22648 rts 22648 rts 22649 inf_or_nan_s: 22649 inf_or_nan_s: 22650 and.l &0x007fffff, %d1 22650 and.l &0x007fffff, %d1 22651 bne is_nan_s 22651 bne is_nan_s 22652 is_inf_s: 22652 is_inf_s: 22653 mov.b &INF, %d0 22653 mov.b &INF, %d0 22654 rts 22654 rts 22655 is_nan_s: 22655 is_nan_s: 22656 btst &22, %d1 22656 btst &22, %d1 22657 bne is_qnan_s 22657 bne is_qnan_s 22658 is_snan_s: 22658 is_snan_s: 22659 mov.b &SNAN, %d0 22659 mov.b &SNAN, %d0 22660 rts 22660 rts 22661 is_qnan_s: 22661 is_qnan_s: 22662 mov.b &QNAN, %d0 22662 mov.b &QNAN, %d0 22663 rts 22663 rts 22664 22664 22665 ############################################ 22665 ######################################################################### 22666 # XDEF ************************************* 22666 # XDEF **************************************************************** # 22667 # unf_res(): routine to produce defaul 22667 # unf_res(): routine to produce default underflow result of a # 22668 # scaled extended precision 22668 # scaled extended precision number; this is used by # 22669 # fadd/fdiv/fmul/etc. emula 22669 # fadd/fdiv/fmul/etc. emulation routines. # 22670 # unf_res4(): same as above but for fs 22670 # unf_res4(): same as above but for fsglmul/fsgldiv which use # 22671 # single round prec and ex 22671 # single round prec and extended prec mode. # 22672 # 22672 # # 22673 # XREF ************************************* 22673 # XREF **************************************************************** # 22674 # _denorm() - denormalize according to 22674 # _denorm() - denormalize according to scale factor # 22675 # _round() - round denormalized number 22675 # _round() - round denormalized number according to rnd prec # 22676 # 22676 # # 22677 # INPUT ************************************ 22677 # INPUT *************************************************************** # 22678 # a0 = pointer to extended precison op 22678 # a0 = pointer to extended precison operand # 22679 # d0 = scale factor 22679 # d0 = scale factor # 22680 # d1 = rounding precision/mode 22680 # d1 = rounding precision/mode # 22681 # 22681 # # 22682 # OUTPUT *********************************** 22682 # OUTPUT ************************************************************** # 22683 # a0 = pointer to default underflow re 22683 # a0 = pointer to default underflow result in extended precision # 22684 # d0.b = result FPSR_cc which caller m 22684 # d0.b = result FPSR_cc which caller may or may not want to save # 22685 # 22685 # # 22686 # ALGORITHM ******************************** 22686 # ALGORITHM *********************************************************** # 22687 # Convert the input operand to "intern 22687 # Convert the input operand to "internal format" which means the # 22688 # exponent is extended to 16 bits and the si 22688 # exponent is extended to 16 bits and the sign is stored in the unused # 22689 # portion of the extended precison operand. 22689 # portion of the extended precison operand. Denormalize the number # 22690 # according to the scale factor passed in d0 22690 # according to the scale factor passed in d0. Then, round the # 22691 # denormalized result. 22691 # denormalized result. # 22692 # Set the FPSR_exc bits as appropriate 22692 # Set the FPSR_exc bits as appropriate but return the cc bits in # 22693 # d0 in case the caller doesn't want to save 22693 # d0 in case the caller doesn't want to save them (as is the case for # 22694 # fmove out). 22694 # fmove out). # 22695 # unf_res4() for fsglmul/fsgldiv force 22695 # unf_res4() for fsglmul/fsgldiv forces the denorm to extended # 22696 # precision and the rounding mode to single. 22696 # precision and the rounding mode to single. # 22697 # 22697 # # 22698 ############################################ 22698 ######################################################################### 22699 global unf_res 22699 global unf_res 22700 unf_res: 22700 unf_res: 22701 mov.l %d1, -(%sp) 22701 mov.l %d1, -(%sp) # save rnd prec,mode on stack 22702 22702 22703 btst &0x7, FTEMP_EX(%a0) 22703 btst &0x7, FTEMP_EX(%a0) # make "internal" format 22704 sne FTEMP_SGN(%a0) 22704 sne FTEMP_SGN(%a0) 22705 22705 22706 mov.w FTEMP_EX(%a0), %d1 22706 mov.w FTEMP_EX(%a0), %d1 # extract exponent 22707 and.w &0x7fff, %d1 22707 and.w &0x7fff, %d1 22708 sub.w %d0, %d1 22708 sub.w %d0, %d1 22709 mov.w %d1, FTEMP_EX(%a0) 22709 mov.w %d1, FTEMP_EX(%a0) # insert 16 bit exponent 22710 22710 22711 mov.l %a0, -(%sp) 22711 mov.l %a0, -(%sp) # save operand ptr during calls 22712 22712 22713 mov.l 0x4(%sp),%d0 22713 mov.l 0x4(%sp),%d0 # pass rnd prec. 22714 andi.w &0x00c0,%d0 22714 andi.w &0x00c0,%d0 22715 lsr.w &0x4,%d0 22715 lsr.w &0x4,%d0 22716 bsr.l _denorm 22716 bsr.l _denorm # denorm result 22717 22717 22718 mov.l (%sp),%a0 22718 mov.l (%sp),%a0 22719 mov.w 0x6(%sp),%d1 22719 mov.w 0x6(%sp),%d1 # load prec:mode into %d1 22720 andi.w &0xc0,%d1 22720 andi.w &0xc0,%d1 # extract rnd prec 22721 lsr.w &0x4,%d1 22721 lsr.w &0x4,%d1 22722 swap %d1 22722 swap %d1 22723 mov.w 0x6(%sp),%d1 22723 mov.w 0x6(%sp),%d1 22724 andi.w &0x30,%d1 22724 andi.w &0x30,%d1 22725 lsr.w &0x4,%d1 22725 lsr.w &0x4,%d1 22726 bsr.l _round 22726 bsr.l _round # round the denorm 22727 22727 22728 mov.l (%sp)+, %a0 22728 mov.l (%sp)+, %a0 22729 22729 22730 # result is now rounded properly. convert ba 22730 # result is now rounded properly. convert back to normal format 22731 bclr &0x7, FTEMP_EX(%a0) 22731 bclr &0x7, FTEMP_EX(%a0) # clear sgn first; may have residue 22732 tst.b FTEMP_SGN(%a0) 22732 tst.b FTEMP_SGN(%a0) # is "internal result" sign set? 22733 beq.b unf_res_chkifzero 22733 beq.b unf_res_chkifzero # no; result is positive 22734 bset &0x7, FTEMP_EX(%a0) 22734 bset &0x7, FTEMP_EX(%a0) # set result sgn 22735 clr.b FTEMP_SGN(%a0) 22735 clr.b FTEMP_SGN(%a0) # clear temp sign 22736 22736 22737 # the number may have become zero after roun 22737 # the number may have become zero after rounding. set ccodes accordingly. 22738 unf_res_chkifzero: 22738 unf_res_chkifzero: 22739 clr.l %d0 22739 clr.l %d0 22740 tst.l FTEMP_HI(%a0) 22740 tst.l FTEMP_HI(%a0) # is value now a zero? 22741 bne.b unf_res_cont 22741 bne.b unf_res_cont # no 22742 tst.l FTEMP_LO(%a0) 22742 tst.l FTEMP_LO(%a0) 22743 bne.b unf_res_cont 22743 bne.b unf_res_cont # no 22744 # bset &z_bit, FPSR_CC(%a6) 22744 # bset &z_bit, FPSR_CC(%a6) # yes; set zero ccode bit 22745 bset &z_bit, %d0 22745 bset &z_bit, %d0 # yes; set zero ccode bit 22746 22746 22747 unf_res_cont: 22747 unf_res_cont: 22748 22748 22749 # 22749 # 22750 # can inex1 also be set along with unfl and 22750 # can inex1 also be set along with unfl and inex2??? 22751 # 22751 # 22752 # we know that underflow has occurred. aunfl 22752 # we know that underflow has occurred. aunfl should be set if INEX2 is also set. 22753 # 22753 # 22754 btst &inex2_bit, FPSR_EXC 22754 btst &inex2_bit, FPSR_EXCEPT(%a6) # is INEX2 set? 22755 beq.b unf_res_end 22755 beq.b unf_res_end # no 22756 bset &aunfl_bit, FPSR_AEX 22756 bset &aunfl_bit, FPSR_AEXCEPT(%a6) # yes; set aunfl 22757 22757 22758 unf_res_end: 22758 unf_res_end: 22759 add.l &0x4, %sp 22759 add.l &0x4, %sp # clear stack 22760 rts 22760 rts 22761 22761 22762 # unf_res() for fsglmul() and fsgldiv(). 22762 # unf_res() for fsglmul() and fsgldiv(). 22763 global unf_res4 22763 global unf_res4 22764 unf_res4: 22764 unf_res4: 22765 mov.l %d1,-(%sp) 22765 mov.l %d1,-(%sp) # save rnd prec,mode on stack 22766 22766 22767 btst &0x7,FTEMP_EX(%a0) 22767 btst &0x7,FTEMP_EX(%a0) # make "internal" format 22768 sne FTEMP_SGN(%a0) 22768 sne FTEMP_SGN(%a0) 22769 22769 22770 mov.w FTEMP_EX(%a0),%d1 22770 mov.w FTEMP_EX(%a0),%d1 # extract exponent 22771 and.w &0x7fff,%d1 22771 and.w &0x7fff,%d1 22772 sub.w %d0,%d1 22772 sub.w %d0,%d1 22773 mov.w %d1,FTEMP_EX(%a0) 22773 mov.w %d1,FTEMP_EX(%a0) # insert 16 bit exponent 22774 22774 22775 mov.l %a0,-(%sp) 22775 mov.l %a0,-(%sp) # save operand ptr during calls 22776 22776 22777 clr.l %d0 22777 clr.l %d0 # force rnd prec = ext 22778 bsr.l _denorm 22778 bsr.l _denorm # denorm result 22779 22779 22780 mov.l (%sp),%a0 22780 mov.l (%sp),%a0 22781 mov.w &s_mode,%d1 22781 mov.w &s_mode,%d1 # force rnd prec = sgl 22782 swap %d1 22782 swap %d1 22783 mov.w 0x6(%sp),%d1 22783 mov.w 0x6(%sp),%d1 # load rnd mode 22784 andi.w &0x30,%d1 22784 andi.w &0x30,%d1 # extract rnd prec 22785 lsr.w &0x4,%d1 22785 lsr.w &0x4,%d1 22786 bsr.l _round 22786 bsr.l _round # round the denorm 22787 22787 22788 mov.l (%sp)+,%a0 22788 mov.l (%sp)+,%a0 22789 22789 22790 # result is now rounded properly. convert ba 22790 # result is now rounded properly. convert back to normal format 22791 bclr &0x7,FTEMP_EX(%a0) 22791 bclr &0x7,FTEMP_EX(%a0) # clear sgn first; may have residue 22792 tst.b FTEMP_SGN(%a0) 22792 tst.b FTEMP_SGN(%a0) # is "internal result" sign set? 22793 beq.b unf_res4_chkifzero 22793 beq.b unf_res4_chkifzero # no; result is positive 22794 bset &0x7,FTEMP_EX(%a0) 22794 bset &0x7,FTEMP_EX(%a0) # set result sgn 22795 clr.b FTEMP_SGN(%a0) 22795 clr.b FTEMP_SGN(%a0) # clear temp sign 22796 22796 22797 # the number may have become zero after roun 22797 # the number may have become zero after rounding. set ccodes accordingly. 22798 unf_res4_chkifzero: 22798 unf_res4_chkifzero: 22799 clr.l %d0 22799 clr.l %d0 22800 tst.l FTEMP_HI(%a0) 22800 tst.l FTEMP_HI(%a0) # is value now a zero? 22801 bne.b unf_res4_cont 22801 bne.b unf_res4_cont # no 22802 tst.l FTEMP_LO(%a0) 22802 tst.l FTEMP_LO(%a0) 22803 bne.b unf_res4_cont 22803 bne.b unf_res4_cont # no 22804 # bset &z_bit,FPSR_CC(%a6) 22804 # bset &z_bit,FPSR_CC(%a6) # yes; set zero ccode bit 22805 bset &z_bit,%d0 22805 bset &z_bit,%d0 # yes; set zero ccode bit 22806 22806 22807 unf_res4_cont: 22807 unf_res4_cont: 22808 22808 22809 # 22809 # 22810 # can inex1 also be set along with unfl and 22810 # can inex1 also be set along with unfl and inex2??? 22811 # 22811 # 22812 # we know that underflow has occurred. aunfl 22812 # we know that underflow has occurred. aunfl should be set if INEX2 is also set. 22813 # 22813 # 22814 btst &inex2_bit,FPSR_EXCE 22814 btst &inex2_bit,FPSR_EXCEPT(%a6) # is INEX2 set? 22815 beq.b unf_res4_end 22815 beq.b unf_res4_end # no 22816 bset &aunfl_bit,FPSR_AEXC 22816 bset &aunfl_bit,FPSR_AEXCEPT(%a6) # yes; set aunfl 22817 22817 22818 unf_res4_end: 22818 unf_res4_end: 22819 add.l &0x4,%sp 22819 add.l &0x4,%sp # clear stack 22820 rts 22820 rts 22821 22821 22822 ############################################ 22822 ######################################################################### 22823 # XDEF ************************************* 22823 # XDEF **************************************************************** # 22824 # ovf_res(): routine to produce the de 22824 # ovf_res(): routine to produce the default overflow result of # 22825 # an overflowing number. 22825 # an overflowing number. # 22826 # ovf_res2(): same as above but the rn 22826 # ovf_res2(): same as above but the rnd mode/prec are passed # 22827 # differently. 22827 # differently. # 22828 # 22828 # # 22829 # XREF ************************************* 22829 # XREF **************************************************************** # 22830 # none 22830 # none # 22831 # 22831 # # 22832 # INPUT ************************************ 22832 # INPUT *************************************************************** # 22833 # d1.b = '-1' => (-); '0' => (+) 22833 # d1.b = '-1' => (-); '0' => (+) # 22834 # ovf_res(): 22834 # ovf_res(): # 22835 # d0 = rnd mode/prec 22835 # d0 = rnd mode/prec # 22836 # ovf_res2(): 22836 # ovf_res2(): # 22837 # hi(d0) = rnd prec 22837 # hi(d0) = rnd prec # 22838 # lo(d0) = rnd mode 22838 # lo(d0) = rnd mode # 22839 # 22839 # # 22840 # OUTPUT *********************************** 22840 # OUTPUT ************************************************************** # 22841 # a0 = points to extended precisi 22841 # a0 = points to extended precision result # 22842 # d0.b = condition code bits 22842 # d0.b = condition code bits # 22843 # 22843 # # 22844 # ALGORITHM ******************************** 22844 # ALGORITHM *********************************************************** # 22845 # The default overflow result can be d 22845 # The default overflow result can be determined by the sign of # 22846 # the result and the rounding mode/prec in e 22846 # the result and the rounding mode/prec in effect. These bits are # 22847 # concatenated together to create an index i 22847 # concatenated together to create an index into the default result # 22848 # table. A pointer to the correct result is 22848 # table. A pointer to the correct result is returned in a0. The # 22849 # resulting condition codes are returned in 22849 # resulting condition codes are returned in d0 in case the caller # 22850 # doesn't want FPSR_cc altered (as is the ca 22850 # doesn't want FPSR_cc altered (as is the case for fmove out). # 22851 # 22851 # # 22852 ############################################ 22852 ######################################################################### 22853 22853 22854 global ovf_res 22854 global ovf_res 22855 ovf_res: 22855 ovf_res: 22856 andi.w &0x10,%d1 22856 andi.w &0x10,%d1 # keep result sign 22857 lsr.b &0x4,%d0 22857 lsr.b &0x4,%d0 # shift prec/mode 22858 or.b %d0,%d1 22858 or.b %d0,%d1 # concat the two 22859 mov.w %d1,%d0 22859 mov.w %d1,%d0 # make a copy 22860 lsl.b &0x1,%d1 22860 lsl.b &0x1,%d1 # multiply d1 by 2 22861 bra.b ovf_res_load 22861 bra.b ovf_res_load 22862 22862 22863 global ovf_res2 22863 global ovf_res2 22864 ovf_res2: 22864 ovf_res2: 22865 and.w &0x10, %d1 22865 and.w &0x10, %d1 # keep result sign 22866 or.b %d0, %d1 22866 or.b %d0, %d1 # insert rnd mode 22867 swap %d0 22867 swap %d0 22868 or.b %d0, %d1 22868 or.b %d0, %d1 # insert rnd prec 22869 mov.w %d1, %d0 22869 mov.w %d1, %d0 # make a copy 22870 lsl.b &0x1, %d1 22870 lsl.b &0x1, %d1 # shift left by 1 22871 22871 22872 # 22872 # 22873 # use the rounding mode, precision, and resu 22873 # use the rounding mode, precision, and result sign as in index into the 22874 # two tables below to fetch the default resu 22874 # two tables below to fetch the default result and the result ccodes. 22875 # 22875 # 22876 ovf_res_load: 22876 ovf_res_load: 22877 mov.b (tbl_ovfl_cc.b,%pc,% 22877 mov.b (tbl_ovfl_cc.b,%pc,%d0.w*1), %d0 # fetch result ccodes 22878 lea (tbl_ovfl_result.b,% 22878 lea (tbl_ovfl_result.b,%pc,%d1.w*8), %a0 # return result ptr 22879 22879 22880 rts 22880 rts 22881 22881 22882 tbl_ovfl_cc: 22882 tbl_ovfl_cc: 22883 byte 0x2, 0x0, 0x0, 0x2 22883 byte 0x2, 0x0, 0x0, 0x2 22884 byte 0x2, 0x0, 0x0, 0x2 22884 byte 0x2, 0x0, 0x0, 0x2 22885 byte 0x2, 0x0, 0x0, 0x2 22885 byte 0x2, 0x0, 0x0, 0x2 22886 byte 0x0, 0x0, 0x0, 0x0 22886 byte 0x0, 0x0, 0x0, 0x0 22887 byte 0x2+0x8, 0x8, 0x2+0x 22887 byte 0x2+0x8, 0x8, 0x2+0x8, 0x8 22888 byte 0x2+0x8, 0x8, 0x2+0x 22888 byte 0x2+0x8, 0x8, 0x2+0x8, 0x8 22889 byte 0x2+0x8, 0x8, 0x2+0x 22889 byte 0x2+0x8, 0x8, 0x2+0x8, 0x8 22890 22890 22891 tbl_ovfl_result: 22891 tbl_ovfl_result: 22892 long 0x7fff0000,0x0000000 22892 long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN 22893 long 0x7ffe0000,0xfffffff 22893 long 0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RZ 22894 long 0x7ffe0000,0xfffffff 22894 long 0x7ffe0000,0xffffffff,0xffffffff,0x00000000 # +EXT; RM 22895 long 0x7fff0000,0x0000000 22895 long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP 22896 22896 22897 long 0x7fff0000,0x0000000 22897 long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN 22898 long 0x407e0000,0xffffff0 22898 long 0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RZ 22899 long 0x407e0000,0xffffff0 22899 long 0x407e0000,0xffffff00,0x00000000,0x00000000 # +SGL; RM 22900 long 0x7fff0000,0x0000000 22900 long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP 22901 22901 22902 long 0x7fff0000,0x0000000 22902 long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RN 22903 long 0x43fe0000,0xfffffff 22903 long 0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RZ 22904 long 0x43fe0000,0xfffffff 22904 long 0x43fe0000,0xffffffff,0xfffff800,0x00000000 # +DBL; RM 22905 long 0x7fff0000,0x0000000 22905 long 0x7fff0000,0x00000000,0x00000000,0x00000000 # +INF; RP 22906 22906 22907 long 0x00000000,0x0000000 22907 long 0x00000000,0x00000000,0x00000000,0x00000000 22908 long 0x00000000,0x0000000 22908 long 0x00000000,0x00000000,0x00000000,0x00000000 22909 long 0x00000000,0x0000000 22909 long 0x00000000,0x00000000,0x00000000,0x00000000 22910 long 0x00000000,0x0000000 22910 long 0x00000000,0x00000000,0x00000000,0x00000000 22911 22911 22912 long 0xffff0000,0x0000000 22912 long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN 22913 long 0xfffe0000,0xfffffff 22913 long 0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RZ 22914 long 0xffff0000,0x0000000 22914 long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM 22915 long 0xfffe0000,0xfffffff 22915 long 0xfffe0000,0xffffffff,0xffffffff,0x00000000 # -EXT; RP 22916 22916 22917 long 0xffff0000,0x0000000 22917 long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN 22918 long 0xc07e0000,0xffffff0 22918 long 0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RZ 22919 long 0xffff0000,0x0000000 22919 long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM 22920 long 0xc07e0000,0xffffff0 22920 long 0xc07e0000,0xffffff00,0x00000000,0x00000000 # -SGL; RP 22921 22921 22922 long 0xffff0000,0x0000000 22922 long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RN 22923 long 0xc3fe0000,0xfffffff 22923 long 0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RZ 22924 long 0xffff0000,0x0000000 22924 long 0xffff0000,0x00000000,0x00000000,0x00000000 # -INF; RM 22925 long 0xc3fe0000,0xfffffff 22925 long 0xc3fe0000,0xffffffff,0xfffff800,0x00000000 # -DBL; RP 22926 22926 22927 ############################################ 22927 ######################################################################### 22928 # XDEF ************************************* 22928 # XDEF **************************************************************** # 22929 # get_packed(): fetch a packed operand 22929 # get_packed(): fetch a packed operand from memory and then # 22930 # convert it to a floati 22930 # convert it to a floating-point binary number. # 22931 # 22931 # # 22932 # XREF ************************************* 22932 # XREF **************************************************************** # 22933 # _dcalc_ea() - calculate the correct 22933 # _dcalc_ea() - calculate the correct <ea> # 22934 # _mem_read() - fetch the packed opera 22934 # _mem_read() - fetch the packed operand from memory # 22935 # facc_in_x() - the fetch failed so ju 22935 # facc_in_x() - the fetch failed so jump to special exit code # 22936 # decbin() - convert packed to bina 22936 # decbin() - convert packed to binary extended precision # 22937 # 22937 # # 22938 # INPUT ************************************ 22938 # INPUT *************************************************************** # 22939 # None 22939 # None # 22940 # 22940 # # 22941 # OUTPUT *********************************** 22941 # OUTPUT ************************************************************** # 22942 # If no failure on _mem_read(): 22942 # If no failure on _mem_read(): # 22943 # FP_SRC(a6) = packed operand now as a 22943 # FP_SRC(a6) = packed operand now as a binary FP number # 22944 # 22944 # # 22945 # ALGORITHM ******************************** 22945 # ALGORITHM *********************************************************** # 22946 # Get the correct <ea> which is the va 22946 # Get the correct <ea> which is the value on the exception stack # 22947 # frame w/ maybe a correction factor if the 22947 # frame w/ maybe a correction factor if the <ea> is -(an) or (an)+. # 22948 # Then, fetch the operand from memory. If th 22948 # Then, fetch the operand from memory. If the fetch fails, exit # 22949 # through facc_in_x(). 22949 # through facc_in_x(). # 22950 # If the packed operand is a ZERO,NAN, 22950 # If the packed operand is a ZERO,NAN, or INF, convert it to # 22951 # its binary representation here. Else, call 22951 # its binary representation here. Else, call decbin() which will # 22952 # convert the packed value to an extended pr 22952 # convert the packed value to an extended precision binary value. # 22953 # 22953 # # 22954 ############################################ 22954 ######################################################################### 22955 22955 22956 # the stacked <ea> for packed is correct exc 22956 # the stacked <ea> for packed is correct except for -(An). 22957 # the base reg must be updated for both -(An 22957 # the base reg must be updated for both -(An) and (An)+. 22958 global get_packed 22958 global get_packed 22959 get_packed: 22959 get_packed: 22960 mov.l &0xc,%d0 22960 mov.l &0xc,%d0 # packed is 12 bytes 22961 bsr.l _dcalc_ea 22961 bsr.l _dcalc_ea # fetch <ea>; correct An 22962 22962 22963 lea FP_SRC(%a6),%a1 22963 lea FP_SRC(%a6),%a1 # pass: ptr to super dst 22964 mov.l &0xc,%d0 22964 mov.l &0xc,%d0 # pass: 12 bytes 22965 bsr.l _dmem_read 22965 bsr.l _dmem_read # read packed operand 22966 22966 22967 tst.l %d1 22967 tst.l %d1 # did dfetch fail? 22968 bne.l facc_in_x 22968 bne.l facc_in_x # yes 22969 22969 22970 # The packed operand is an INF or a NAN if t 22970 # The packed operand is an INF or a NAN if the exponent field is all ones. 22971 bfextu FP_SRC(%a6){&1:&15}, 22971 bfextu FP_SRC(%a6){&1:&15},%d0 # get exp 22972 cmpi.w %d0,&0x7fff 22972 cmpi.w %d0,&0x7fff # INF or NAN? 22973 bne.b gp_try_zero 22973 bne.b gp_try_zero # no 22974 rts 22974 rts # operand is an INF or NAN 22975 22975 22976 # The packed operand is a zero if the mantis 22976 # The packed operand is a zero if the mantissa is all zero, else it's 22977 # a normal packed op. 22977 # a normal packed op. 22978 gp_try_zero: 22978 gp_try_zero: 22979 mov.b 3+FP_SRC(%a6),%d0 22979 mov.b 3+FP_SRC(%a6),%d0 # get byte 4 22980 andi.b &0x0f,%d0 22980 andi.b &0x0f,%d0 # clear all but last nybble 22981 bne.b gp_not_spec 22981 bne.b gp_not_spec # not a zero 22982 tst.l FP_SRC_HI(%a6) 22982 tst.l FP_SRC_HI(%a6) # is lw 2 zero? 22983 bne.b gp_not_spec 22983 bne.b gp_not_spec # not a zero 22984 tst.l FP_SRC_LO(%a6) 22984 tst.l FP_SRC_LO(%a6) # is lw 3 zero? 22985 bne.b gp_not_spec 22985 bne.b gp_not_spec # not a zero 22986 rts 22986 rts # operand is a ZERO 22987 gp_not_spec: 22987 gp_not_spec: 22988 lea FP_SRC(%a6),%a0 22988 lea FP_SRC(%a6),%a0 # pass: ptr to packed op 22989 bsr.l decbin 22989 bsr.l decbin # convert to extended 22990 fmovm.x &0x80,FP_SRC(%a6) 22990 fmovm.x &0x80,FP_SRC(%a6) # make this the srcop 22991 rts 22991 rts 22992 22992 22993 ############################################ 22993 ######################################################################### 22994 # decbin(): Converts normalized packed bcd v 22994 # decbin(): Converts normalized packed bcd value pointed to by register # 22995 # a0 to extended-precision value i 22995 # a0 to extended-precision value in fp0. # 22996 # 22996 # # 22997 # INPUT ************************************ 22997 # INPUT *************************************************************** # 22998 # a0 = pointer to normalized packed bc 22998 # a0 = pointer to normalized packed bcd value # 22999 # 22999 # # 23000 # OUTPUT *********************************** 23000 # OUTPUT ************************************************************** # 23001 # fp0 = exact fp representation of the 23001 # fp0 = exact fp representation of the packed bcd value. # 23002 # 23002 # # 23003 # ALGORITHM ******************************** 23003 # ALGORITHM *********************************************************** # 23004 # Expected is a normal bcd (i.e. non-e 23004 # Expected is a normal bcd (i.e. non-exceptional; all inf, zero, # 23005 # and NaN operands are dispatched with 23005 # and NaN operands are dispatched without entering this routine) # 23006 # value in 68881/882 format at locatio 23006 # value in 68881/882 format at location (a0). # 23007 # 23007 # # 23008 # A1. Convert the bcd exponent to bina 23008 # A1. Convert the bcd exponent to binary by successive adds and # 23009 # muls. Set the sign according to SE. 23009 # muls. Set the sign according to SE. Subtract 16 to compensate # 23010 # for the mantissa which is to be inte 23010 # for the mantissa which is to be interpreted as 17 integer # 23011 # digits, rather than 1 integer and 16 23011 # digits, rather than 1 integer and 16 fraction digits. # 23012 # Note: this operation can never overf 23012 # Note: this operation can never overflow. # 23013 # 23013 # # 23014 # A2. Convert the bcd mantissa to bina 23014 # A2. Convert the bcd mantissa to binary by successive # 23015 # adds and muls in FP0. Set the sign a 23015 # adds and muls in FP0. Set the sign according to SM. # 23016 # The mantissa digits will be converte 23016 # The mantissa digits will be converted with the decimal point # 23017 # assumed following the least-signific 23017 # assumed following the least-significant digit. # 23018 # Note: this operation can never overf 23018 # Note: this operation can never overflow. # 23019 # 23019 # # 23020 # A3. Count the number of leading/trai 23020 # A3. Count the number of leading/trailing zeros in the # 23021 # bcd string. If SE is positive, coun 23021 # bcd string. If SE is positive, count the leading zeros; # 23022 # if negative, count the trailing zero 23022 # if negative, count the trailing zeros. Set the adjusted # 23023 # exponent equal to the exponent from 23023 # exponent equal to the exponent from A1 and the zero count # 23024 # added if SM = 1 and subtracted if SM 23024 # added if SM = 1 and subtracted if SM = 0. Scale the # 23025 # mantissa the equivalent of forcing i 23025 # mantissa the equivalent of forcing in the bcd value: # 23026 # 23026 # # 23027 # SM = 0 a non-zero digit in the inte 23027 # SM = 0 a non-zero digit in the integer position # 23028 # SM = 1 a non-zero digit in Mant0, l 23028 # SM = 1 a non-zero digit in Mant0, lsd of the fraction # 23029 # 23029 # # 23030 # this will insure that any value, reg 23030 # this will insure that any value, regardless of its # 23031 # representation (ex. 0.1E2, 1E1, 10E0 23031 # representation (ex. 0.1E2, 1E1, 10E0, 100E-1), is converted # 23032 # consistently. 23032 # consistently. # 23033 # 23033 # # 23034 # A4. Calculate the factor 10^exp in F 23034 # A4. Calculate the factor 10^exp in FP1 using a table of # 23035 # 10^(2^n) values. To reduce the erro 23035 # 10^(2^n) values. To reduce the error in forming factors # 23036 # greater than 10^27, a directed round 23036 # greater than 10^27, a directed rounding scheme is used with # 23037 # tables rounded to RN, RM, and RP, ac 23037 # tables rounded to RN, RM, and RP, according to the table # 23038 # in the comments of the pwrten sectio 23038 # in the comments of the pwrten section. # 23039 # 23039 # # 23040 # A5. Form the final binary number by 23040 # A5. Form the final binary number by scaling the mantissa by # 23041 # the exponent factor. This is done b 23041 # the exponent factor. This is done by multiplying the # 23042 # mantissa in FP0 by the factor in FP1 23042 # mantissa in FP0 by the factor in FP1 if the adjusted # 23043 # exponent sign is positive, and divid 23043 # exponent sign is positive, and dividing FP0 by FP1 if # 23044 # it is negative. 23044 # it is negative. # 23045 # 23045 # # 23046 # Clean up and return. Check if the fi 23046 # Clean up and return. Check if the final mul or div was inexact. # 23047 # If so, set INEX1 in USER_FPSR. 23047 # If so, set INEX1 in USER_FPSR. # 23048 # 23048 # # 23049 ############################################ 23049 ######################################################################### 23050 23050 23051 # 23051 # 23052 # PTENRN, PTENRM, and PTENRP are array 23052 # PTENRN, PTENRM, and PTENRP are arrays of powers of 10 rounded 23053 # to nearest, minus, and plus, respect 23053 # to nearest, minus, and plus, respectively. The tables include 23054 # 10**{1,2,4,8,16,32,64,128,256,512,10 23054 # 10**{1,2,4,8,16,32,64,128,256,512,1024,2048,4096}. No rounding 23055 # is required until the power is great 23055 # is required until the power is greater than 27, however, all 23056 # tables include the first 5 for ease 23056 # tables include the first 5 for ease of indexing. 23057 # 23057 # 23058 RTABLE: 23058 RTABLE: 23059 byte 0,0,0,0 23059 byte 0,0,0,0 23060 byte 2,3,2,3 23060 byte 2,3,2,3 23061 byte 2,3,3,2 23061 byte 2,3,3,2 23062 byte 3,2,2,3 23062 byte 3,2,2,3 23063 23063 23064 set FNIBS,7 23064 set FNIBS,7 23065 set FSTRT,0 23065 set FSTRT,0 23066 23066 23067 set ESTRT,4 23067 set ESTRT,4 23068 set EDIGITS,2 23068 set EDIGITS,2 23069 23069 23070 global decbin 23070 global decbin 23071 decbin: 23071 decbin: 23072 mov.l 0x0(%a0),FP_SCR0_EX( 23072 mov.l 0x0(%a0),FP_SCR0_EX(%a6) # make a copy of input 23073 mov.l 0x4(%a0),FP_SCR0_HI( 23073 mov.l 0x4(%a0),FP_SCR0_HI(%a6) # so we don't alter it 23074 mov.l 0x8(%a0),FP_SCR0_LO( 23074 mov.l 0x8(%a0),FP_SCR0_LO(%a6) 23075 23075 23076 lea FP_SCR0(%a6),%a0 23076 lea FP_SCR0(%a6),%a0 23077 23077 23078 movm.l &0x3c00,-(%sp) 23078 movm.l &0x3c00,-(%sp) # save d2-d5 23079 fmovm.x &0x1,-(%sp) 23079 fmovm.x &0x1,-(%sp) # save fp1 23080 # 23080 # 23081 # Calculate exponent: 23081 # Calculate exponent: 23082 # 1. Copy bcd value in memory for use as a 23082 # 1. Copy bcd value in memory for use as a working copy. 23083 # 2. Calculate absolute value of exponent i 23083 # 2. Calculate absolute value of exponent in d1 by mul and add. 23084 # 3. Correct for exponent sign. 23084 # 3. Correct for exponent sign. 23085 # 4. Subtract 16 to compensate for interpre 23085 # 4. Subtract 16 to compensate for interpreting the mant as all integer digits. 23086 # (i.e., all digits assumed left of the 23086 # (i.e., all digits assumed left of the decimal point.) 23087 # 23087 # 23088 # Register usage: 23088 # Register usage: 23089 # 23089 # 23090 # calc_e: 23090 # calc_e: 23091 # (*) d0: temp digit storage 23091 # (*) d0: temp digit storage 23092 # (*) d1: accumulator for binary expo 23092 # (*) d1: accumulator for binary exponent 23093 # (*) d2: digit count 23093 # (*) d2: digit count 23094 # (*) d3: offset pointer 23094 # (*) d3: offset pointer 23095 # ( ) d4: first word of bcd 23095 # ( ) d4: first word of bcd 23096 # ( ) a0: pointer to working bcd valu 23096 # ( ) a0: pointer to working bcd value 23097 # ( ) a6: pointer to original bcd val 23097 # ( ) a6: pointer to original bcd value 23098 # (*) FP_SCR1: working copy of origin 23098 # (*) FP_SCR1: working copy of original bcd value 23099 # (*) L_SCR1: copy of original expone 23099 # (*) L_SCR1: copy of original exponent word 23100 # 23100 # 23101 calc_e: 23101 calc_e: 23102 mov.l &EDIGITS,%d2 23102 mov.l &EDIGITS,%d2 # # of nibbles (digits) in fraction part 23103 mov.l &ESTRT,%d3 23103 mov.l &ESTRT,%d3 # counter to pick up digits 23104 mov.l (%a0),%d4 23104 mov.l (%a0),%d4 # get first word of bcd 23105 clr.l %d1 23105 clr.l %d1 # zero d1 for accumulator 23106 e_gd: 23106 e_gd: 23107 mulu.l &0xa,%d1 23107 mulu.l &0xa,%d1 # mul partial product by one digit place 23108 bfextu %d4{%d3:&4},%d0 23108 bfextu %d4{%d3:&4},%d0 # get the digit and zero extend into d0 23109 add.l %d0,%d1 23109 add.l %d0,%d1 # d1 = d1 + d0 23110 addq.b &4,%d3 23110 addq.b &4,%d3 # advance d3 to the next digit 23111 dbf.w %d2,e_gd 23111 dbf.w %d2,e_gd # if we have used all 3 digits, exit loop 23112 btst &30,%d4 23112 btst &30,%d4 # get SE 23113 beq.b e_pos 23113 beq.b e_pos # don't negate if pos 23114 neg.l %d1 23114 neg.l %d1 # negate before subtracting 23115 e_pos: 23115 e_pos: 23116 sub.l &16,%d1 23116 sub.l &16,%d1 # sub to compensate for shift of mant 23117 bge.b e_save 23117 bge.b e_save # if still pos, do not neg 23118 neg.l %d1 23118 neg.l %d1 # now negative, make pos and set SE 23119 or.l &0x40000000,%d4 23119 or.l &0x40000000,%d4 # set SE in d4, 23120 or.l &0x40000000,(%a0) 23120 or.l &0x40000000,(%a0) # and in working bcd 23121 e_save: 23121 e_save: 23122 mov.l %d1,-(%sp) 23122 mov.l %d1,-(%sp) # save exp on stack 23123 # 23123 # 23124 # 23124 # 23125 # Calculate mantissa: 23125 # Calculate mantissa: 23126 # 1. Calculate absolute value of mantissa i 23126 # 1. Calculate absolute value of mantissa in fp0 by mul and add. 23127 # 2. Correct for mantissa sign. 23127 # 2. Correct for mantissa sign. 23128 # (i.e., all digits assumed left of the 23128 # (i.e., all digits assumed left of the decimal point.) 23129 # 23129 # 23130 # Register usage: 23130 # Register usage: 23131 # 23131 # 23132 # calc_m: 23132 # calc_m: 23133 # (*) d0: temp digit storage 23133 # (*) d0: temp digit storage 23134 # (*) d1: lword counter 23134 # (*) d1: lword counter 23135 # (*) d2: digit count 23135 # (*) d2: digit count 23136 # (*) d3: offset pointer 23136 # (*) d3: offset pointer 23137 # ( ) d4: words 2 and 3 of bcd 23137 # ( ) d4: words 2 and 3 of bcd 23138 # ( ) a0: pointer to working bcd valu 23138 # ( ) a0: pointer to working bcd value 23139 # ( ) a6: pointer to original bcd val 23139 # ( ) a6: pointer to original bcd value 23140 # (*) fp0: mantissa accumulator 23140 # (*) fp0: mantissa accumulator 23141 # ( ) FP_SCR1: working copy of origin 23141 # ( ) FP_SCR1: working copy of original bcd value 23142 # ( ) L_SCR1: copy of original expone 23142 # ( ) L_SCR1: copy of original exponent word 23143 # 23143 # 23144 calc_m: 23144 calc_m: 23145 mov.l &1,%d1 23145 mov.l &1,%d1 # word counter, init to 1 23146 fmov.s &0x00000000,%fp0 23146 fmov.s &0x00000000,%fp0 # accumulator 23147 # 23147 # 23148 # 23148 # 23149 # Since the packed number has a long word b 23149 # Since the packed number has a long word between the first & second parts, 23150 # get the integer digit then skip down & ge 23150 # get the integer digit then skip down & get the rest of the 23151 # mantissa. We will unroll the loop once. 23151 # mantissa. We will unroll the loop once. 23152 # 23152 # 23153 bfextu (%a0){&28:&4},%d0 23153 bfextu (%a0){&28:&4},%d0 # integer part is ls digit in long word 23154 fadd.b %d0,%fp0 23154 fadd.b %d0,%fp0 # add digit to sum in fp0 23155 # 23155 # 23156 # 23156 # 23157 # Get the rest of the mantissa. 23157 # Get the rest of the mantissa. 23158 # 23158 # 23159 loadlw: 23159 loadlw: 23160 mov.l (%a0,%d1.L*4),%d4 23160 mov.l (%a0,%d1.L*4),%d4 # load mantissa lonqword into d4 23161 mov.l &FSTRT,%d3 23161 mov.l &FSTRT,%d3 # counter to pick up digits 23162 mov.l &FNIBS,%d2 23162 mov.l &FNIBS,%d2 # reset number of digits per a0 ptr 23163 md2b: 23163 md2b: 23164 fmul.s &0x41200000,%fp0 23164 fmul.s &0x41200000,%fp0 # fp0 = fp0 * 10 23165 bfextu %d4{%d3:&4},%d0 23165 bfextu %d4{%d3:&4},%d0 # get the digit and zero extend 23166 fadd.b %d0,%fp0 23166 fadd.b %d0,%fp0 # fp0 = fp0 + digit 23167 # 23167 # 23168 # 23168 # 23169 # If all the digits (8) in that long word h 23169 # If all the digits (8) in that long word have been converted (d2=0), 23170 # then inc d1 (=2) to point to the next lon 23170 # then inc d1 (=2) to point to the next long word and reset d3 to 0 23171 # to initialize the digit offset, and set d 23171 # to initialize the digit offset, and set d2 to 7 for the digit count; 23172 # else continue with this long word. 23172 # else continue with this long word. 23173 # 23173 # 23174 addq.b &4,%d3 23174 addq.b &4,%d3 # advance d3 to the next digit 23175 dbf.w %d2,md2b 23175 dbf.w %d2,md2b # check for last digit in this lw 23176 nextlw: 23176 nextlw: 23177 addq.l &1,%d1 23177 addq.l &1,%d1 # inc lw pointer in mantissa 23178 cmp.l %d1,&2 23178 cmp.l %d1,&2 # test for last lw 23179 ble.b loadlw 23179 ble.b loadlw # if not, get last one 23180 # 23180 # 23181 # Check the sign of the mant and make the v 23181 # Check the sign of the mant and make the value in fp0 the same sign. 23182 # 23182 # 23183 m_sign: 23183 m_sign: 23184 btst &31,(%a0) 23184 btst &31,(%a0) # test sign of the mantissa 23185 beq.b ap_st_z 23185 beq.b ap_st_z # if clear, go to append/strip zeros 23186 fneg.x %fp0 23186 fneg.x %fp0 # if set, negate fp0 23187 # 23187 # 23188 # Append/strip zeros: 23188 # Append/strip zeros: 23189 # 23189 # 23190 # For adjusted exponents which have an abso 23190 # For adjusted exponents which have an absolute value greater than 27*, 23191 # this routine calculates the amount needed 23191 # this routine calculates the amount needed to normalize the mantissa 23192 # for the adjusted exponent. That number i 23192 # for the adjusted exponent. That number is subtracted from the exp 23193 # if the exp was positive, and added if it 23193 # if the exp was positive, and added if it was negative. The purpose 23194 # of this is to reduce the value of the exp 23194 # of this is to reduce the value of the exponent and the possibility 23195 # of error in calculation of pwrten. 23195 # of error in calculation of pwrten. 23196 # 23196 # 23197 # 1. Branch on the sign of the adjusted exp 23197 # 1. Branch on the sign of the adjusted exponent. 23198 # 2p.(positive exp) 23198 # 2p.(positive exp) 23199 # 2. Check M16 and the digits in lwords 2 23199 # 2. Check M16 and the digits in lwords 2 and 3 in descending order. 23200 # 3. Add one for each zero encountered unt 23200 # 3. Add one for each zero encountered until a non-zero digit. 23201 # 4. Subtract the count from the exp. 23201 # 4. Subtract the count from the exp. 23202 # 5. Check if the exp has crossed zero in 23202 # 5. Check if the exp has crossed zero in #3 above; make the exp abs 23203 # and set SE. 23203 # and set SE. 23204 # 6. Multiply the mantissa by 10**coun 23204 # 6. Multiply the mantissa by 10**count. 23205 # 2n.(negative exp) 23205 # 2n.(negative exp) 23206 # 2. Check the digits in lwords 3 and 2 in 23206 # 2. Check the digits in lwords 3 and 2 in descending order. 23207 # 3. Add one for each zero encountered unt 23207 # 3. Add one for each zero encountered until a non-zero digit. 23208 # 4. Add the count to the exp. 23208 # 4. Add the count to the exp. 23209 # 5. Check if the exp has crossed zero in 23209 # 5. Check if the exp has crossed zero in #3 above; clear SE. 23210 # 6. Divide the mantissa by 10**count. 23210 # 6. Divide the mantissa by 10**count. 23211 # 23211 # 23212 # *Why 27? If the adjusted exponent is wit 23212 # *Why 27? If the adjusted exponent is within -28 < expA < 28, than 23213 # any adjustment due to append/strip zeros 23213 # any adjustment due to append/strip zeros will drive the resultane 23214 # exponent towards zero. Since all pwrten 23214 # exponent towards zero. Since all pwrten constants with a power 23215 # of 27 or less are exact, there is no nee 23215 # of 27 or less are exact, there is no need to use this routine to 23216 # attempt to lessen the resultant exponent 23216 # attempt to lessen the resultant exponent. 23217 # 23217 # 23218 # Register usage: 23218 # Register usage: 23219 # 23219 # 23220 # ap_st_z: 23220 # ap_st_z: 23221 # (*) d0: temp digit storage 23221 # (*) d0: temp digit storage 23222 # (*) d1: zero count 23222 # (*) d1: zero count 23223 # (*) d2: digit count 23223 # (*) d2: digit count 23224 # (*) d3: offset pointer 23224 # (*) d3: offset pointer 23225 # ( ) d4: first word of bcd 23225 # ( ) d4: first word of bcd 23226 # (*) d5: lword counter 23226 # (*) d5: lword counter 23227 # ( ) a0: pointer to working bcd valu 23227 # ( ) a0: pointer to working bcd value 23228 # ( ) FP_SCR1: working copy of origin 23228 # ( ) FP_SCR1: working copy of original bcd value 23229 # ( ) L_SCR1: copy of original expone 23229 # ( ) L_SCR1: copy of original exponent word 23230 # 23230 # 23231 # 23231 # 23232 # First check the absolute value of the expo 23232 # First check the absolute value of the exponent to see if this 23233 # routine is necessary. If so, then check t 23233 # routine is necessary. If so, then check the sign of the exponent 23234 # and do append (+) or strip (-) zeros accor 23234 # and do append (+) or strip (-) zeros accordingly. 23235 # This section handles a positive adjusted e 23235 # This section handles a positive adjusted exponent. 23236 # 23236 # 23237 ap_st_z: 23237 ap_st_z: 23238 mov.l (%sp),%d1 23238 mov.l (%sp),%d1 # load expA for range test 23239 cmp.l %d1,&27 23239 cmp.l %d1,&27 # test is with 27 23240 ble.w pwrten 23240 ble.w pwrten # if abs(expA) <28, skip ap/st zeros 23241 btst &30,(%a0) 23241 btst &30,(%a0) # check sign of exp 23242 bne.b ap_st_n 23242 bne.b ap_st_n # if neg, go to neg side 23243 clr.l %d1 23243 clr.l %d1 # zero count reg 23244 mov.l (%a0),%d4 23244 mov.l (%a0),%d4 # load lword 1 to d4 23245 bfextu %d4{&28:&4},%d0 23245 bfextu %d4{&28:&4},%d0 # get M16 in d0 23246 bne.b ap_p_fx 23246 bne.b ap_p_fx # if M16 is non-zero, go fix exp 23247 addq.l &1,%d1 23247 addq.l &1,%d1 # inc zero count 23248 mov.l &1,%d5 23248 mov.l &1,%d5 # init lword counter 23249 mov.l (%a0,%d5.L*4),%d4 23249 mov.l (%a0,%d5.L*4),%d4 # get lword 2 to d4 23250 bne.b ap_p_cl 23250 bne.b ap_p_cl # if lw 2 is zero, skip it 23251 addq.l &8,%d1 23251 addq.l &8,%d1 # and inc count by 8 23252 addq.l &1,%d5 23252 addq.l &1,%d5 # inc lword counter 23253 mov.l (%a0,%d5.L*4),%d4 23253 mov.l (%a0,%d5.L*4),%d4 # get lword 3 to d4 23254 ap_p_cl: 23254 ap_p_cl: 23255 clr.l %d3 23255 clr.l %d3 # init offset reg 23256 mov.l &7,%d2 23256 mov.l &7,%d2 # init digit counter 23257 ap_p_gd: 23257 ap_p_gd: 23258 bfextu %d4{%d3:&4},%d0 23258 bfextu %d4{%d3:&4},%d0 # get digit 23259 bne.b ap_p_fx 23259 bne.b ap_p_fx # if non-zero, go to fix exp 23260 addq.l &4,%d3 23260 addq.l &4,%d3 # point to next digit 23261 addq.l &1,%d1 23261 addq.l &1,%d1 # inc digit counter 23262 dbf.w %d2,ap_p_gd 23262 dbf.w %d2,ap_p_gd # get next digit 23263 ap_p_fx: 23263 ap_p_fx: 23264 mov.l %d1,%d0 23264 mov.l %d1,%d0 # copy counter to d2 23265 mov.l (%sp),%d1 23265 mov.l (%sp),%d1 # get adjusted exp from memory 23266 sub.l %d0,%d1 23266 sub.l %d0,%d1 # subtract count from exp 23267 bge.b ap_p_fm 23267 bge.b ap_p_fm # if still pos, go to pwrten 23268 neg.l %d1 23268 neg.l %d1 # now its neg; get abs 23269 mov.l (%a0),%d4 23269 mov.l (%a0),%d4 # load lword 1 to d4 23270 or.l &0x40000000,%d4 23270 or.l &0x40000000,%d4 # and set SE in d4 23271 or.l &0x40000000,(%a0) 23271 or.l &0x40000000,(%a0) # and in memory 23272 # 23272 # 23273 # Calculate the mantissa multiplier to compe 23273 # Calculate the mantissa multiplier to compensate for the striping of 23274 # zeros from the mantissa. 23274 # zeros from the mantissa. 23275 # 23275 # 23276 ap_p_fm: 23276 ap_p_fm: 23277 lea.l PTENRN(%pc),%a1 23277 lea.l PTENRN(%pc),%a1 # get address of power-of-ten table 23278 clr.l %d3 23278 clr.l %d3 # init table index 23279 fmov.s &0x3f800000,%fp1 23279 fmov.s &0x3f800000,%fp1 # init fp1 to 1 23280 mov.l &3,%d2 23280 mov.l &3,%d2 # init d2 to count bits in counter 23281 ap_p_el: 23281 ap_p_el: 23282 asr.l &1,%d0 23282 asr.l &1,%d0 # shift lsb into carry 23283 bcc.b ap_p_en 23283 bcc.b ap_p_en # if 1, mul fp1 by pwrten factor 23284 fmul.x (%a1,%d3),%fp1 23284 fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no) 23285 ap_p_en: 23285 ap_p_en: 23286 add.l &12,%d3 23286 add.l &12,%d3 # inc d3 to next rtable entry 23287 tst.l %d0 23287 tst.l %d0 # check if d0 is zero 23288 bne.b ap_p_el 23288 bne.b ap_p_el # if not, get next bit 23289 fmul.x %fp1,%fp0 23289 fmul.x %fp1,%fp0 # mul mantissa by 10**(no_bits_shifted) 23290 bra.b pwrten 23290 bra.b pwrten # go calc pwrten 23291 # 23291 # 23292 # This section handles a negative adjusted e 23292 # This section handles a negative adjusted exponent. 23293 # 23293 # 23294 ap_st_n: 23294 ap_st_n: 23295 clr.l %d1 23295 clr.l %d1 # clr counter 23296 mov.l &2,%d5 23296 mov.l &2,%d5 # set up d5 to point to lword 3 23297 mov.l (%a0,%d5.L*4),%d4 23297 mov.l (%a0,%d5.L*4),%d4 # get lword 3 23298 bne.b ap_n_cl 23298 bne.b ap_n_cl # if not zero, check digits 23299 sub.l &1,%d5 23299 sub.l &1,%d5 # dec d5 to point to lword 2 23300 addq.l &8,%d1 23300 addq.l &8,%d1 # inc counter by 8 23301 mov.l (%a0,%d5.L*4),%d4 23301 mov.l (%a0,%d5.L*4),%d4 # get lword 2 23302 ap_n_cl: 23302 ap_n_cl: 23303 mov.l &28,%d3 23303 mov.l &28,%d3 # point to last digit 23304 mov.l &7,%d2 23304 mov.l &7,%d2 # init digit counter 23305 ap_n_gd: 23305 ap_n_gd: 23306 bfextu %d4{%d3:&4},%d0 23306 bfextu %d4{%d3:&4},%d0 # get digit 23307 bne.b ap_n_fx 23307 bne.b ap_n_fx # if non-zero, go to exp fix 23308 subq.l &4,%d3 23308 subq.l &4,%d3 # point to previous digit 23309 addq.l &1,%d1 23309 addq.l &1,%d1 # inc digit counter 23310 dbf.w %d2,ap_n_gd 23310 dbf.w %d2,ap_n_gd # get next digit 23311 ap_n_fx: 23311 ap_n_fx: 23312 mov.l %d1,%d0 23312 mov.l %d1,%d0 # copy counter to d0 23313 mov.l (%sp),%d1 23313 mov.l (%sp),%d1 # get adjusted exp from memory 23314 sub.l %d0,%d1 23314 sub.l %d0,%d1 # subtract count from exp 23315 bgt.b ap_n_fm 23315 bgt.b ap_n_fm # if still pos, go fix mantissa 23316 neg.l %d1 23316 neg.l %d1 # take abs of exp and clr SE 23317 mov.l (%a0),%d4 23317 mov.l (%a0),%d4 # load lword 1 to d4 23318 and.l &0xbfffffff,%d4 23318 and.l &0xbfffffff,%d4 # and clr SE in d4 23319 and.l &0xbfffffff,(%a0) 23319 and.l &0xbfffffff,(%a0) # and in memory 23320 # 23320 # 23321 # Calculate the mantissa multiplier to compe 23321 # Calculate the mantissa multiplier to compensate for the appending of 23322 # zeros to the mantissa. 23322 # zeros to the mantissa. 23323 # 23323 # 23324 ap_n_fm: 23324 ap_n_fm: 23325 lea.l PTENRN(%pc),%a1 23325 lea.l PTENRN(%pc),%a1 # get address of power-of-ten table 23326 clr.l %d3 23326 clr.l %d3 # init table index 23327 fmov.s &0x3f800000,%fp1 23327 fmov.s &0x3f800000,%fp1 # init fp1 to 1 23328 mov.l &3,%d2 23328 mov.l &3,%d2 # init d2 to count bits in counter 23329 ap_n_el: 23329 ap_n_el: 23330 asr.l &1,%d0 23330 asr.l &1,%d0 # shift lsb into carry 23331 bcc.b ap_n_en 23331 bcc.b ap_n_en # if 1, mul fp1 by pwrten factor 23332 fmul.x (%a1,%d3),%fp1 23332 fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no) 23333 ap_n_en: 23333 ap_n_en: 23334 add.l &12,%d3 23334 add.l &12,%d3 # inc d3 to next rtable entry 23335 tst.l %d0 23335 tst.l %d0 # check if d0 is zero 23336 bne.b ap_n_el 23336 bne.b ap_n_el # if not, get next bit 23337 fdiv.x %fp1,%fp0 23337 fdiv.x %fp1,%fp0 # div mantissa by 10**(no_bits_shifted) 23338 # 23338 # 23339 # 23339 # 23340 # Calculate power-of-ten factor from adjuste 23340 # Calculate power-of-ten factor from adjusted and shifted exponent. 23341 # 23341 # 23342 # Register usage: 23342 # Register usage: 23343 # 23343 # 23344 # pwrten: 23344 # pwrten: 23345 # (*) d0: temp 23345 # (*) d0: temp 23346 # ( ) d1: exponent 23346 # ( ) d1: exponent 23347 # (*) d2: {FPCR[6:5],SM,SE} as index 23347 # (*) d2: {FPCR[6:5],SM,SE} as index in RTABLE; temp 23348 # (*) d3: FPCR work copy 23348 # (*) d3: FPCR work copy 23349 # ( ) d4: first word of bcd 23349 # ( ) d4: first word of bcd 23350 # (*) a1: RTABLE pointer 23350 # (*) a1: RTABLE pointer 23351 # calc_p: 23351 # calc_p: 23352 # (*) d0: temp 23352 # (*) d0: temp 23353 # ( ) d1: exponent 23353 # ( ) d1: exponent 23354 # (*) d3: PWRTxx table index 23354 # (*) d3: PWRTxx table index 23355 # ( ) a0: pointer to working copy of 23355 # ( ) a0: pointer to working copy of bcd 23356 # (*) a1: PWRTxx pointer 23356 # (*) a1: PWRTxx pointer 23357 # (*) fp1: power-of-ten accumulator 23357 # (*) fp1: power-of-ten accumulator 23358 # 23358 # 23359 # Pwrten calculates the exponent factor in t 23359 # Pwrten calculates the exponent factor in the selected rounding mode 23360 # according to the following table: 23360 # according to the following table: 23361 # 23361 # 23362 # Sign of Mant Sign of Exp Rounding 23362 # Sign of Mant Sign of Exp Rounding Mode PWRTEN Rounding Mode 23363 # 23363 # 23364 # ANY ANY RN RN 23364 # ANY ANY RN RN 23365 # 23365 # 23366 # + + RP RP 23366 # + + RP RP 23367 # - + RP RM 23367 # - + RP RM 23368 # + - RP RM 23368 # + - RP RM 23369 # - - RP RP 23369 # - - RP RP 23370 # 23370 # 23371 # + + RM RM 23371 # + + RM RM 23372 # - + RM RP 23372 # - + RM RP 23373 # + - RM RP 23373 # + - RM RP 23374 # - - RM RM 23374 # - - RM RM 23375 # 23375 # 23376 # + + RZ RM 23376 # + + RZ RM 23377 # - + RZ RM 23377 # - + RZ RM 23378 # + - RZ RP 23378 # + - RZ RP 23379 # - - RZ RP 23379 # - - RZ RP 23380 # 23380 # 23381 # 23381 # 23382 pwrten: 23382 pwrten: 23383 mov.l USER_FPCR(%a6),%d3 23383 mov.l USER_FPCR(%a6),%d3 # get user's FPCR 23384 bfextu %d3{&26:&2},%d2 23384 bfextu %d3{&26:&2},%d2 # isolate rounding mode bits 23385 mov.l (%a0),%d4 23385 mov.l (%a0),%d4 # reload 1st bcd word to d4 23386 asl.l &2,%d2 23386 asl.l &2,%d2 # format d2 to be 23387 bfextu %d4{&0:&2},%d0 23387 bfextu %d4{&0:&2},%d0 # {FPCR[6],FPCR[5],SM,SE} 23388 add.l %d0,%d2 23388 add.l %d0,%d2 # in d2 as index into RTABLE 23389 lea.l RTABLE(%pc),%a1 23389 lea.l RTABLE(%pc),%a1 # load rtable base 23390 mov.b (%a1,%d2),%d0 23390 mov.b (%a1,%d2),%d0 # load new rounding bits from table 23391 clr.l %d3 23391 clr.l %d3 # clear d3 to force no exc and extended 23392 bfins %d0,%d3{&26:&2} 23392 bfins %d0,%d3{&26:&2} # stuff new rounding bits in FPCR 23393 fmov.l %d3,%fpcr 23393 fmov.l %d3,%fpcr # write new FPCR 23394 asr.l &1,%d0 23394 asr.l &1,%d0 # write correct PTENxx table 23395 bcc.b not_rp 23395 bcc.b not_rp # to a1 23396 lea.l PTENRP(%pc),%a1 23396 lea.l PTENRP(%pc),%a1 # it is RP 23397 bra.b calc_p 23397 bra.b calc_p # go to init section 23398 not_rp: 23398 not_rp: 23399 asr.l &1,%d0 23399 asr.l &1,%d0 # keep checking 23400 bcc.b not_rm 23400 bcc.b not_rm 23401 lea.l PTENRM(%pc),%a1 23401 lea.l PTENRM(%pc),%a1 # it is RM 23402 bra.b calc_p 23402 bra.b calc_p # go to init section 23403 not_rm: 23403 not_rm: 23404 lea.l PTENRN(%pc),%a1 23404 lea.l PTENRN(%pc),%a1 # it is RN 23405 calc_p: 23405 calc_p: 23406 mov.l %d1,%d0 23406 mov.l %d1,%d0 # copy exp to d0;use d0 23407 bpl.b no_neg 23407 bpl.b no_neg # if exp is negative, 23408 neg.l %d0 23408 neg.l %d0 # invert it 23409 or.l &0x40000000,(%a0) 23409 or.l &0x40000000,(%a0) # and set SE bit 23410 no_neg: 23410 no_neg: 23411 clr.l %d3 23411 clr.l %d3 # table index 23412 fmov.s &0x3f800000,%fp1 23412 fmov.s &0x3f800000,%fp1 # init fp1 to 1 23413 e_loop: 23413 e_loop: 23414 asr.l &1,%d0 23414 asr.l &1,%d0 # shift next bit into carry 23415 bcc.b e_next 23415 bcc.b e_next # if zero, skip the mul 23416 fmul.x (%a1,%d3),%fp1 23416 fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no) 23417 e_next: 23417 e_next: 23418 add.l &12,%d3 23418 add.l &12,%d3 # inc d3 to next rtable entry 23419 tst.l %d0 23419 tst.l %d0 # check if d0 is zero 23420 bne.b e_loop 23420 bne.b e_loop # not zero, continue shifting 23421 # 23421 # 23422 # 23422 # 23423 # Check the sign of the adjusted exp and ma 23423 # Check the sign of the adjusted exp and make the value in fp0 the 23424 # same sign. If the exp was pos then multip 23424 # same sign. If the exp was pos then multiply fp1*fp0; 23425 # else divide fp0/fp1. 23425 # else divide fp0/fp1. 23426 # 23426 # 23427 # Register Usage: 23427 # Register Usage: 23428 # norm: 23428 # norm: 23429 # ( ) a0: pointer to working bcd valu 23429 # ( ) a0: pointer to working bcd value 23430 # (*) fp0: mantissa accumulator 23430 # (*) fp0: mantissa accumulator 23431 # ( ) fp1: scaling factor - 10**(abs(e 23431 # ( ) fp1: scaling factor - 10**(abs(exp)) 23432 # 23432 # 23433 pnorm: 23433 pnorm: 23434 btst &30,(%a0) 23434 btst &30,(%a0) # test the sign of the exponent 23435 beq.b mul 23435 beq.b mul # if clear, go to multiply 23436 div: 23436 div: 23437 fdiv.x %fp1,%fp0 23437 fdiv.x %fp1,%fp0 # exp is negative, so divide mant by exp 23438 bra.b end_dec 23438 bra.b end_dec 23439 mul: 23439 mul: 23440 fmul.x %fp1,%fp0 23440 fmul.x %fp1,%fp0 # exp is positive, so multiply by exp 23441 # 23441 # 23442 # 23442 # 23443 # Clean up and return with result in fp0. 23443 # Clean up and return with result in fp0. 23444 # 23444 # 23445 # If the final mul/div in decbin incurred an 23445 # If the final mul/div in decbin incurred an inex exception, 23446 # it will be inex2, but will be reported as 23446 # it will be inex2, but will be reported as inex1 by get_op. 23447 # 23447 # 23448 end_dec: 23448 end_dec: 23449 fmov.l %fpsr,%d0 23449 fmov.l %fpsr,%d0 # get status register 23450 bclr &inex2_bit+8,%d0 23450 bclr &inex2_bit+8,%d0 # test for inex2 and clear it 23451 beq.b no_exc 23451 beq.b no_exc # skip this if no exc 23452 ori.w &inx1a_mask,2+USER_F 23452 ori.w &inx1a_mask,2+USER_FPSR(%a6) # set INEX1/AINEX 23453 no_exc: 23453 no_exc: 23454 add.l &0x4,%sp 23454 add.l &0x4,%sp # clear 1 lw param 23455 fmovm.x (%sp)+,&0x40 23455 fmovm.x (%sp)+,&0x40 # restore fp1 23456 movm.l (%sp)+,&0x3c 23456 movm.l (%sp)+,&0x3c # restore d2-d5 23457 fmov.l &0x0,%fpcr 23457 fmov.l &0x0,%fpcr 23458 fmov.l &0x0,%fpsr 23458 fmov.l &0x0,%fpsr 23459 rts 23459 rts 23460 23460 23461 ############################################ 23461 ######################################################################### 23462 # bindec(): Converts an input in extended pr 23462 # bindec(): Converts an input in extended precision format to bcd format# 23463 # 23463 # # 23464 # INPUT ************************************ 23464 # INPUT *************************************************************** # 23465 # a0 = pointer to the input extended p 23465 # a0 = pointer to the input extended precision value in memory. # 23466 # the input may be either normali 23466 # the input may be either normalized, unnormalized, or # 23467 # denormalized. 23467 # denormalized. # 23468 # d0 = contains the k-factor sign-exte 23468 # d0 = contains the k-factor sign-extended to 32-bits. # 23469 # 23469 # # 23470 # OUTPUT *********************************** 23470 # OUTPUT ************************************************************** # 23471 # FP_SCR0(a6) = bcd format result on t 23471 # FP_SCR0(a6) = bcd format result on the stack. # 23472 # 23472 # # 23473 # ALGORITHM ******************************** 23473 # ALGORITHM *********************************************************** # 23474 # 23474 # # 23475 # A1. Set RM and size ext; Set SI 23475 # A1. Set RM and size ext; Set SIGMA = sign of input. # 23476 # The k-factor is saved for us 23476 # The k-factor is saved for use in d7. Clear the # 23477 # BINDEC_FLG for separating no 23477 # BINDEC_FLG for separating normalized/denormalized # 23478 # input. If input is unnormal 23478 # input. If input is unnormalized or denormalized, # 23479 # normalize it. 23479 # normalize it. # 23480 # 23480 # # 23481 # A2. Set X = abs(input). 23481 # A2. Set X = abs(input). # 23482 # 23482 # # 23483 # A3. Compute ILOG. 23483 # A3. Compute ILOG. # 23484 # ILOG is the log base 10 of t 23484 # ILOG is the log base 10 of the input value. It is # 23485 # approximated by adding e + 0 23485 # approximated by adding e + 0.f when the original # 23486 # value is viewed as 2^^e * 1. 23486 # value is viewed as 2^^e * 1.f in extended precision. # 23487 # This value is stored in d6. 23487 # This value is stored in d6. # 23488 # 23488 # # 23489 # A4. Clr INEX bit. 23489 # A4. Clr INEX bit. # 23490 # The operation in A3 above ma 23490 # The operation in A3 above may have set INEX2. # 23491 # 23491 # # 23492 # A5. Set ICTR = 0; 23492 # A5. Set ICTR = 0; # 23493 # ICTR is a flag used in A13. 23493 # ICTR is a flag used in A13. It must be set before the # 23494 # loop entry A6. 23494 # loop entry A6. # 23495 # 23495 # # 23496 # A6. Calculate LEN. 23496 # A6. Calculate LEN. # 23497 # LEN is the number of digits 23497 # LEN is the number of digits to be displayed. The # 23498 # k-factor can dictate either 23498 # k-factor can dictate either the total number of digits, # 23499 # if it is a positive number, 23499 # if it is a positive number, or the number of digits # 23500 # after the decimal point whic 23500 # after the decimal point which are to be included as # 23501 # significant. See the 68882 23501 # significant. See the 68882 manual for examples. # 23502 # If LEN is computed to be gre 23502 # If LEN is computed to be greater than 17, set OPERR in # 23503 # USER_FPSR. LEN is stored in 23503 # USER_FPSR. LEN is stored in d4. # 23504 # 23504 # # 23505 # A7. Calculate SCALE. 23505 # A7. Calculate SCALE. # 23506 # SCALE is equal to 10^ISCALE, 23506 # SCALE is equal to 10^ISCALE, where ISCALE is the number # 23507 # of decimal places needed to 23507 # of decimal places needed to insure LEN integer digits # 23508 # in the output before convers 23508 # in the output before conversion to bcd. LAMBDA is the # 23509 # sign of ISCALE, used in A9. 23509 # sign of ISCALE, used in A9. Fp1 contains # 23510 # 10^^(abs(ISCALE)) using a ro 23510 # 10^^(abs(ISCALE)) using a rounding mode which is a # 23511 # function of the original rou 23511 # function of the original rounding mode and the signs # 23512 # of ISCALE and X. A table is 23512 # of ISCALE and X. A table is given in the code. # 23513 # 23513 # # 23514 # A8. Clr INEX; Force RZ. 23514 # A8. Clr INEX; Force RZ. # 23515 # The operation in A3 above ma 23515 # The operation in A3 above may have set INEX2. # 23516 # RZ mode is forced for the sc 23516 # RZ mode is forced for the scaling operation to insure # 23517 # only one rounding error. Th 23517 # only one rounding error. The grs bits are collected in # 23518 # the INEX flag for use in A10 23518 # the INEX flag for use in A10. # 23519 # 23519 # # 23520 # A9. Scale X -> Y. 23520 # A9. Scale X -> Y. # 23521 # The mantissa is scaled to th 23521 # The mantissa is scaled to the desired number of # 23522 # significant digits. The exc 23522 # significant digits. The excess digits are collected # 23523 # in INEX2. 23523 # in INEX2. # 23524 # 23524 # # 23525 # A10. Or in INEX. 23525 # A10. Or in INEX. # 23526 # If INEX is set, round error 23526 # If INEX is set, round error occurred. This is # 23527 # compensated for by 'or-ing' 23527 # compensated for by 'or-ing' in the INEX2 flag to # 23528 # the lsb of Y. 23528 # the lsb of Y. # 23529 # 23529 # # 23530 # A11. Restore original FPCR; set s 23530 # A11. Restore original FPCR; set size ext. # 23531 # Perform FINT operation in th 23531 # Perform FINT operation in the user's rounding mode. # 23532 # Keep the size to extended. 23532 # Keep the size to extended. # 23533 # 23533 # # 23534 # A12. Calculate YINT = FINT(Y) acc 23534 # A12. Calculate YINT = FINT(Y) according to user's rounding # 23535 # mode. The FPSP routine sint 23535 # mode. The FPSP routine sintd0 is used. The output # 23536 # is in fp0. 23536 # is in fp0. # 23537 # 23537 # # 23538 # A13. Check for LEN digits. 23538 # A13. Check for LEN digits. # 23539 # If the int operation results 23539 # If the int operation results in more than LEN digits, # 23540 # or less than LEN -1 digits, 23540 # or less than LEN -1 digits, adjust ILOG and repeat from # 23541 # A6. This test occurs only o 23541 # A6. This test occurs only on the first pass. If the # 23542 # result is exactly 10^LEN, de 23542 # result is exactly 10^LEN, decrement ILOG and divide # 23543 # the mantissa by 10. 23543 # the mantissa by 10. # 23544 # 23544 # # 23545 # A14. Convert the mantissa to bcd. 23545 # A14. Convert the mantissa to bcd. # 23546 # The binstr routine is used t 23546 # The binstr routine is used to convert the LEN digit # 23547 # mantissa to bcd in memory. 23547 # mantissa to bcd in memory. The input to binstr is # 23548 # to be a fraction; i.e. (mant 23548 # to be a fraction; i.e. (mantissa)/10^LEN and adjusted # 23549 # such that the decimal point 23549 # such that the decimal point is to the left of bit 63. # 23550 # The bcd digits are stored in 23550 # The bcd digits are stored in the correct position in # 23551 # the final string area in mem 23551 # the final string area in memory. # 23552 # 23552 # # 23553 # A15. Convert the exponent to bcd. 23553 # A15. Convert the exponent to bcd. # 23554 # As in A14 above, the exp is 23554 # As in A14 above, the exp is converted to bcd and the # 23555 # digits are stored in the fin 23555 # digits are stored in the final string. # 23556 # Test the length of the final 23556 # Test the length of the final exponent string. If the # 23557 # length is 4, set operr. 23557 # length is 4, set operr. # 23558 # 23558 # # 23559 # A16. Write sign bits to final str 23559 # A16. Write sign bits to final string. # 23560 # 23560 # # 23561 ############################################ 23561 ######################################################################### 23562 23562 23563 set BINDEC_FLG, EXC_TEMP # DE 23563 set BINDEC_FLG, EXC_TEMP # DENORM flag 23564 23564 23565 # Constants in extended precision 23565 # Constants in extended precision 23566 PLOG2: 23566 PLOG2: 23567 long 0x3FFD0000,0x9A209A8 23567 long 0x3FFD0000,0x9A209A84,0xFBCFF798,0x00000000 23568 PLOG2UP1: 23568 PLOG2UP1: 23569 long 0x3FFD0000,0x9A209A8 23569 long 0x3FFD0000,0x9A209A84,0xFBCFF799,0x00000000 23570 23570 23571 # Constants in single precision 23571 # Constants in single precision 23572 FONE: 23572 FONE: 23573 long 0x3F800000,0x0000000 23573 long 0x3F800000,0x00000000,0x00000000,0x00000000 23574 FTWO: 23574 FTWO: 23575 long 0x40000000,0x0000000 23575 long 0x40000000,0x00000000,0x00000000,0x00000000 23576 FTEN: 23576 FTEN: 23577 long 0x41200000,0x0000000 23577 long 0x41200000,0x00000000,0x00000000,0x00000000 23578 F4933: 23578 F4933: 23579 long 0x459A2800,0x0000000 23579 long 0x459A2800,0x00000000,0x00000000,0x00000000 23580 23580 23581 RBDTBL: 23581 RBDTBL: 23582 byte 0,0,0,0 23582 byte 0,0,0,0 23583 byte 3,3,2,2 23583 byte 3,3,2,2 23584 byte 3,2,2,3 23584 byte 3,2,2,3 23585 byte 2,3,3,2 23585 byte 2,3,3,2 23586 23586 23587 # Implementation Notes: 23587 # Implementation Notes: 23588 # 23588 # 23589 # The registers are used as follows: 23589 # The registers are used as follows: 23590 # 23590 # 23591 # d0: scratch; LEN input to bi 23591 # d0: scratch; LEN input to binstr 23592 # d1: scratch 23592 # d1: scratch 23593 # d2: upper 32-bits of mantiss 23593 # d2: upper 32-bits of mantissa for binstr 23594 # d3: scratch;lower 32-bits of 23594 # d3: scratch;lower 32-bits of mantissa for binstr 23595 # d4: LEN 23595 # d4: LEN 23596 # d5: LAMBDA/ICTR 23596 # d5: LAMBDA/ICTR 23597 # d6: ILOG 23597 # d6: ILOG 23598 # d7: k-factor 23598 # d7: k-factor 23599 # a0: ptr for original operand 23599 # a0: ptr for original operand/final result 23600 # a1: scratch pointer 23600 # a1: scratch pointer 23601 # a2: pointer to FP_X; abs(ori 23601 # a2: pointer to FP_X; abs(original value) in ext 23602 # fp0: scratch 23602 # fp0: scratch 23603 # fp1: scratch 23603 # fp1: scratch 23604 # fp2: scratch 23604 # fp2: scratch 23605 # F_SCR1: 23605 # F_SCR1: 23606 # F_SCR2: 23606 # F_SCR2: 23607 # L_SCR1: 23607 # L_SCR1: 23608 # L_SCR2: 23608 # L_SCR2: 23609 23609 23610 global bindec 23610 global bindec 23611 bindec: 23611 bindec: 23612 movm.l &0x3f20,-(%sp) # { 23612 movm.l &0x3f20,-(%sp) # {%d2-%d7/%a2} 23613 fmovm.x &0x7,-(%sp) # { 23613 fmovm.x &0x7,-(%sp) # {%fp0-%fp2} 23614 23614 23615 # A1. Set RM and size ext. Set SIGMA = sign 23615 # A1. Set RM and size ext. Set SIGMA = sign input; 23616 # The k-factor is saved for use in d7. 23616 # The k-factor is saved for use in d7. Clear BINDEC_FLG for 23617 # separating normalized/denormalized in 23617 # separating normalized/denormalized input. If the input 23618 # is a denormalized number, set the BIND 23618 # is a denormalized number, set the BINDEC_FLG memory word 23619 # to signal denorm. If the input is unn 23619 # to signal denorm. If the input is unnormalized, normalize 23620 # the input and test for denormalized re 23620 # the input and test for denormalized result. 23621 # 23621 # 23622 fmov.l &rm_mode*0x10,%fpcr 23622 fmov.l &rm_mode*0x10,%fpcr # set RM and ext 23623 mov.l (%a0),L_SCR2(%a6) 23623 mov.l (%a0),L_SCR2(%a6) # save exponent for sign check 23624 mov.l %d0,%d7 # mo 23624 mov.l %d0,%d7 # move k-factor to d7 23625 23625 23626 clr.b BINDEC_FLG(%a6) # cl 23626 clr.b BINDEC_FLG(%a6) # clr norm/denorm flag 23627 cmpi.b STAG(%a6),&DENORM # 23627 cmpi.b STAG(%a6),&DENORM # is input a DENORM? 23628 bne.w A2_str # no 23628 bne.w A2_str # no; input is a NORM 23629 23629 23630 # 23630 # 23631 # Normalize the denorm 23631 # Normalize the denorm 23632 # 23632 # 23633 un_de_norm: 23633 un_de_norm: 23634 mov.w (%a0),%d0 23634 mov.w (%a0),%d0 23635 and.w &0x7fff,%d0 # st 23635 and.w &0x7fff,%d0 # strip sign of normalized exp 23636 mov.l 4(%a0),%d1 23636 mov.l 4(%a0),%d1 23637 mov.l 8(%a0),%d2 23637 mov.l 8(%a0),%d2 23638 norm_loop: 23638 norm_loop: 23639 sub.w &1,%d0 23639 sub.w &1,%d0 23640 lsl.l &1,%d2 23640 lsl.l &1,%d2 23641 roxl.l &1,%d1 23641 roxl.l &1,%d1 23642 tst.l %d1 23642 tst.l %d1 23643 bge.b norm_loop 23643 bge.b norm_loop 23644 # 23644 # 23645 # Test if the normalized input is denormaliz 23645 # Test if the normalized input is denormalized 23646 # 23646 # 23647 tst.w %d0 23647 tst.w %d0 23648 bgt.b pos_exp # if 23648 bgt.b pos_exp # if greater than zero, it is a norm 23649 st BINDEC_FLG(%a6) # se 23649 st BINDEC_FLG(%a6) # set flag for denorm 23650 pos_exp: 23650 pos_exp: 23651 and.w &0x7fff,%d0 # st 23651 and.w &0x7fff,%d0 # strip sign of normalized exp 23652 mov.w %d0,(%a0) 23652 mov.w %d0,(%a0) 23653 mov.l %d1,4(%a0) 23653 mov.l %d1,4(%a0) 23654 mov.l %d2,8(%a0) 23654 mov.l %d2,8(%a0) 23655 23655 23656 # A2. Set X = abs(input). 23656 # A2. Set X = abs(input). 23657 # 23657 # 23658 A2_str: 23658 A2_str: 23659 mov.l (%a0),FP_SCR1(%a6) 23659 mov.l (%a0),FP_SCR1(%a6) # move input to work space 23660 mov.l 4(%a0),FP_SCR1+4(%a6 23660 mov.l 4(%a0),FP_SCR1+4(%a6) # move input to work space 23661 mov.l 8(%a0),FP_SCR1+8(%a6 23661 mov.l 8(%a0),FP_SCR1+8(%a6) # move input to work space 23662 and.l &0x7fffffff,FP_SCR1( 23662 and.l &0x7fffffff,FP_SCR1(%a6) # create abs(X) 23663 23663 23664 # A3. Compute ILOG. 23664 # A3. Compute ILOG. 23665 # ILOG is the log base 10 of the input v 23665 # ILOG is the log base 10 of the input value. It is approx- 23666 # imated by adding e + 0.f when the orig 23666 # imated by adding e + 0.f when the original value is viewed 23667 # as 2^^e * 1.f in extended precision. 23667 # as 2^^e * 1.f in extended precision. This value is stored 23668 # in d6. 23668 # in d6. 23669 # 23669 # 23670 # Register usage: 23670 # Register usage: 23671 # Input/Output 23671 # Input/Output 23672 # d0: k-factor/exponent 23672 # d0: k-factor/exponent 23673 # d2: x/x 23673 # d2: x/x 23674 # d3: x/x 23674 # d3: x/x 23675 # d4: x/x 23675 # d4: x/x 23676 # d5: x/x 23676 # d5: x/x 23677 # d6: x/ILOG 23677 # d6: x/ILOG 23678 # d7: k-factor/Unchanged 23678 # d7: k-factor/Unchanged 23679 # a0: ptr for original operand/final r 23679 # a0: ptr for original operand/final result 23680 # a1: x/x 23680 # a1: x/x 23681 # a2: x/x 23681 # a2: x/x 23682 # fp0: x/float(ILOG) 23682 # fp0: x/float(ILOG) 23683 # fp1: x/x 23683 # fp1: x/x 23684 # fp2: x/x 23684 # fp2: x/x 23685 # F_SCR1:x/x 23685 # F_SCR1:x/x 23686 # F_SCR2:Abs(X)/Abs(X) with $3fff expo 23686 # F_SCR2:Abs(X)/Abs(X) with $3fff exponent 23687 # L_SCR1:x/x 23687 # L_SCR1:x/x 23688 # L_SCR2:first word of X packed/Unchan 23688 # L_SCR2:first word of X packed/Unchanged 23689 23689 23690 tst.b BINDEC_FLG(%a6) # ch 23690 tst.b BINDEC_FLG(%a6) # check for denorm 23691 beq.b A3_cont # if 23691 beq.b A3_cont # if clr, continue with norm 23692 mov.l &-4933,%d6 # fo 23692 mov.l &-4933,%d6 # force ILOG = -4933 23693 bra.b A4_str 23693 bra.b A4_str 23694 A3_cont: 23694 A3_cont: 23695 mov.w FP_SCR1(%a6),%d0 23695 mov.w FP_SCR1(%a6),%d0 # move exp to d0 23696 mov.w &0x3fff,FP_SCR1(%a6) 23696 mov.w &0x3fff,FP_SCR1(%a6) # replace exponent with 0x3fff 23697 fmov.x FP_SCR1(%a6),%fp0 23697 fmov.x FP_SCR1(%a6),%fp0 # now fp0 has 1.f 23698 sub.w &0x3fff,%d0 # st 23698 sub.w &0x3fff,%d0 # strip off bias 23699 fadd.w %d0,%fp0 # ad 23699 fadd.w %d0,%fp0 # add in exp 23700 fsub.s FONE(%pc),%fp0 # su 23700 fsub.s FONE(%pc),%fp0 # subtract off 1.0 23701 fbge.w pos_res # if 23701 fbge.w pos_res # if pos, branch 23702 fmul.x PLOG2UP1(%pc),%fp0 23702 fmul.x PLOG2UP1(%pc),%fp0 # if neg, mul by LOG2UP1 23703 fmov.l %fp0,%d6 # pu 23703 fmov.l %fp0,%d6 # put ILOG in d6 as a lword 23704 bra.b A4_str # go 23704 bra.b A4_str # go move out ILOG 23705 pos_res: 23705 pos_res: 23706 fmul.x PLOG2(%pc),%fp0 # if 23706 fmul.x PLOG2(%pc),%fp0 # if pos, mul by LOG2 23707 fmov.l %fp0,%d6 # pu 23707 fmov.l %fp0,%d6 # put ILOG in d6 as a lword 23708 23708 23709 23709 23710 # A4. Clr INEX bit. 23710 # A4. Clr INEX bit. 23711 # The operation in A3 above may have set 23711 # The operation in A3 above may have set INEX2. 23712 23712 23713 A4_str: 23713 A4_str: 23714 fmov.l &0,%fpsr # ze 23714 fmov.l &0,%fpsr # zero all of fpsr - nothing needed 23715 23715 23716 23716 23717 # A5. Set ICTR = 0; 23717 # A5. Set ICTR = 0; 23718 # ICTR is a flag used in A13. It must b 23718 # ICTR is a flag used in A13. It must be set before the 23719 # loop entry A6. The lower word of d5 is 23719 # loop entry A6. The lower word of d5 is used for ICTR. 23720 23720 23721 clr.w %d5 # cl 23721 clr.w %d5 # clear ICTR 23722 23722 23723 # A6. Calculate LEN. 23723 # A6. Calculate LEN. 23724 # LEN is the number of digits to be disp 23724 # LEN is the number of digits to be displayed. The k-factor 23725 # can dictate either the total number of 23725 # can dictate either the total number of digits, if it is 23726 # a positive number, or the number of di 23726 # a positive number, or the number of digits after the 23727 # original decimal point which are to be 23727 # original decimal point which are to be included as 23728 # significant. See the 68882 manual for 23728 # significant. See the 68882 manual for examples. 23729 # If LEN is computed to be greater than 23729 # If LEN is computed to be greater than 17, set OPERR in 23730 # USER_FPSR. LEN is stored in d4. 23730 # USER_FPSR. LEN is stored in d4. 23731 # 23731 # 23732 # Register usage: 23732 # Register usage: 23733 # Input/Output 23733 # Input/Output 23734 # d0: exponent/Unchanged 23734 # d0: exponent/Unchanged 23735 # d2: x/x/scratch 23735 # d2: x/x/scratch 23736 # d3: x/x 23736 # d3: x/x 23737 # d4: exc picture/LEN 23737 # d4: exc picture/LEN 23738 # d5: ICTR/Unchanged 23738 # d5: ICTR/Unchanged 23739 # d6: ILOG/Unchanged 23739 # d6: ILOG/Unchanged 23740 # d7: k-factor/Unchanged 23740 # d7: k-factor/Unchanged 23741 # a0: ptr for original operand/final r 23741 # a0: ptr for original operand/final result 23742 # a1: x/x 23742 # a1: x/x 23743 # a2: x/x 23743 # a2: x/x 23744 # fp0: float(ILOG)/Unchanged 23744 # fp0: float(ILOG)/Unchanged 23745 # fp1: x/x 23745 # fp1: x/x 23746 # fp2: x/x 23746 # fp2: x/x 23747 # F_SCR1:x/x 23747 # F_SCR1:x/x 23748 # F_SCR2:Abs(X) with $3fff exponent/Un 23748 # F_SCR2:Abs(X) with $3fff exponent/Unchanged 23749 # L_SCR1:x/x 23749 # L_SCR1:x/x 23750 # L_SCR2:first word of X packed/Unchan 23750 # L_SCR2:first word of X packed/Unchanged 23751 23751 23752 A6_str: 23752 A6_str: 23753 tst.l %d7 # br 23753 tst.l %d7 # branch on sign of k 23754 ble.b k_neg # if 23754 ble.b k_neg # if k <= 0, LEN = ILOG + 1 - k 23755 mov.l %d7,%d4 # if 23755 mov.l %d7,%d4 # if k > 0, LEN = k 23756 bra.b len_ck # sk 23756 bra.b len_ck # skip to LEN check 23757 k_neg: 23757 k_neg: 23758 mov.l %d6,%d4 # fi 23758 mov.l %d6,%d4 # first load ILOG to d4 23759 sub.l %d7,%d4 # su 23759 sub.l %d7,%d4 # subtract off k 23760 addq.l &1,%d4 # ad 23760 addq.l &1,%d4 # add in the 1 23761 len_ck: 23761 len_ck: 23762 tst.l %d4 # LE 23762 tst.l %d4 # LEN check: branch on sign of LEN 23763 ble.b LEN_ng # if 23763 ble.b LEN_ng # if neg, set LEN = 1 23764 cmp.l %d4,&17 # te 23764 cmp.l %d4,&17 # test if LEN > 17 23765 ble.b A7_str # if 23765 ble.b A7_str # if not, forget it 23766 mov.l &17,%d4 # se 23766 mov.l &17,%d4 # set max LEN = 17 23767 tst.l %d7 # if 23767 tst.l %d7 # if negative, never set OPERR 23768 ble.b A7_str # if 23768 ble.b A7_str # if positive, continue 23769 or.l &opaop_mask,USER_FPS 23769 or.l &opaop_mask,USER_FPSR(%a6) # set OPERR & AIOP in USER_FPSR 23770 bra.b A7_str # fi 23770 bra.b A7_str # finished here 23771 LEN_ng: 23771 LEN_ng: 23772 mov.l &1,%d4 # mi 23772 mov.l &1,%d4 # min LEN is 1 23773 23773 23774 23774 23775 # A7. Calculate SCALE. 23775 # A7. Calculate SCALE. 23776 # SCALE is equal to 10^ISCALE, where ISC 23776 # SCALE is equal to 10^ISCALE, where ISCALE is the number 23777 # of decimal places needed to insure LEN 23777 # of decimal places needed to insure LEN integer digits 23778 # in the output before conversion to bcd 23778 # in the output before conversion to bcd. LAMBDA is the sign 23779 # of ISCALE, used in A9. Fp1 contains 1 23779 # of ISCALE, used in A9. Fp1 contains 10^^(abs(ISCALE)) using 23780 # the rounding mode as given in the foll 23780 # the rounding mode as given in the following table (see 23781 # Coonen, p. 7.23 as ref.; however, the 23781 # Coonen, p. 7.23 as ref.; however, the SCALE variable is 23782 # of opposite sign in bindec.sa from Coo 23782 # of opposite sign in bindec.sa from Coonen). 23783 # 23783 # 23784 # Initial 23784 # Initial USE 23785 # FPCR[6:5] LAMBDA SIGN(X) 23785 # FPCR[6:5] LAMBDA SIGN(X) FPCR[6:5] 23786 # ------------------------------------ 23786 # ---------------------------------------------- 23787 # RN 00 0 0 23787 # RN 00 0 0 00/0 RN 23788 # RN 00 0 1 23788 # RN 00 0 1 00/0 RN 23789 # RN 00 1 0 23789 # RN 00 1 0 00/0 RN 23790 # RN 00 1 1 23790 # RN 00 1 1 00/0 RN 23791 # RZ 01 0 0 23791 # RZ 01 0 0 11/3 RP 23792 # RZ 01 0 1 23792 # RZ 01 0 1 11/3 RP 23793 # RZ 01 1 0 23793 # RZ 01 1 0 10/2 RM 23794 # RZ 01 1 1 23794 # RZ 01 1 1 10/2 RM 23795 # RM 10 0 0 23795 # RM 10 0 0 11/3 RP 23796 # RM 10 0 1 23796 # RM 10 0 1 10/2 RM 23797 # RM 10 1 0 23797 # RM 10 1 0 10/2 RM 23798 # RM 10 1 1 23798 # RM 10 1 1 11/3 RP 23799 # RP 11 0 0 23799 # RP 11 0 0 10/2 RM 23800 # RP 11 0 1 23800 # RP 11 0 1 11/3 RP 23801 # RP 11 1 0 23801 # RP 11 1 0 11/3 RP 23802 # RP 11 1 1 23802 # RP 11 1 1 10/2 RM 23803 # 23803 # 23804 # Register usage: 23804 # Register usage: 23805 # Input/Output 23805 # Input/Output 23806 # d0: exponent/scratch - final is 0 23806 # d0: exponent/scratch - final is 0 23807 # d2: x/0 or 24 for A9 23807 # d2: x/0 or 24 for A9 23808 # d3: x/scratch - offset ptr into PTEN 23808 # d3: x/scratch - offset ptr into PTENRM array 23809 # d4: LEN/Unchanged 23809 # d4: LEN/Unchanged 23810 # d5: 0/ICTR:LAMBDA 23810 # d5: 0/ICTR:LAMBDA 23811 # d6: ILOG/ILOG or k if ((k<=0)&(ILOG< 23811 # d6: ILOG/ILOG or k if ((k<=0)&(ILOG<k)) 23812 # d7: k-factor/Unchanged 23812 # d7: k-factor/Unchanged 23813 # a0: ptr for original operand/final r 23813 # a0: ptr for original operand/final result 23814 # a1: x/ptr to PTENRM array 23814 # a1: x/ptr to PTENRM array 23815 # a2: x/x 23815 # a2: x/x 23816 # fp0: float(ILOG)/Unchanged 23816 # fp0: float(ILOG)/Unchanged 23817 # fp1: x/10^ISCALE 23817 # fp1: x/10^ISCALE 23818 # fp2: x/x 23818 # fp2: x/x 23819 # F_SCR1:x/x 23819 # F_SCR1:x/x 23820 # F_SCR2:Abs(X) with $3fff exponent/Un 23820 # F_SCR2:Abs(X) with $3fff exponent/Unchanged 23821 # L_SCR1:x/x 23821 # L_SCR1:x/x 23822 # L_SCR2:first word of X packed/Unchan 23822 # L_SCR2:first word of X packed/Unchanged 23823 23823 23824 A7_str: 23824 A7_str: 23825 tst.l %d7 # te 23825 tst.l %d7 # test sign of k 23826 bgt.b k_pos # if 23826 bgt.b k_pos # if pos and > 0, skip this 23827 cmp.l %d7,%d6 # te 23827 cmp.l %d7,%d6 # test k - ILOG 23828 blt.b k_pos # if 23828 blt.b k_pos # if ILOG >= k, skip this 23829 mov.l %d7,%d6 # if 23829 mov.l %d7,%d6 # if ((k<0) & (ILOG < k)) ILOG = k 23830 k_pos: 23830 k_pos: 23831 mov.l %d6,%d0 # ca 23831 mov.l %d6,%d0 # calc ILOG + 1 - LEN in d0 23832 addq.l &1,%d0 # ad 23832 addq.l &1,%d0 # add the 1 23833 sub.l %d4,%d0 # su 23833 sub.l %d4,%d0 # sub off LEN 23834 swap %d5 # us 23834 swap %d5 # use upper word of d5 for LAMBDA 23835 clr.w %d5 # se 23835 clr.w %d5 # set it zero initially 23836 clr.w %d2 # se 23836 clr.w %d2 # set up d2 for very small case 23837 tst.l %d0 # te 23837 tst.l %d0 # test sign of ISCALE 23838 bge.b iscale # if 23838 bge.b iscale # if pos, skip next inst 23839 addq.w &1,%d5 # if 23839 addq.w &1,%d5 # if neg, set LAMBDA true 23840 cmp.l %d0,&0xffffecd4 # te 23840 cmp.l %d0,&0xffffecd4 # test iscale <= -4908 23841 bgt.b no_inf # if 23841 bgt.b no_inf # if false, skip rest 23842 add.l &24,%d0 # ad 23842 add.l &24,%d0 # add in 24 to iscale 23843 mov.l &24,%d2 # pu 23843 mov.l &24,%d2 # put 24 in d2 for A9 23844 no_inf: 23844 no_inf: 23845 neg.l %d0 # an 23845 neg.l %d0 # and take abs of ISCALE 23846 iscale: 23846 iscale: 23847 fmov.s FONE(%pc),%fp1 # in 23847 fmov.s FONE(%pc),%fp1 # init fp1 to 1 23848 bfextu USER_FPCR(%a6){&26:& 23848 bfextu USER_FPCR(%a6){&26:&2},%d1 # get initial rmode bits 23849 lsl.w &1,%d1 # pu 23849 lsl.w &1,%d1 # put them in bits 2:1 23850 add.w %d5,%d1 # ad 23850 add.w %d5,%d1 # add in LAMBDA 23851 lsl.w &1,%d1 # pu 23851 lsl.w &1,%d1 # put them in bits 3:1 23852 tst.l L_SCR2(%a6) # te 23852 tst.l L_SCR2(%a6) # test sign of original x 23853 bge.b x_pos # if 23853 bge.b x_pos # if pos, don't set bit 0 23854 addq.l &1,%d1 # if 23854 addq.l &1,%d1 # if neg, set bit 0 23855 x_pos: 23855 x_pos: 23856 lea.l RBDTBL(%pc),%a2 # lo 23856 lea.l RBDTBL(%pc),%a2 # load rbdtbl base 23857 mov.b (%a2,%d1),%d3 # lo 23857 mov.b (%a2,%d1),%d3 # load d3 with new rmode 23858 lsl.l &4,%d3 # pu 23858 lsl.l &4,%d3 # put bits in proper position 23859 fmov.l %d3,%fpcr # lo 23859 fmov.l %d3,%fpcr # load bits into fpu 23860 lsr.l &4,%d3 # pu 23860 lsr.l &4,%d3 # put bits in proper position 23861 tst.b %d3 # de 23861 tst.b %d3 # decode new rmode for pten table 23862 bne.b not_rn # if 23862 bne.b not_rn # if zero, it is RN 23863 lea.l PTENRN(%pc),%a1 # lo 23863 lea.l PTENRN(%pc),%a1 # load a1 with RN table base 23864 bra.b rmode # ex 23864 bra.b rmode # exit decode 23865 not_rn: 23865 not_rn: 23866 lsr.b &1,%d3 # ge 23866 lsr.b &1,%d3 # get lsb in carry 23867 bcc.b not_rp2 # if 23867 bcc.b not_rp2 # if carry clear, it is RM 23868 lea.l PTENRP(%pc),%a1 # lo 23868 lea.l PTENRP(%pc),%a1 # load a1 with RP table base 23869 bra.b rmode # ex 23869 bra.b rmode # exit decode 23870 not_rp2: 23870 not_rp2: 23871 lea.l PTENRM(%pc),%a1 # lo 23871 lea.l PTENRM(%pc),%a1 # load a1 with RM table base 23872 rmode: 23872 rmode: 23873 clr.l %d3 # cl 23873 clr.l %d3 # clr table index 23874 e_loop2: 23874 e_loop2: 23875 lsr.l &1,%d0 # sh 23875 lsr.l &1,%d0 # shift next bit into carry 23876 bcc.b e_next2 # if 23876 bcc.b e_next2 # if zero, skip the mul 23877 fmul.x (%a1,%d3),%fp1 # mu 23877 fmul.x (%a1,%d3),%fp1 # mul by 10**(d3_bit_no) 23878 e_next2: 23878 e_next2: 23879 add.l &12,%d3 # in 23879 add.l &12,%d3 # inc d3 to next pwrten table entry 23880 tst.l %d0 # te 23880 tst.l %d0 # test if ISCALE is zero 23881 bne.b e_loop2 # if 23881 bne.b e_loop2 # if not, loop 23882 23882 23883 # A8. Clr INEX; Force RZ. 23883 # A8. Clr INEX; Force RZ. 23884 # The operation in A3 above may have set 23884 # The operation in A3 above may have set INEX2. 23885 # RZ mode is forced for the scaling oper 23885 # RZ mode is forced for the scaling operation to insure 23886 # only one rounding error. The grs bits 23886 # only one rounding error. The grs bits are collected in 23887 # the INEX flag for use in A10. 23887 # the INEX flag for use in A10. 23888 # 23888 # 23889 # Register usage: 23889 # Register usage: 23890 # Input/Output 23890 # Input/Output 23891 23891 23892 fmov.l &0,%fpsr # cl 23892 fmov.l &0,%fpsr # clr INEX 23893 fmov.l &rz_mode*0x10,%fpcr 23893 fmov.l &rz_mode*0x10,%fpcr # set RZ rounding mode 23894 23894 23895 # A9. Scale X -> Y. 23895 # A9. Scale X -> Y. 23896 # The mantissa is scaled to the desired 23896 # The mantissa is scaled to the desired number of significant 23897 # digits. The excess digits are collect 23897 # digits. The excess digits are collected in INEX2. If mul, 23898 # Check d2 for excess 10 exponential val 23898 # Check d2 for excess 10 exponential value. If not zero, 23899 # the iscale value would have caused the 23899 # the iscale value would have caused the pwrten calculation 23900 # to overflow. Only a negative iscale c 23900 # to overflow. Only a negative iscale can cause this, so 23901 # multiply by 10^(d2), which is now only 23901 # multiply by 10^(d2), which is now only allowed to be 24, 23902 # with a multiply by 10^8 and 10^16, whi 23902 # with a multiply by 10^8 and 10^16, which is exact since 23903 # 10^24 is exact. If the input was deno 23903 # 10^24 is exact. If the input was denormalized, we must 23904 # create a busy stack frame with the mul 23904 # create a busy stack frame with the mul command and the 23905 # two operands, and allow the fpu to com 23905 # two operands, and allow the fpu to complete the multiply. 23906 # 23906 # 23907 # Register usage: 23907 # Register usage: 23908 # Input/Output 23908 # Input/Output 23909 # d0: FPCR with RZ mode/Unchanged 23909 # d0: FPCR with RZ mode/Unchanged 23910 # d2: 0 or 24/unchanged 23910 # d2: 0 or 24/unchanged 23911 # d3: x/x 23911 # d3: x/x 23912 # d4: LEN/Unchanged 23912 # d4: LEN/Unchanged 23913 # d5: ICTR:LAMBDA 23913 # d5: ICTR:LAMBDA 23914 # d6: ILOG/Unchanged 23914 # d6: ILOG/Unchanged 23915 # d7: k-factor/Unchanged 23915 # d7: k-factor/Unchanged 23916 # a0: ptr for original operand/final r 23916 # a0: ptr for original operand/final result 23917 # a1: ptr to PTENRM array/Unchanged 23917 # a1: ptr to PTENRM array/Unchanged 23918 # a2: x/x 23918 # a2: x/x 23919 # fp0: float(ILOG)/X adjusted for SCAL 23919 # fp0: float(ILOG)/X adjusted for SCALE (Y) 23920 # fp1: 10^ISCALE/Unchanged 23920 # fp1: 10^ISCALE/Unchanged 23921 # fp2: x/x 23921 # fp2: x/x 23922 # F_SCR1:x/x 23922 # F_SCR1:x/x 23923 # F_SCR2:Abs(X) with $3fff exponent/Un 23923 # F_SCR2:Abs(X) with $3fff exponent/Unchanged 23924 # L_SCR1:x/x 23924 # L_SCR1:x/x 23925 # L_SCR2:first word of X packed/Unchan 23925 # L_SCR2:first word of X packed/Unchanged 23926 23926 23927 A9_str: 23927 A9_str: 23928 fmov.x (%a0),%fp0 # lo 23928 fmov.x (%a0),%fp0 # load X from memory 23929 fabs.x %fp0 # us 23929 fabs.x %fp0 # use abs(X) 23930 tst.w %d5 # LA 23930 tst.w %d5 # LAMBDA is in lower word of d5 23931 bne.b sc_mul # if 23931 bne.b sc_mul # if neg (LAMBDA = 1), scale by mul 23932 fdiv.x %fp1,%fp0 # ca 23932 fdiv.x %fp1,%fp0 # calculate X / SCALE -> Y to fp0 23933 bra.w A10_st # br 23933 bra.w A10_st # branch to A10 23934 23934 23935 sc_mul: 23935 sc_mul: 23936 tst.b BINDEC_FLG(%a6) # ch 23936 tst.b BINDEC_FLG(%a6) # check for denorm 23937 beq.w A9_norm # if 23937 beq.w A9_norm # if norm, continue with mul 23938 23938 23939 # for DENORM, we must calculate: 23939 # for DENORM, we must calculate: 23940 # fp0 = input_op * 10^ISCALE * 10^24 23940 # fp0 = input_op * 10^ISCALE * 10^24 23941 # since the input operand is a DENORM, we ca 23941 # since the input operand is a DENORM, we can't multiply it directly. 23942 # so, we do the multiplication of the expone 23942 # so, we do the multiplication of the exponents and mantissas separately. 23943 # in this way, we avoid underflow on interme 23943 # in this way, we avoid underflow on intermediate stages of the 23944 # multiplication and guarantee a result with 23944 # multiplication and guarantee a result without exception. 23945 fmovm.x &0x2,-(%sp) # sa 23945 fmovm.x &0x2,-(%sp) # save 10^ISCALE to stack 23946 23946 23947 mov.w (%sp),%d3 # gr 23947 mov.w (%sp),%d3 # grab exponent 23948 andi.w &0x7fff,%d3 # cl 23948 andi.w &0x7fff,%d3 # clear sign 23949 ori.w &0x8000,(%a0) # ma 23949 ori.w &0x8000,(%a0) # make DENORM exp negative 23950 add.w (%a0),%d3 # ad 23950 add.w (%a0),%d3 # add DENORM exp to 10^ISCALE exp 23951 subi.w &0x3fff,%d3 # su 23951 subi.w &0x3fff,%d3 # subtract BIAS 23952 add.w 36(%a1),%d3 23952 add.w 36(%a1),%d3 23953 subi.w &0x3fff,%d3 # su 23953 subi.w &0x3fff,%d3 # subtract BIAS 23954 add.w 48(%a1),%d3 23954 add.w 48(%a1),%d3 23955 subi.w &0x3fff,%d3 # su 23955 subi.w &0x3fff,%d3 # subtract BIAS 23956 23956 23957 bmi.w sc_mul_err # is 23957 bmi.w sc_mul_err # is result is DENORM, punt!!! 23958 23958 23959 andi.w &0x8000,(%sp) # ke 23959 andi.w &0x8000,(%sp) # keep sign 23960 or.w %d3,(%sp) # in 23960 or.w %d3,(%sp) # insert new exponent 23961 andi.w &0x7fff,(%a0) # cl 23961 andi.w &0x7fff,(%a0) # clear sign bit on DENORM again 23962 mov.l 0x8(%a0),-(%sp) # pu 23962 mov.l 0x8(%a0),-(%sp) # put input op mantissa on stk 23963 mov.l 0x4(%a0),-(%sp) 23963 mov.l 0x4(%a0),-(%sp) 23964 mov.l &0x3fff0000,-(%sp) # 23964 mov.l &0x3fff0000,-(%sp) # force exp to zero 23965 fmovm.x (%sp)+,&0x80 # lo 23965 fmovm.x (%sp)+,&0x80 # load normalized DENORM into fp0 23966 fmul.x (%sp)+,%fp0 23966 fmul.x (%sp)+,%fp0 23967 23967 23968 # fmul.x 36(%a1),%fp0 # multiply f 23968 # fmul.x 36(%a1),%fp0 # multiply fp0 by 10^8 23969 # fmul.x 48(%a1),%fp0 # multiply f 23969 # fmul.x 48(%a1),%fp0 # multiply fp0 by 10^16 23970 mov.l 36+8(%a1),-(%sp) # g 23970 mov.l 36+8(%a1),-(%sp) # get 10^8 mantissa 23971 mov.l 36+4(%a1),-(%sp) 23971 mov.l 36+4(%a1),-(%sp) 23972 mov.l &0x3fff0000,-(%sp) # 23972 mov.l &0x3fff0000,-(%sp) # force exp to zero 23973 mov.l 48+8(%a1),-(%sp) # g 23973 mov.l 48+8(%a1),-(%sp) # get 10^16 mantissa 23974 mov.l 48+4(%a1),-(%sp) 23974 mov.l 48+4(%a1),-(%sp) 23975 mov.l &0x3fff0000,-(%sp)# 23975 mov.l &0x3fff0000,-(%sp)# force exp to zero 23976 fmul.x (%sp)+,%fp0 # mu 23976 fmul.x (%sp)+,%fp0 # multiply fp0 by 10^8 23977 fmul.x (%sp)+,%fp0 # mu 23977 fmul.x (%sp)+,%fp0 # multiply fp0 by 10^16 23978 bra.b A10_st 23978 bra.b A10_st 23979 23979 23980 sc_mul_err: 23980 sc_mul_err: 23981 bra.b sc_mul_err 23981 bra.b sc_mul_err 23982 23982 23983 A9_norm: 23983 A9_norm: 23984 tst.w %d2 # te 23984 tst.w %d2 # test for small exp case 23985 beq.b A9_con # if 23985 beq.b A9_con # if zero, continue as normal 23986 fmul.x 36(%a1),%fp0 # mu 23986 fmul.x 36(%a1),%fp0 # multiply fp0 by 10^8 23987 fmul.x 48(%a1),%fp0 # mu 23987 fmul.x 48(%a1),%fp0 # multiply fp0 by 10^16 23988 A9_con: 23988 A9_con: 23989 fmul.x %fp1,%fp0 # ca 23989 fmul.x %fp1,%fp0 # calculate X * SCALE -> Y to fp0 23990 23990 23991 # A10. Or in INEX. 23991 # A10. Or in INEX. 23992 # If INEX is set, round error occurred. 23992 # If INEX is set, round error occurred. This is compensated 23993 # for by 'or-ing' in the INEX2 flag to 23993 # for by 'or-ing' in the INEX2 flag to the lsb of Y. 23994 # 23994 # 23995 # Register usage: 23995 # Register usage: 23996 # Input/Output 23996 # Input/Output 23997 # d0: FPCR with RZ mode/FPSR with INEX 23997 # d0: FPCR with RZ mode/FPSR with INEX2 isolated 23998 # d2: x/x 23998 # d2: x/x 23999 # d3: x/x 23999 # d3: x/x 24000 # d4: LEN/Unchanged 24000 # d4: LEN/Unchanged 24001 # d5: ICTR:LAMBDA 24001 # d5: ICTR:LAMBDA 24002 # d6: ILOG/Unchanged 24002 # d6: ILOG/Unchanged 24003 # d7: k-factor/Unchanged 24003 # d7: k-factor/Unchanged 24004 # a0: ptr for original operand/final r 24004 # a0: ptr for original operand/final result 24005 # a1: ptr to PTENxx array/Unchanged 24005 # a1: ptr to PTENxx array/Unchanged 24006 # a2: x/ptr to FP_SCR1(a6) 24006 # a2: x/ptr to FP_SCR1(a6) 24007 # fp0: Y/Y with lsb adjusted 24007 # fp0: Y/Y with lsb adjusted 24008 # fp1: 10^ISCALE/Unchanged 24008 # fp1: 10^ISCALE/Unchanged 24009 # fp2: x/x 24009 # fp2: x/x 24010 24010 24011 A10_st: 24011 A10_st: 24012 fmov.l %fpsr,%d0 # ge 24012 fmov.l %fpsr,%d0 # get FPSR 24013 fmov.x %fp0,FP_SCR1(%a6) 24013 fmov.x %fp0,FP_SCR1(%a6) # move Y to memory 24014 lea.l FP_SCR1(%a6),%a2 24014 lea.l FP_SCR1(%a6),%a2 # load a2 with ptr to FP_SCR1 24015 btst &9,%d0 # ch 24015 btst &9,%d0 # check if INEX2 set 24016 beq.b A11_st # if 24016 beq.b A11_st # if clear, skip rest 24017 or.l &1,8(%a2) # or 24017 or.l &1,8(%a2) # or in 1 to lsb of mantissa 24018 fmov.x FP_SCR1(%a6),%fp0 24018 fmov.x FP_SCR1(%a6),%fp0 # write adjusted Y back to fpu 24019 24019 24020 24020 24021 # A11. Restore original FPCR; set size ext. 24021 # A11. Restore original FPCR; set size ext. 24022 # Perform FINT operation in the user's 24022 # Perform FINT operation in the user's rounding mode. Keep 24023 # the size to extended. The sintdo ent 24023 # the size to extended. The sintdo entry point in the sint 24024 # routine expects the FPCR value to be 24024 # routine expects the FPCR value to be in USER_FPCR for 24025 # mode and precision. The original FPC 24025 # mode and precision. The original FPCR is saved in L_SCR1. 24026 24026 24027 A11_st: 24027 A11_st: 24028 mov.l USER_FPCR(%a6),L_SCR 24028 mov.l USER_FPCR(%a6),L_SCR1(%a6) # save it for later 24029 and.l &0x00000030,USER_FPC 24029 and.l &0x00000030,USER_FPCR(%a6) # set size to ext, 24030 # ;blo 24030 # ;block exceptions 24031 24031 24032 24032 24033 # A12. Calculate YINT = FINT(Y) according to 24033 # A12. Calculate YINT = FINT(Y) according to user's rounding mode. 24034 # The FPSP routine sintd0 is used. The 24034 # The FPSP routine sintd0 is used. The output is in fp0. 24035 # 24035 # 24036 # Register usage: 24036 # Register usage: 24037 # Input/Output 24037 # Input/Output 24038 # d0: FPSR with AINEX cleared/FPCR wit 24038 # d0: FPSR with AINEX cleared/FPCR with size set to ext 24039 # d2: x/x/scratch 24039 # d2: x/x/scratch 24040 # d3: x/x 24040 # d3: x/x 24041 # d4: LEN/Unchanged 24041 # d4: LEN/Unchanged 24042 # d5: ICTR:LAMBDA/Unchanged 24042 # d5: ICTR:LAMBDA/Unchanged 24043 # d6: ILOG/Unchanged 24043 # d6: ILOG/Unchanged 24044 # d7: k-factor/Unchanged 24044 # d7: k-factor/Unchanged 24045 # a0: ptr for original operand/src ptr 24045 # a0: ptr for original operand/src ptr for sintdo 24046 # a1: ptr to PTENxx array/Unchanged 24046 # a1: ptr to PTENxx array/Unchanged 24047 # a2: ptr to FP_SCR1(a6)/Unchanged 24047 # a2: ptr to FP_SCR1(a6)/Unchanged 24048 # a6: temp pointer to FP_SCR1(a6) - or 24048 # a6: temp pointer to FP_SCR1(a6) - orig value saved and restored 24049 # fp0: Y/YINT 24049 # fp0: Y/YINT 24050 # fp1: 10^ISCALE/Unchanged 24050 # fp1: 10^ISCALE/Unchanged 24051 # fp2: x/x 24051 # fp2: x/x 24052 # F_SCR1:x/x 24052 # F_SCR1:x/x 24053 # F_SCR2:Y adjusted for inex/Y with or 24053 # F_SCR2:Y adjusted for inex/Y with original exponent 24054 # L_SCR1:x/original USER_FPCR 24054 # L_SCR1:x/original USER_FPCR 24055 # L_SCR2:first word of X packed/Unchan 24055 # L_SCR2:first word of X packed/Unchanged 24056 24056 24057 A12_st: 24057 A12_st: 24058 movm.l &0xc0c0,-(%sp) # save regs 24058 movm.l &0xc0c0,-(%sp) # save regs used by sintd0 {%d0-%d1/%a0-%a1} 24059 mov.l L_SCR1(%a6),-(%sp) 24059 mov.l L_SCR1(%a6),-(%sp) 24060 mov.l L_SCR2(%a6),-(%sp) 24060 mov.l L_SCR2(%a6),-(%sp) 24061 24061 24062 lea.l FP_SCR1(%a6),%a0 24062 lea.l FP_SCR1(%a6),%a0 # a0 is ptr to FP_SCR1(a6) 24063 fmov.x %fp0,(%a0) # mo 24063 fmov.x %fp0,(%a0) # move Y to memory at FP_SCR1(a6) 24064 tst.l L_SCR2(%a6) # te 24064 tst.l L_SCR2(%a6) # test sign of original operand 24065 bge.b do_fint12 24065 bge.b do_fint12 # if pos, use Y 24066 or.l &0x80000000,(%a0) 24066 or.l &0x80000000,(%a0) # if neg, use -Y 24067 do_fint12: 24067 do_fint12: 24068 mov.l USER_FPSR(%a6),-(%sp) 24068 mov.l USER_FPSR(%a6),-(%sp) 24069 # bsr sintdo # sint routi 24069 # bsr sintdo # sint routine returns int in fp0 24070 24070 24071 fmov.l USER_FPCR(%a6),%fpcr 24071 fmov.l USER_FPCR(%a6),%fpcr 24072 fmov.l &0x0,%fpsr 24072 fmov.l &0x0,%fpsr # clear the AEXC bits!!! 24073 ## mov.l USER_FPCR(%a6),%d0 24073 ## mov.l USER_FPCR(%a6),%d0 # ext prec/keep rnd mode 24074 ## andi.l &0x00000030,%d0 24074 ## andi.l &0x00000030,%d0 24075 ## fmov.l %d0,%fpcr 24075 ## fmov.l %d0,%fpcr 24076 fint.x FP_SCR1(%a6),%fp0 24076 fint.x FP_SCR1(%a6),%fp0 # do fint() 24077 fmov.l %fpsr,%d0 24077 fmov.l %fpsr,%d0 24078 or.w %d0,FPSR_EXCEPT(%a6) 24078 or.w %d0,FPSR_EXCEPT(%a6) 24079 ## fmov.l &0x0,%fpcr 24079 ## fmov.l &0x0,%fpcr 24080 ## fmov.l %fpsr,%d0 24080 ## fmov.l %fpsr,%d0 # don't keep ccodes 24081 ## or.w %d0,FPSR_EXCEPT(%a6) 24081 ## or.w %d0,FPSR_EXCEPT(%a6) 24082 24082 24083 mov.b (%sp),USER_FPSR(%a6) 24083 mov.b (%sp),USER_FPSR(%a6) 24084 add.l &4,%sp 24084 add.l &4,%sp 24085 24085 24086 mov.l (%sp)+,L_SCR2(%a6) 24086 mov.l (%sp)+,L_SCR2(%a6) 24087 mov.l (%sp)+,L_SCR1(%a6) 24087 mov.l (%sp)+,L_SCR1(%a6) 24088 movm.l (%sp)+,&0x303 # restore re 24088 movm.l (%sp)+,&0x303 # restore regs used by sint {%d0-%d1/%a0-%a1} 24089 24089 24090 mov.l L_SCR2(%a6),FP_SCR1(%a6) 24090 mov.l L_SCR2(%a6),FP_SCR1(%a6) # restore original exponent 24091 mov.l L_SCR1(%a6),USER_FPCR(%a6) 24091 mov.l L_SCR1(%a6),USER_FPCR(%a6) # restore user's FPCR 24092 24092 24093 # A13. Check for LEN digits. 24093 # A13. Check for LEN digits. 24094 # If the int operation results in more 24094 # If the int operation results in more than LEN digits, 24095 # or less than LEN -1 digits, adjust IL 24095 # or less than LEN -1 digits, adjust ILOG and repeat from 24096 # A6. This test occurs only on the fir 24096 # A6. This test occurs only on the first pass. If the 24097 # result is exactly 10^LEN, decrement I 24097 # result is exactly 10^LEN, decrement ILOG and divide 24098 # the mantissa by 10. The calculation 24098 # the mantissa by 10. The calculation of 10^LEN cannot 24099 # be inexact, since all powers of ten u 24099 # be inexact, since all powers of ten up to 10^27 are exact 24100 # in extended precision, so the use of 24100 # in extended precision, so the use of a previous power-of-ten 24101 # table will introduce no error. 24101 # table will introduce no error. 24102 # 24102 # 24103 # 24103 # 24104 # Register usage: 24104 # Register usage: 24105 # Input/Output 24105 # Input/Output 24106 # d0: FPCR with size set to ext/scratc 24106 # d0: FPCR with size set to ext/scratch final = 0 24107 # d2: x/x 24107 # d2: x/x 24108 # d3: x/scratch final = x 24108 # d3: x/scratch final = x 24109 # d4: LEN/LEN adjusted 24109 # d4: LEN/LEN adjusted 24110 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24110 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24111 # d6: ILOG/ILOG adjusted 24111 # d6: ILOG/ILOG adjusted 24112 # d7: k-factor/Unchanged 24112 # d7: k-factor/Unchanged 24113 # a0: pointer into memory for packed b 24113 # a0: pointer into memory for packed bcd string formation 24114 # a1: ptr to PTENxx array/Unchanged 24114 # a1: ptr to PTENxx array/Unchanged 24115 # a2: ptr to FP_SCR1(a6)/Unchanged 24115 # a2: ptr to FP_SCR1(a6)/Unchanged 24116 # fp0: int portion of Y/abs(YINT) adju 24116 # fp0: int portion of Y/abs(YINT) adjusted 24117 # fp1: 10^ISCALE/Unchanged 24117 # fp1: 10^ISCALE/Unchanged 24118 # fp2: x/10^LEN 24118 # fp2: x/10^LEN 24119 # F_SCR1:x/x 24119 # F_SCR1:x/x 24120 # F_SCR2:Y with original exponent/Unch 24120 # F_SCR2:Y with original exponent/Unchanged 24121 # L_SCR1:original USER_FPCR/Unchanged 24121 # L_SCR1:original USER_FPCR/Unchanged 24122 # L_SCR2:first word of X packed/Unchan 24122 # L_SCR2:first word of X packed/Unchanged 24123 24123 24124 A13_st: 24124 A13_st: 24125 swap %d5 # pu 24125 swap %d5 # put ICTR in lower word of d5 24126 tst.w %d5 # ch 24126 tst.w %d5 # check if ICTR = 0 24127 bne not_zr # if 24127 bne not_zr # if non-zero, go to second test 24128 # 24128 # 24129 # Compute 10^(LEN-1) 24129 # Compute 10^(LEN-1) 24130 # 24130 # 24131 fmov.s FONE(%pc),%fp2 # in 24131 fmov.s FONE(%pc),%fp2 # init fp2 to 1.0 24132 mov.l %d4,%d0 # pu 24132 mov.l %d4,%d0 # put LEN in d0 24133 subq.l &1,%d0 # d0 24133 subq.l &1,%d0 # d0 = LEN -1 24134 clr.l %d3 # cl 24134 clr.l %d3 # clr table index 24135 l_loop: 24135 l_loop: 24136 lsr.l &1,%d0 # sh 24136 lsr.l &1,%d0 # shift next bit into carry 24137 bcc.b l_next # if 24137 bcc.b l_next # if zero, skip the mul 24138 fmul.x (%a1,%d3),%fp2 # mu 24138 fmul.x (%a1,%d3),%fp2 # mul by 10**(d3_bit_no) 24139 l_next: 24139 l_next: 24140 add.l &12,%d3 # in 24140 add.l &12,%d3 # inc d3 to next pwrten table entry 24141 tst.l %d0 # te 24141 tst.l %d0 # test if LEN is zero 24142 bne.b l_loop # if 24142 bne.b l_loop # if not, loop 24143 # 24143 # 24144 # 10^LEN-1 is computed for this test and A14 24144 # 10^LEN-1 is computed for this test and A14. If the input was 24145 # denormalized, check only the case in which 24145 # denormalized, check only the case in which YINT > 10^LEN. 24146 # 24146 # 24147 tst.b BINDEC_FLG(%a6) # ch 24147 tst.b BINDEC_FLG(%a6) # check if input was norm 24148 beq.b A13_con # if 24148 beq.b A13_con # if norm, continue with checking 24149 fabs.x %fp0 # ta 24149 fabs.x %fp0 # take abs of YINT 24150 bra test_2 24150 bra test_2 24151 # 24151 # 24152 # Compare abs(YINT) to 10^(LEN-1) and 10^LEN 24152 # Compare abs(YINT) to 10^(LEN-1) and 10^LEN 24153 # 24153 # 24154 A13_con: 24154 A13_con: 24155 fabs.x %fp0 # ta 24155 fabs.x %fp0 # take abs of YINT 24156 fcmp.x %fp0,%fp2 # co 24156 fcmp.x %fp0,%fp2 # compare abs(YINT) with 10^(LEN-1) 24157 fbge.w test_2 # if 24157 fbge.w test_2 # if greater, do next test 24158 subq.l &1,%d6 # su 24158 subq.l &1,%d6 # subtract 1 from ILOG 24159 mov.w &1,%d5 # se 24159 mov.w &1,%d5 # set ICTR 24160 fmov.l &rm_mode*0x10,%fpcr 24160 fmov.l &rm_mode*0x10,%fpcr # set rmode to RM 24161 fmul.s FTEN(%pc),%fp2 # co 24161 fmul.s FTEN(%pc),%fp2 # compute 10^LEN 24162 bra.w A6_str # re 24162 bra.w A6_str # return to A6 and recompute YINT 24163 test_2: 24163 test_2: 24164 fmul.s FTEN(%pc),%fp2 # co 24164 fmul.s FTEN(%pc),%fp2 # compute 10^LEN 24165 fcmp.x %fp0,%fp2 # co 24165 fcmp.x %fp0,%fp2 # compare abs(YINT) with 10^LEN 24166 fblt.w A14_st # if 24166 fblt.w A14_st # if less, all is ok, go to A14 24167 fbgt.w fix_ex # if 24167 fbgt.w fix_ex # if greater, fix and redo 24168 fdiv.s FTEN(%pc),%fp0 # if 24168 fdiv.s FTEN(%pc),%fp0 # if equal, divide by 10 24169 addq.l &1,%d6 # an 24169 addq.l &1,%d6 # and inc ILOG 24170 bra.b A14_st # an 24170 bra.b A14_st # and continue elsewhere 24171 fix_ex: 24171 fix_ex: 24172 addq.l &1,%d6 # in 24172 addq.l &1,%d6 # increment ILOG by 1 24173 mov.w &1,%d5 # se 24173 mov.w &1,%d5 # set ICTR 24174 fmov.l &rm_mode*0x10,%fpcr 24174 fmov.l &rm_mode*0x10,%fpcr # set rmode to RM 24175 bra.w A6_str # re 24175 bra.w A6_str # return to A6 and recompute YINT 24176 # 24176 # 24177 # Since ICTR <> 0, we have already been thro 24177 # Since ICTR <> 0, we have already been through one adjustment, 24178 # and shouldn't have another; this is to che 24178 # and shouldn't have another; this is to check if abs(YINT) = 10^LEN 24179 # 10^LEN is again computed using whatever ta 24179 # 10^LEN is again computed using whatever table is in a1 since the 24180 # value calculated cannot be inexact. 24180 # value calculated cannot be inexact. 24181 # 24181 # 24182 not_zr: 24182 not_zr: 24183 fmov.s FONE(%pc),%fp2 # in 24183 fmov.s FONE(%pc),%fp2 # init fp2 to 1.0 24184 mov.l %d4,%d0 # pu 24184 mov.l %d4,%d0 # put LEN in d0 24185 clr.l %d3 # cl 24185 clr.l %d3 # clr table index 24186 z_loop: 24186 z_loop: 24187 lsr.l &1,%d0 # sh 24187 lsr.l &1,%d0 # shift next bit into carry 24188 bcc.b z_next # if 24188 bcc.b z_next # if zero, skip the mul 24189 fmul.x (%a1,%d3),%fp2 # mu 24189 fmul.x (%a1,%d3),%fp2 # mul by 10**(d3_bit_no) 24190 z_next: 24190 z_next: 24191 add.l &12,%d3 # in 24191 add.l &12,%d3 # inc d3 to next pwrten table entry 24192 tst.l %d0 # te 24192 tst.l %d0 # test if LEN is zero 24193 bne.b z_loop # if 24193 bne.b z_loop # if not, loop 24194 fabs.x %fp0 # ge 24194 fabs.x %fp0 # get abs(YINT) 24195 fcmp.x %fp0,%fp2 # ch 24195 fcmp.x %fp0,%fp2 # check if abs(YINT) = 10^LEN 24196 fbneq.w A14_st # if 24196 fbneq.w A14_st # if not, skip this 24197 fdiv.s FTEN(%pc),%fp0 # di 24197 fdiv.s FTEN(%pc),%fp0 # divide abs(YINT) by 10 24198 addq.l &1,%d6 # an 24198 addq.l &1,%d6 # and inc ILOG by 1 24199 addq.l &1,%d4 # an 24199 addq.l &1,%d4 # and inc LEN 24200 fmul.s FTEN(%pc),%fp2 # if 24200 fmul.s FTEN(%pc),%fp2 # if LEN++, the get 10^^LEN 24201 24201 24202 # A14. Convert the mantissa to bcd. 24202 # A14. Convert the mantissa to bcd. 24203 # The binstr routine is used to convert 24203 # The binstr routine is used to convert the LEN digit 24204 # mantissa to bcd in memory. The input 24204 # mantissa to bcd in memory. The input to binstr is 24205 # to be a fraction; i.e. (mantissa)/10^ 24205 # to be a fraction; i.e. (mantissa)/10^LEN and adjusted 24206 # such that the decimal point is to the 24206 # such that the decimal point is to the left of bit 63. 24207 # The bcd digits are stored in the corr 24207 # The bcd digits are stored in the correct position in 24208 # the final string area in memory. 24208 # the final string area in memory. 24209 # 24209 # 24210 # 24210 # 24211 # Register usage: 24211 # Register usage: 24212 # Input/Output 24212 # Input/Output 24213 # d0: x/LEN call to binstr - final is 24213 # d0: x/LEN call to binstr - final is 0 24214 # d1: x/0 24214 # d1: x/0 24215 # d2: x/ms 32-bits of mant of abs(YINT 24215 # d2: x/ms 32-bits of mant of abs(YINT) 24216 # d3: x/ls 32-bits of mant of abs(YINT 24216 # d3: x/ls 32-bits of mant of abs(YINT) 24217 # d4: LEN/Unchanged 24217 # d4: LEN/Unchanged 24218 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24218 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24219 # d6: ILOG 24219 # d6: ILOG 24220 # d7: k-factor/Unchanged 24220 # d7: k-factor/Unchanged 24221 # a0: pointer into memory for packed b 24221 # a0: pointer into memory for packed bcd string formation 24222 # /ptr to first mantissa byte in r 24222 # /ptr to first mantissa byte in result string 24223 # a1: ptr to PTENxx array/Unchanged 24223 # a1: ptr to PTENxx array/Unchanged 24224 # a2: ptr to FP_SCR1(a6)/Unchanged 24224 # a2: ptr to FP_SCR1(a6)/Unchanged 24225 # fp0: int portion of Y/abs(YINT) adju 24225 # fp0: int portion of Y/abs(YINT) adjusted 24226 # fp1: 10^ISCALE/Unchanged 24226 # fp1: 10^ISCALE/Unchanged 24227 # fp2: 10^LEN/Unchanged 24227 # fp2: 10^LEN/Unchanged 24228 # F_SCR1:x/Work area for final result 24228 # F_SCR1:x/Work area for final result 24229 # F_SCR2:Y with original exponent/Unch 24229 # F_SCR2:Y with original exponent/Unchanged 24230 # L_SCR1:original USER_FPCR/Unchanged 24230 # L_SCR1:original USER_FPCR/Unchanged 24231 # L_SCR2:first word of X packed/Unchan 24231 # L_SCR2:first word of X packed/Unchanged 24232 24232 24233 A14_st: 24233 A14_st: 24234 fmov.l &rz_mode*0x10,%fpcr 24234 fmov.l &rz_mode*0x10,%fpcr # force rz for conversion 24235 fdiv.x %fp2,%fp0 # di 24235 fdiv.x %fp2,%fp0 # divide abs(YINT) by 10^LEN 24236 lea.l FP_SCR0(%a6),%a0 24236 lea.l FP_SCR0(%a6),%a0 24237 fmov.x %fp0,(%a0) # mo 24237 fmov.x %fp0,(%a0) # move abs(YINT)/10^LEN to memory 24238 mov.l 4(%a0),%d2 # mo 24238 mov.l 4(%a0),%d2 # move 2nd word of FP_RES to d2 24239 mov.l 8(%a0),%d3 # mo 24239 mov.l 8(%a0),%d3 # move 3rd word of FP_RES to d3 24240 clr.l 4(%a0) # ze 24240 clr.l 4(%a0) # zero word 2 of FP_RES 24241 clr.l 8(%a0) # ze 24241 clr.l 8(%a0) # zero word 3 of FP_RES 24242 mov.l (%a0),%d0 # mo 24242 mov.l (%a0),%d0 # move exponent to d0 24243 swap %d0 # pu 24243 swap %d0 # put exponent in lower word 24244 beq.b no_sft # if 24244 beq.b no_sft # if zero, don't shift 24245 sub.l &0x3ffd,%d0 # su 24245 sub.l &0x3ffd,%d0 # sub bias less 2 to make fract 24246 tst.l %d0 # ch 24246 tst.l %d0 # check if > 1 24247 bgt.b no_sft # if 24247 bgt.b no_sft # if so, don't shift 24248 neg.l %d0 # ma 24248 neg.l %d0 # make exp positive 24249 m_loop: 24249 m_loop: 24250 lsr.l &1,%d2 # sh 24250 lsr.l &1,%d2 # shift d2:d3 right, add 0s 24251 roxr.l &1,%d3 # th 24251 roxr.l &1,%d3 # the number of places 24252 dbf.w %d0,m_loop # gi 24252 dbf.w %d0,m_loop # given in d0 24253 no_sft: 24253 no_sft: 24254 tst.l %d2 # ch 24254 tst.l %d2 # check for mantissa of zero 24255 bne.b no_zr # if 24255 bne.b no_zr # if not, go on 24256 tst.l %d3 # co 24256 tst.l %d3 # continue zero check 24257 beq.b zer_m # if 24257 beq.b zer_m # if zero, go directly to binstr 24258 no_zr: 24258 no_zr: 24259 clr.l %d1 # pu 24259 clr.l %d1 # put zero in d1 for addx 24260 add.l &0x00000080,%d3 # in 24260 add.l &0x00000080,%d3 # inc at bit 7 24261 addx.l %d1,%d2 # co 24261 addx.l %d1,%d2 # continue inc 24262 and.l &0xffffff80,%d3 # st 24262 and.l &0xffffff80,%d3 # strip off lsb not used by 882 24263 zer_m: 24263 zer_m: 24264 mov.l %d4,%d0 # pu 24264 mov.l %d4,%d0 # put LEN in d0 for binstr call 24265 addq.l &3,%a0 # a0 24265 addq.l &3,%a0 # a0 points to M16 byte in result 24266 bsr binstr # ca 24266 bsr binstr # call binstr to convert mant 24267 24267 24268 24268 24269 # A15. Convert the exponent to bcd. 24269 # A15. Convert the exponent to bcd. 24270 # As in A14 above, the exp is converted 24270 # As in A14 above, the exp is converted to bcd and the 24271 # digits are stored in the final string 24271 # digits are stored in the final string. 24272 # 24272 # 24273 # Digits are stored in L_SCR1(a6) on re 24273 # Digits are stored in L_SCR1(a6) on return from BINDEC as: 24274 # 24274 # 24275 # 32 16 15 24275 # 32 16 15 0 24276 # ------------------------------------ 24276 # ----------------------------------------- 24277 # | 0 | e3 | e2 | e1 | e4 | X | X | 24277 # | 0 | e3 | e2 | e1 | e4 | X | X | X | 24278 # ------------------------------------ 24278 # ----------------------------------------- 24279 # 24279 # 24280 # And are moved into their proper places in 24280 # And are moved into their proper places in FP_SCR0. If digit e4 24281 # is non-zero, OPERR is signaled. In all ca 24281 # is non-zero, OPERR is signaled. In all cases, all 4 digits are 24282 # written as specified in the 881/882 manual 24282 # written as specified in the 881/882 manual for packed decimal. 24283 # 24283 # 24284 # Register usage: 24284 # Register usage: 24285 # Input/Output 24285 # Input/Output 24286 # d0: x/LEN call to binstr - final is 24286 # d0: x/LEN call to binstr - final is 0 24287 # d1: x/scratch (0);shift count for fi 24287 # d1: x/scratch (0);shift count for final exponent packing 24288 # d2: x/ms 32-bits of exp fraction/scr 24288 # d2: x/ms 32-bits of exp fraction/scratch 24289 # d3: x/ls 32-bits of exp fraction 24289 # d3: x/ls 32-bits of exp fraction 24290 # d4: LEN/Unchanged 24290 # d4: LEN/Unchanged 24291 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24291 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24292 # d6: ILOG 24292 # d6: ILOG 24293 # d7: k-factor/Unchanged 24293 # d7: k-factor/Unchanged 24294 # a0: ptr to result string/ptr to L_SC 24294 # a0: ptr to result string/ptr to L_SCR1(a6) 24295 # a1: ptr to PTENxx array/Unchanged 24295 # a1: ptr to PTENxx array/Unchanged 24296 # a2: ptr to FP_SCR1(a6)/Unchanged 24296 # a2: ptr to FP_SCR1(a6)/Unchanged 24297 # fp0: abs(YINT) adjusted/float(ILOG) 24297 # fp0: abs(YINT) adjusted/float(ILOG) 24298 # fp1: 10^ISCALE/Unchanged 24298 # fp1: 10^ISCALE/Unchanged 24299 # fp2: 10^LEN/Unchanged 24299 # fp2: 10^LEN/Unchanged 24300 # F_SCR1:Work area for final result/BC 24300 # F_SCR1:Work area for final result/BCD result 24301 # F_SCR2:Y with original exponent/ILOG 24301 # F_SCR2:Y with original exponent/ILOG/10^4 24302 # L_SCR1:original USER_FPCR/Exponent d 24302 # L_SCR1:original USER_FPCR/Exponent digits on return from binstr 24303 # L_SCR2:first word of X packed/Unchan 24303 # L_SCR2:first word of X packed/Unchanged 24304 24304 24305 A15_st: 24305 A15_st: 24306 tst.b BINDEC_FLG(%a6) # ch 24306 tst.b BINDEC_FLG(%a6) # check for denorm 24307 beq.b not_denorm 24307 beq.b not_denorm 24308 ftest.x %fp0 # te 24308 ftest.x %fp0 # test for zero 24309 fbeq.w den_zero # if 24309 fbeq.w den_zero # if zero, use k-factor or 4933 24310 fmov.l %d6,%fp0 # fl 24310 fmov.l %d6,%fp0 # float ILOG 24311 fabs.x %fp0 # ge 24311 fabs.x %fp0 # get abs of ILOG 24312 bra.b convrt 24312 bra.b convrt 24313 den_zero: 24313 den_zero: 24314 tst.l %d7 # ch 24314 tst.l %d7 # check sign of the k-factor 24315 blt.b use_ilog # if 24315 blt.b use_ilog # if negative, use ILOG 24316 fmov.s F4933(%pc),%fp0 # fo 24316 fmov.s F4933(%pc),%fp0 # force exponent to 4933 24317 bra.b convrt # do 24317 bra.b convrt # do it 24318 use_ilog: 24318 use_ilog: 24319 fmov.l %d6,%fp0 # fl 24319 fmov.l %d6,%fp0 # float ILOG 24320 fabs.x %fp0 # ge 24320 fabs.x %fp0 # get abs of ILOG 24321 bra.b convrt 24321 bra.b convrt 24322 not_denorm: 24322 not_denorm: 24323 ftest.x %fp0 # te 24323 ftest.x %fp0 # test for zero 24324 fbneq.w not_zero # if 24324 fbneq.w not_zero # if zero, force exponent 24325 fmov.s FONE(%pc),%fp0 # fo 24325 fmov.s FONE(%pc),%fp0 # force exponent to 1 24326 bra.b convrt # do 24326 bra.b convrt # do it 24327 not_zero: 24327 not_zero: 24328 fmov.l %d6,%fp0 # fl 24328 fmov.l %d6,%fp0 # float ILOG 24329 fabs.x %fp0 # ge 24329 fabs.x %fp0 # get abs of ILOG 24330 convrt: 24330 convrt: 24331 fdiv.x 24(%a1),%fp0 # co 24331 fdiv.x 24(%a1),%fp0 # compute ILOG/10^4 24332 fmov.x %fp0,FP_SCR1(%a6) 24332 fmov.x %fp0,FP_SCR1(%a6) # store fp0 in memory 24333 mov.l 4(%a2),%d2 # mo 24333 mov.l 4(%a2),%d2 # move word 2 to d2 24334 mov.l 8(%a2),%d3 # mo 24334 mov.l 8(%a2),%d3 # move word 3 to d3 24335 mov.w (%a2),%d0 # mo 24335 mov.w (%a2),%d0 # move exp to d0 24336 beq.b x_loop_fin # if 24336 beq.b x_loop_fin # if zero, skip the shift 24337 sub.w &0x3ffd,%d0 # su 24337 sub.w &0x3ffd,%d0 # subtract off bias 24338 neg.w %d0 # ma 24338 neg.w %d0 # make exp positive 24339 x_loop: 24339 x_loop: 24340 lsr.l &1,%d2 # sh 24340 lsr.l &1,%d2 # shift d2:d3 right 24341 roxr.l &1,%d3 # th 24341 roxr.l &1,%d3 # the number of places 24342 dbf.w %d0,x_loop # gi 24342 dbf.w %d0,x_loop # given in d0 24343 x_loop_fin: 24343 x_loop_fin: 24344 clr.l %d1 # pu 24344 clr.l %d1 # put zero in d1 for addx 24345 add.l &0x00000080,%d3 # in 24345 add.l &0x00000080,%d3 # inc at bit 6 24346 addx.l %d1,%d2 # co 24346 addx.l %d1,%d2 # continue inc 24347 and.l &0xffffff80,%d3 # st 24347 and.l &0xffffff80,%d3 # strip off lsb not used by 882 24348 mov.l &4,%d0 # pu 24348 mov.l &4,%d0 # put 4 in d0 for binstr call 24349 lea.l L_SCR1(%a6),%a0 # a0 24349 lea.l L_SCR1(%a6),%a0 # a0 is ptr to L_SCR1 for exp digits 24350 bsr binstr # ca 24350 bsr binstr # call binstr to convert exp 24351 mov.l L_SCR1(%a6),%d0 # lo 24351 mov.l L_SCR1(%a6),%d0 # load L_SCR1 lword to d0 24352 mov.l &12,%d1 # us 24352 mov.l &12,%d1 # use d1 for shift count 24353 lsr.l %d1,%d0 # sh 24353 lsr.l %d1,%d0 # shift d0 right by 12 24354 bfins %d0,FP_SCR0(%a6){&4: 24354 bfins %d0,FP_SCR0(%a6){&4:&12} # put e3:e2:e1 in FP_SCR0 24355 lsr.l %d1,%d0 # sh 24355 lsr.l %d1,%d0 # shift d0 right by 12 24356 bfins %d0,FP_SCR0(%a6){&16 24356 bfins %d0,FP_SCR0(%a6){&16:&4} # put e4 in FP_SCR0 24357 tst.b %d0 # ch 24357 tst.b %d0 # check if e4 is zero 24358 beq.b A16_st # if 24358 beq.b A16_st # if zero, skip rest 24359 or.l &opaop_mask,USER_FPS 24359 or.l &opaop_mask,USER_FPSR(%a6) # set OPERR & AIOP in USER_FPSR 24360 24360 24361 24361 24362 # A16. Write sign bits to final string. 24362 # A16. Write sign bits to final string. 24363 # Sigma is bit 31 of initial value; 24363 # Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG). 24364 # 24364 # 24365 # Register usage: 24365 # Register usage: 24366 # Input/Output 24366 # Input/Output 24367 # d0: x/scratch - final is x 24367 # d0: x/scratch - final is x 24368 # d2: x/x 24368 # d2: x/x 24369 # d3: x/x 24369 # d3: x/x 24370 # d4: LEN/Unchanged 24370 # d4: LEN/Unchanged 24371 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24371 # d5: ICTR:LAMBDA/LAMBDA:ICTR 24372 # d6: ILOG/ILOG adjusted 24372 # d6: ILOG/ILOG adjusted 24373 # d7: k-factor/Unchanged 24373 # d7: k-factor/Unchanged 24374 # a0: ptr to L_SCR1(a6)/Unchanged 24374 # a0: ptr to L_SCR1(a6)/Unchanged 24375 # a1: ptr to PTENxx array/Unchanged 24375 # a1: ptr to PTENxx array/Unchanged 24376 # a2: ptr to FP_SCR1(a6)/Unchanged 24376 # a2: ptr to FP_SCR1(a6)/Unchanged 24377 # fp0: float(ILOG)/Unchanged 24377 # fp0: float(ILOG)/Unchanged 24378 # fp1: 10^ISCALE/Unchanged 24378 # fp1: 10^ISCALE/Unchanged 24379 # fp2: 10^LEN/Unchanged 24379 # fp2: 10^LEN/Unchanged 24380 # F_SCR1:BCD result with correct signs 24380 # F_SCR1:BCD result with correct signs 24381 # F_SCR2:ILOG/10^4 24381 # F_SCR2:ILOG/10^4 24382 # L_SCR1:Exponent digits on return fro 24382 # L_SCR1:Exponent digits on return from binstr 24383 # L_SCR2:first word of X packed/Unchan 24383 # L_SCR2:first word of X packed/Unchanged 24384 24384 24385 A16_st: 24385 A16_st: 24386 clr.l %d0 # cl 24386 clr.l %d0 # clr d0 for collection of signs 24387 and.b &0x0f,FP_SCR0(%a6) 24387 and.b &0x0f,FP_SCR0(%a6) # clear first nibble of FP_SCR0 24388 tst.l L_SCR2(%a6) # ch 24388 tst.l L_SCR2(%a6) # check sign of original mantissa 24389 bge.b mant_p # if 24389 bge.b mant_p # if pos, don't set SM 24390 mov.l &2,%d0 # mo 24390 mov.l &2,%d0 # move 2 in to d0 for SM 24391 mant_p: 24391 mant_p: 24392 tst.l %d6 # ch 24392 tst.l %d6 # check sign of ILOG 24393 bge.b wr_sgn # if 24393 bge.b wr_sgn # if pos, don't set SE 24394 addq.l &1,%d0 # se 24394 addq.l &1,%d0 # set bit 0 in d0 for SE 24395 wr_sgn: 24395 wr_sgn: 24396 bfins %d0,FP_SCR0(%a6){&0: 24396 bfins %d0,FP_SCR0(%a6){&0:&2} # insert SM and SE into FP_SCR0 24397 24397 24398 # Clean up and restore all registers used. 24398 # Clean up and restore all registers used. 24399 24399 24400 fmov.l &0,%fpsr # cl 24400 fmov.l &0,%fpsr # clear possible inex2/ainex bits 24401 fmovm.x (%sp)+,&0xe0 # { 24401 fmovm.x (%sp)+,&0xe0 # {%fp0-%fp2} 24402 movm.l (%sp)+,&0x4fc # { 24402 movm.l (%sp)+,&0x4fc # {%d2-%d7/%a2} 24403 rts 24403 rts 24404 24404 24405 global PTENRN 24405 global PTENRN 24406 PTENRN: 24406 PTENRN: 24407 long 0x40020000,0xA000000 24407 long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1 24408 long 0x40050000,0xC800000 24408 long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2 24409 long 0x400C0000,0x9C40000 24409 long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4 24410 long 0x40190000,0xBEBC200 24410 long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8 24411 long 0x40340000,0x8E1BC9B 24411 long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16 24412 long 0x40690000,0x9DC5ADA 24412 long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32 24413 long 0x40D30000,0xC2781F4 24413 long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64 24414 long 0x41A80000,0x93BA47C 24414 long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128 24415 long 0x43510000,0xAA7EEBF 24415 long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256 24416 long 0x46A30000,0xE319A0A 24416 long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512 24417 long 0x4D480000,0xC976758 24417 long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024 24418 long 0x5A920000,0x9E8B3B5 24418 long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048 24419 long 0x75250000,0xC460520 24419 long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096 24420 24420 24421 global PTENRP 24421 global PTENRP 24422 PTENRP: 24422 PTENRP: 24423 long 0x40020000,0xA000000 24423 long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1 24424 long 0x40050000,0xC800000 24424 long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2 24425 long 0x400C0000,0x9C40000 24425 long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4 24426 long 0x40190000,0xBEBC200 24426 long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8 24427 long 0x40340000,0x8E1BC9B 24427 long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16 24428 long 0x40690000,0x9DC5ADA 24428 long 0x40690000,0x9DC5ADA8,0x2B70B59E # 10 ^ 32 24429 long 0x40D30000,0xC2781F4 24429 long 0x40D30000,0xC2781F49,0xFFCFA6D6 # 10 ^ 64 24430 long 0x41A80000,0x93BA47C 24430 long 0x41A80000,0x93BA47C9,0x80E98CE0 # 10 ^ 128 24431 long 0x43510000,0xAA7EEBF 24431 long 0x43510000,0xAA7EEBFB,0x9DF9DE8E # 10 ^ 256 24432 long 0x46A30000,0xE319A0A 24432 long 0x46A30000,0xE319A0AE,0xA60E91C7 # 10 ^ 512 24433 long 0x4D480000,0xC976758 24433 long 0x4D480000,0xC9767586,0x81750C18 # 10 ^ 1024 24434 long 0x5A920000,0x9E8B3B5 24434 long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 # 10 ^ 2048 24435 long 0x75250000,0xC460520 24435 long 0x75250000,0xC4605202,0x8A20979B # 10 ^ 4096 24436 24436 24437 global PTENRM 24437 global PTENRM 24438 PTENRM: 24438 PTENRM: 24439 long 0x40020000,0xA000000 24439 long 0x40020000,0xA0000000,0x00000000 # 10 ^ 1 24440 long 0x40050000,0xC800000 24440 long 0x40050000,0xC8000000,0x00000000 # 10 ^ 2 24441 long 0x400C0000,0x9C40000 24441 long 0x400C0000,0x9C400000,0x00000000 # 10 ^ 4 24442 long 0x40190000,0xBEBC200 24442 long 0x40190000,0xBEBC2000,0x00000000 # 10 ^ 8 24443 long 0x40340000,0x8E1BC9B 24443 long 0x40340000,0x8E1BC9BF,0x04000000 # 10 ^ 16 24444 long 0x40690000,0x9DC5ADA 24444 long 0x40690000,0x9DC5ADA8,0x2B70B59D # 10 ^ 32 24445 long 0x40D30000,0xC2781F4 24445 long 0x40D30000,0xC2781F49,0xFFCFA6D5 # 10 ^ 64 24446 long 0x41A80000,0x93BA47C 24446 long 0x41A80000,0x93BA47C9,0x80E98CDF # 10 ^ 128 24447 long 0x43510000,0xAA7EEBF 24447 long 0x43510000,0xAA7EEBFB,0x9DF9DE8D # 10 ^ 256 24448 long 0x46A30000,0xE319A0A 24448 long 0x46A30000,0xE319A0AE,0xA60E91C6 # 10 ^ 512 24449 long 0x4D480000,0xC976758 24449 long 0x4D480000,0xC9767586,0x81750C17 # 10 ^ 1024 24450 long 0x5A920000,0x9E8B3B5 24450 long 0x5A920000,0x9E8B3B5D,0xC53D5DE4 # 10 ^ 2048 24451 long 0x75250000,0xC460520 24451 long 0x75250000,0xC4605202,0x8A20979A # 10 ^ 4096 24452 24452 24453 ############################################ 24453 ######################################################################### 24454 # binstr(): Converts a 64-bit binary integer 24454 # binstr(): Converts a 64-bit binary integer to bcd. # 24455 # 24455 # # 24456 # INPUT ************************************ 24456 # INPUT *************************************************************** # 24457 # d2:d3 = 64-bit binary integer 24457 # d2:d3 = 64-bit binary integer # 24458 # d0 = desired length (LEN) 24458 # d0 = desired length (LEN) # 24459 # a0 = pointer to start in memory f 24459 # a0 = pointer to start in memory for bcd characters # 24460 # (This pointer must point to 24460 # (This pointer must point to byte 4 of the first # 24461 # lword of the packed decimal 24461 # lword of the packed decimal memory string.) # 24462 # 24462 # # 24463 # OUTPUT *********************************** 24463 # OUTPUT ************************************************************** # 24464 # a0 = pointer to LEN bcd digits repre 24464 # a0 = pointer to LEN bcd digits representing the 64-bit integer. # 24465 # 24465 # # 24466 # ALGORITHM ******************************** 24466 # ALGORITHM *********************************************************** # 24467 # The 64-bit binary is assumed to have 24467 # The 64-bit binary is assumed to have a decimal point before # 24468 # bit 63. The fraction is multiplied 24468 # bit 63. The fraction is multiplied by 10 using a mul by 2 # 24469 # shift and a mul by 8 shift. The bit 24469 # shift and a mul by 8 shift. The bits shifted out of the # 24470 # msb form a decimal digit. This proc 24470 # msb form a decimal digit. This process is iterated until # 24471 # LEN digits are formed. 24471 # LEN digits are formed. # 24472 # 24472 # # 24473 # A1. Init d7 to 1. D7 is the byte digit co 24473 # A1. Init d7 to 1. D7 is the byte digit counter, and if 1, the # 24474 # digit formed will be assumed the least 24474 # digit formed will be assumed the least significant. This is # 24475 # to force the first byte formed to have 24475 # to force the first byte formed to have a 0 in the upper 4 bits. # 24476 # 24476 # # 24477 # A2. Beginning of the loop: 24477 # A2. Beginning of the loop: # 24478 # Copy the fraction in d2:d3 to d4:d5. 24478 # Copy the fraction in d2:d3 to d4:d5. # 24479 # 24479 # # 24480 # A3. Multiply the fraction in d2:d3 by 8 us 24480 # A3. Multiply the fraction in d2:d3 by 8 using bit-field # 24481 # extracts and shifts. The three msbs f 24481 # extracts and shifts. The three msbs from d2 will go into d1. # 24482 # 24482 # # 24483 # A4. Multiply the fraction in d4:d5 by 2 us 24483 # A4. Multiply the fraction in d4:d5 by 2 using shifts. The msb # 24484 # will be collected by the carry. 24484 # will be collected by the carry. # 24485 # 24485 # # 24486 # A5. Add using the carry the 64-bit quantit 24486 # A5. Add using the carry the 64-bit quantities in d2:d3 and d4:d5 # 24487 # into d2:d3. D1 will contain the bcd d 24487 # into d2:d3. D1 will contain the bcd digit formed. # 24488 # 24488 # # 24489 # A6. Test d7. If zero, the digit formed is 24489 # A6. Test d7. If zero, the digit formed is the ms digit. If non- # 24490 # zero, it is the ls digit. Put the dig 24490 # zero, it is the ls digit. Put the digit in its place in the # 24491 # upper word of d0. If it is the ls dig 24491 # upper word of d0. If it is the ls digit, write the word # 24492 # from d0 to memory. 24492 # from d0 to memory. # 24493 # 24493 # # 24494 # A7. Decrement d6 (LEN counter) and repeat 24494 # A7. Decrement d6 (LEN counter) and repeat the loop until zero. # 24495 # 24495 # # 24496 ############################################ 24496 ######################################################################### 24497 24497 24498 # Implementation Notes: 24498 # Implementation Notes: 24499 # 24499 # 24500 # The registers are used as follows: 24500 # The registers are used as follows: 24501 # 24501 # 24502 # d0: LEN counter 24502 # d0: LEN counter 24503 # d1: temp used to form the di 24503 # d1: temp used to form the digit 24504 # d2: upper 32-bits of fractio 24504 # d2: upper 32-bits of fraction for mul by 8 24505 # d3: lower 32-bits of fractio 24505 # d3: lower 32-bits of fraction for mul by 8 24506 # d4: upper 32-bits of fractio 24506 # d4: upper 32-bits of fraction for mul by 2 24507 # d5: lower 32-bits of fractio 24507 # d5: lower 32-bits of fraction for mul by 2 24508 # d6: temp for bit-field extra 24508 # d6: temp for bit-field extracts 24509 # d7: byte digit formation wor 24509 # d7: byte digit formation word;digit count {0,1} 24510 # a0: pointer into memory for 24510 # a0: pointer into memory for packed bcd string formation 24511 # 24511 # 24512 24512 24513 global binstr 24513 global binstr 24514 binstr: 24514 binstr: 24515 movm.l &0xff00,-(%sp) # { 24515 movm.l &0xff00,-(%sp) # {%d0-%d7} 24516 24516 24517 # 24517 # 24518 # A1: Init d7 24518 # A1: Init d7 24519 # 24519 # 24520 mov.l &1,%d7 # in 24520 mov.l &1,%d7 # init d7 for second digit 24521 subq.l &1,%d0 # fo 24521 subq.l &1,%d0 # for dbf d0 would have LEN+1 passes 24522 # 24522 # 24523 # A2. Copy d2:d3 to d4:d5. Start loop. 24523 # A2. Copy d2:d3 to d4:d5. Start loop. 24524 # 24524 # 24525 loop: 24525 loop: 24526 mov.l %d2,%d4 # co 24526 mov.l %d2,%d4 # copy the fraction before muls 24527 mov.l %d3,%d5 # to 24527 mov.l %d3,%d5 # to d4:d5 24528 # 24528 # 24529 # A3. Multiply d2:d3 by 8; extract msbs into 24529 # A3. Multiply d2:d3 by 8; extract msbs into d1. 24530 # 24530 # 24531 bfextu %d2{&0:&3},%d1 # co 24531 bfextu %d2{&0:&3},%d1 # copy 3 msbs of d2 into d1 24532 asl.l &3,%d2 # sh 24532 asl.l &3,%d2 # shift d2 left by 3 places 24533 bfextu %d3{&0:&3},%d6 # co 24533 bfextu %d3{&0:&3},%d6 # copy 3 msbs of d3 into d6 24534 asl.l &3,%d3 # sh 24534 asl.l &3,%d3 # shift d3 left by 3 places 24535 or.l %d6,%d2 # or 24535 or.l %d6,%d2 # or in msbs from d3 into d2 24536 # 24536 # 24537 # A4. Multiply d4:d5 by 2; add carry out to 24537 # A4. Multiply d4:d5 by 2; add carry out to d1. 24538 # 24538 # 24539 asl.l &1,%d5 # mu 24539 asl.l &1,%d5 # mul d5 by 2 24540 roxl.l &1,%d4 # mu 24540 roxl.l &1,%d4 # mul d4 by 2 24541 swap %d6 # pu 24541 swap %d6 # put 0 in d6 lower word 24542 addx.w %d6,%d1 # ad 24542 addx.w %d6,%d1 # add in extend from mul by 2 24543 # 24543 # 24544 # A5. Add mul by 8 to mul by 2. D1 contains 24544 # A5. Add mul by 8 to mul by 2. D1 contains the digit formed. 24545 # 24545 # 24546 add.l %d5,%d3 # ad 24546 add.l %d5,%d3 # add lower 32 bits 24547 nop # ER 24547 nop # ERRATA FIX #13 (Rev. 1.2 6/6/90) 24548 addx.l %d4,%d2 # ad 24548 addx.l %d4,%d2 # add with extend upper 32 bits 24549 nop # ER 24549 nop # ERRATA FIX #13 (Rev. 1.2 6/6/90) 24550 addx.w %d6,%d1 # ad 24550 addx.w %d6,%d1 # add in extend from add to d1 24551 swap %d6 # wi 24551 swap %d6 # with d6 = 0; put 0 in upper word 24552 # 24552 # 24553 # A6. Test d7 and branch. 24553 # A6. Test d7 and branch. 24554 # 24554 # 24555 tst.w %d7 # if 24555 tst.w %d7 # if zero, store digit & to loop 24556 beq.b first_d # if 24556 beq.b first_d # if non-zero, form byte & write 24557 sec_d: 24557 sec_d: 24558 swap %d7 # br 24558 swap %d7 # bring first digit to word d7b 24559 asl.w &4,%d7 # fi 24559 asl.w &4,%d7 # first digit in upper 4 bits d7b 24560 add.w %d1,%d7 # ad 24560 add.w %d1,%d7 # add in ls digit to d7b 24561 mov.b %d7,(%a0)+ # st 24561 mov.b %d7,(%a0)+ # store d7b byte in memory 24562 swap %d7 # pu 24562 swap %d7 # put LEN counter in word d7a 24563 clr.w %d7 # se 24563 clr.w %d7 # set d7a to signal no digits done 24564 dbf.w %d0,loop # do 24564 dbf.w %d0,loop # do loop some more! 24565 bra.b end_bstr # fi 24565 bra.b end_bstr # finished, so exit 24566 first_d: 24566 first_d: 24567 swap %d7 # pu 24567 swap %d7 # put digit word in d7b 24568 mov.w %d1,%d7 # pu 24568 mov.w %d1,%d7 # put new digit in d7b 24569 swap %d7 # pu 24569 swap %d7 # put LEN counter in word d7a 24570 addq.w &1,%d7 # se 24570 addq.w &1,%d7 # set d7a to signal first digit done 24571 dbf.w %d0,loop # do 24571 dbf.w %d0,loop # do loop some more! 24572 swap %d7 # pu 24572 swap %d7 # put last digit in string 24573 lsl.w &4,%d7 # mo 24573 lsl.w &4,%d7 # move it to upper 4 bits 24574 mov.b %d7,(%a0)+ # st 24574 mov.b %d7,(%a0)+ # store it in memory string 24575 # 24575 # 24576 # Clean up and return with result in fp0. 24576 # Clean up and return with result in fp0. 24577 # 24577 # 24578 end_bstr: 24578 end_bstr: 24579 movm.l (%sp)+,&0xff # { 24579 movm.l (%sp)+,&0xff # {%d0-%d7} 24580 rts 24580 rts 24581 24581 24582 ############################################ 24582 ######################################################################### 24583 # XDEF ************************************* 24583 # XDEF **************************************************************** # 24584 # facc_in_b(): dmem_read_byte failed 24584 # facc_in_b(): dmem_read_byte failed # 24585 # facc_in_w(): dmem_read_word failed 24585 # facc_in_w(): dmem_read_word failed # 24586 # facc_in_l(): dmem_read_long failed 24586 # facc_in_l(): dmem_read_long failed # 24587 # facc_in_d(): dmem_read of dbl prec f 24587 # facc_in_d(): dmem_read of dbl prec failed # 24588 # facc_in_x(): dmem_read of ext prec f 24588 # facc_in_x(): dmem_read of ext prec failed # 24589 # 24589 # # 24590 # facc_out_b(): dmem_write_byte failed 24590 # facc_out_b(): dmem_write_byte failed # 24591 # facc_out_w(): dmem_write_word failed 24591 # facc_out_w(): dmem_write_word failed # 24592 # facc_out_l(): dmem_write_long failed 24592 # facc_out_l(): dmem_write_long failed # 24593 # facc_out_d(): dmem_write of dbl prec 24593 # facc_out_d(): dmem_write of dbl prec failed # 24594 # facc_out_x(): dmem_write of ext prec 24594 # facc_out_x(): dmem_write of ext prec failed # 24595 # 24595 # # 24596 # XREF ************************************* 24596 # XREF **************************************************************** # 24597 # _real_access() - exit through access 24597 # _real_access() - exit through access error handler # 24598 # 24598 # # 24599 # INPUT ************************************ 24599 # INPUT *************************************************************** # 24600 # None 24600 # None # 24601 # 24601 # # 24602 # OUTPUT *********************************** 24602 # OUTPUT ************************************************************** # 24603 # None 24603 # None # 24604 # 24604 # # 24605 # ALGORITHM ******************************** 24605 # ALGORITHM *********************************************************** # 24606 # Flow jumps here when an FP data fetc 24606 # Flow jumps here when an FP data fetch call gets an error # 24607 # result. This means the operating system wa 24607 # result. This means the operating system wants an access error frame # 24608 # made out of the current exception stack fr 24608 # made out of the current exception stack frame. # 24609 # So, we first call restore() which ma 24609 # So, we first call restore() which makes sure that any updated # 24610 # -(an)+ register gets returned to its pre-e 24610 # -(an)+ register gets returned to its pre-exception value and then # 24611 # we change the stack to an access error sta 24611 # we change the stack to an access error stack frame. # 24612 # 24612 # # 24613 ############################################ 24613 ######################################################################### 24614 24614 24615 facc_in_b: 24615 facc_in_b: 24616 movq.l &0x1,%d0 24616 movq.l &0x1,%d0 # one byte 24617 bsr.w restore 24617 bsr.w restore # fix An 24618 24618 24619 mov.w &0x0121,EXC_VOFF(%a6 24619 mov.w &0x0121,EXC_VOFF(%a6) # set FSLW 24620 bra.w facc_finish 24620 bra.w facc_finish 24621 24621 24622 facc_in_w: 24622 facc_in_w: 24623 movq.l &0x2,%d0 24623 movq.l &0x2,%d0 # two bytes 24624 bsr.w restore 24624 bsr.w restore # fix An 24625 24625 24626 mov.w &0x0141,EXC_VOFF(%a6 24626 mov.w &0x0141,EXC_VOFF(%a6) # set FSLW 24627 bra.b facc_finish 24627 bra.b facc_finish 24628 24628 24629 facc_in_l: 24629 facc_in_l: 24630 movq.l &0x4,%d0 24630 movq.l &0x4,%d0 # four bytes 24631 bsr.w restore 24631 bsr.w restore # fix An 24632 24632 24633 mov.w &0x0101,EXC_VOFF(%a6 24633 mov.w &0x0101,EXC_VOFF(%a6) # set FSLW 24634 bra.b facc_finish 24634 bra.b facc_finish 24635 24635 24636 facc_in_d: 24636 facc_in_d: 24637 movq.l &0x8,%d0 24637 movq.l &0x8,%d0 # eight bytes 24638 bsr.w restore 24638 bsr.w restore # fix An 24639 24639 24640 mov.w &0x0161,EXC_VOFF(%a6 24640 mov.w &0x0161,EXC_VOFF(%a6) # set FSLW 24641 bra.b facc_finish 24641 bra.b facc_finish 24642 24642 24643 facc_in_x: 24643 facc_in_x: 24644 movq.l &0xc,%d0 24644 movq.l &0xc,%d0 # twelve bytes 24645 bsr.w restore 24645 bsr.w restore # fix An 24646 24646 24647 mov.w &0x0161,EXC_VOFF(%a6 24647 mov.w &0x0161,EXC_VOFF(%a6) # set FSLW 24648 bra.b facc_finish 24648 bra.b facc_finish 24649 24649 24650 ############################################ 24650 ################################################################ 24651 24651 24652 facc_out_b: 24652 facc_out_b: 24653 movq.l &0x1,%d0 24653 movq.l &0x1,%d0 # one byte 24654 bsr.w restore 24654 bsr.w restore # restore An 24655 24655 24656 mov.w &0x00a1,EXC_VOFF(%a6 24656 mov.w &0x00a1,EXC_VOFF(%a6) # set FSLW 24657 bra.b facc_finish 24657 bra.b facc_finish 24658 24658 24659 facc_out_w: 24659 facc_out_w: 24660 movq.l &0x2,%d0 24660 movq.l &0x2,%d0 # two bytes 24661 bsr.w restore 24661 bsr.w restore # restore An 24662 24662 24663 mov.w &0x00c1,EXC_VOFF(%a6 24663 mov.w &0x00c1,EXC_VOFF(%a6) # set FSLW 24664 bra.b facc_finish 24664 bra.b facc_finish 24665 24665 24666 facc_out_l: 24666 facc_out_l: 24667 movq.l &0x4,%d0 24667 movq.l &0x4,%d0 # four bytes 24668 bsr.w restore 24668 bsr.w restore # restore An 24669 24669 24670 mov.w &0x0081,EXC_VOFF(%a6 24670 mov.w &0x0081,EXC_VOFF(%a6) # set FSLW 24671 bra.b facc_finish 24671 bra.b facc_finish 24672 24672 24673 facc_out_d: 24673 facc_out_d: 24674 movq.l &0x8,%d0 24674 movq.l &0x8,%d0 # eight bytes 24675 bsr.w restore 24675 bsr.w restore # restore An 24676 24676 24677 mov.w &0x00e1,EXC_VOFF(%a6 24677 mov.w &0x00e1,EXC_VOFF(%a6) # set FSLW 24678 bra.b facc_finish 24678 bra.b facc_finish 24679 24679 24680 facc_out_x: 24680 facc_out_x: 24681 mov.l &0xc,%d0 24681 mov.l &0xc,%d0 # twelve bytes 24682 bsr.w restore 24682 bsr.w restore # restore An 24683 24683 24684 mov.w &0x00e1,EXC_VOFF(%a6 24684 mov.w &0x00e1,EXC_VOFF(%a6) # set FSLW 24685 24685 24686 # here's where we actually create the access 24686 # here's where we actually create the access error frame from the 24687 # current exception stack frame. 24687 # current exception stack frame. 24688 facc_finish: 24688 facc_finish: 24689 mov.l USER_FPIAR(%a6),EXC_ 24689 mov.l USER_FPIAR(%a6),EXC_PC(%a6) # store current PC 24690 24690 24691 fmovm.x EXC_FPREGS(%a6),&0xc 24691 fmovm.x EXC_FPREGS(%a6),&0xc0 # restore fp0-fp1 24692 fmovm.l USER_FPCR(%a6),%fpcr 24692 fmovm.l USER_FPCR(%a6),%fpcr,%fpsr,%fpiar # restore ctrl regs 24693 movm.l EXC_DREGS(%a6),&0x03 24693 movm.l EXC_DREGS(%a6),&0x0303 # restore d0-d1/a0-a1 24694 24694 24695 unlk %a6 24695 unlk %a6 24696 24696 24697 mov.l (%sp),-(%sp) 24697 mov.l (%sp),-(%sp) # store SR, hi(PC) 24698 mov.l 0x8(%sp),0x4(%sp) 24698 mov.l 0x8(%sp),0x4(%sp) # store lo(PC) 24699 mov.l 0xc(%sp),0x8(%sp) 24699 mov.l 0xc(%sp),0x8(%sp) # store EA 24700 mov.l &0x00000001,0xc(%sp) 24700 mov.l &0x00000001,0xc(%sp) # store FSLW 24701 mov.w 0x6(%sp),0xc(%sp) 24701 mov.w 0x6(%sp),0xc(%sp) # fix FSLW (size) 24702 mov.w &0x4008,0x6(%sp) 24702 mov.w &0x4008,0x6(%sp) # store voff 24703 24703 24704 btst &0x5,(%sp) 24704 btst &0x5,(%sp) # supervisor or user mode? 24705 beq.b facc_out2 24705 beq.b facc_out2 # user 24706 bset &0x2,0xd(%sp) 24706 bset &0x2,0xd(%sp) # set supervisor TM bit 24707 24707 24708 facc_out2: 24708 facc_out2: 24709 bra.l _real_access 24709 bra.l _real_access 24710 24710 24711 ############################################ 24711 ################################################################## 24712 24712 24713 # if the effective addressing mode was prede 24713 # if the effective addressing mode was predecrement or postincrement, 24714 # the emulation has already changed its valu 24714 # the emulation has already changed its value to the correct post- 24715 # instruction value. but since we're exiting 24715 # instruction value. but since we're exiting to the access error 24716 # handler, then AN must be returned to its p 24716 # handler, then AN must be returned to its pre-instruction value. 24717 # we do that here. 24717 # we do that here. 24718 restore: 24718 restore: 24719 mov.b EXC_OPWORD+0x1(%a6), 24719 mov.b EXC_OPWORD+0x1(%a6),%d1 24720 andi.b &0x38,%d1 24720 andi.b &0x38,%d1 # extract opmode 24721 cmpi.b %d1,&0x18 24721 cmpi.b %d1,&0x18 # postinc? 24722 beq.w rest_inc 24722 beq.w rest_inc 24723 cmpi.b %d1,&0x20 24723 cmpi.b %d1,&0x20 # predec? 24724 beq.w rest_dec 24724 beq.w rest_dec 24725 rts 24725 rts 24726 24726 24727 rest_inc: 24727 rest_inc: 24728 mov.b EXC_OPWORD+0x1(%a6), 24728 mov.b EXC_OPWORD+0x1(%a6),%d1 24729 andi.w &0x0007,%d1 24729 andi.w &0x0007,%d1 # fetch An 24730 24730 24731 mov.w (tbl_rest_inc.b,%pc, 24731 mov.w (tbl_rest_inc.b,%pc,%d1.w*2),%d1 24732 jmp (tbl_rest_inc.b,%pc, 24732 jmp (tbl_rest_inc.b,%pc,%d1.w*1) 24733 24733 24734 tbl_rest_inc: 24734 tbl_rest_inc: 24735 short ri_a0 - tbl_rest_inc 24735 short ri_a0 - tbl_rest_inc 24736 short ri_a1 - tbl_rest_inc 24736 short ri_a1 - tbl_rest_inc 24737 short ri_a2 - tbl_rest_inc 24737 short ri_a2 - tbl_rest_inc 24738 short ri_a3 - tbl_rest_inc 24738 short ri_a3 - tbl_rest_inc 24739 short ri_a4 - tbl_rest_inc 24739 short ri_a4 - tbl_rest_inc 24740 short ri_a5 - tbl_rest_inc 24740 short ri_a5 - tbl_rest_inc 24741 short ri_a6 - tbl_rest_inc 24741 short ri_a6 - tbl_rest_inc 24742 short ri_a7 - tbl_rest_inc 24742 short ri_a7 - tbl_rest_inc 24743 24743 24744 ri_a0: 24744 ri_a0: 24745 sub.l %d0,EXC_DREGS+0x8(%a 24745 sub.l %d0,EXC_DREGS+0x8(%a6) # fix stacked a0 24746 rts 24746 rts 24747 ri_a1: 24747 ri_a1: 24748 sub.l %d0,EXC_DREGS+0xc(%a 24748 sub.l %d0,EXC_DREGS+0xc(%a6) # fix stacked a1 24749 rts 24749 rts 24750 ri_a2: 24750 ri_a2: 24751 sub.l %d0,%a2 24751 sub.l %d0,%a2 # fix a2 24752 rts 24752 rts 24753 ri_a3: 24753 ri_a3: 24754 sub.l %d0,%a3 24754 sub.l %d0,%a3 # fix a3 24755 rts 24755 rts 24756 ri_a4: 24756 ri_a4: 24757 sub.l %d0,%a4 24757 sub.l %d0,%a4 # fix a4 24758 rts 24758 rts 24759 ri_a5: 24759 ri_a5: 24760 sub.l %d0,%a5 24760 sub.l %d0,%a5 # fix a5 24761 rts 24761 rts 24762 ri_a6: 24762 ri_a6: 24763 sub.l %d0,(%a6) 24763 sub.l %d0,(%a6) # fix stacked a6 24764 rts 24764 rts 24765 # if it's a fmove out instruction, we don't 24765 # if it's a fmove out instruction, we don't have to fix a7 24766 # because we hadn't changed it yet. if it's 24766 # because we hadn't changed it yet. if it's an opclass two 24767 # instruction (data moved in) and the except 24767 # instruction (data moved in) and the exception was in supervisor 24768 # mode, then also also wasn't updated. if it 24768 # mode, then also also wasn't updated. if it was user mode, then 24769 # restore the correct a7 which is in the USP 24769 # restore the correct a7 which is in the USP currently. 24770 ri_a7: 24770 ri_a7: 24771 cmpi.b EXC_VOFF(%a6),&0x30 24771 cmpi.b EXC_VOFF(%a6),&0x30 # move in or out? 24772 bne.b ri_a7_done 24772 bne.b ri_a7_done # out 24773 24773 24774 btst &0x5,EXC_SR(%a6) 24774 btst &0x5,EXC_SR(%a6) # user or supervisor? 24775 bne.b ri_a7_done 24775 bne.b ri_a7_done # supervisor 24776 movc %usp,%a0 24776 movc %usp,%a0 # restore USP 24777 sub.l %d0,%a0 24777 sub.l %d0,%a0 24778 movc %a0,%usp 24778 movc %a0,%usp 24779 ri_a7_done: 24779 ri_a7_done: 24780 rts 24780 rts 24781 24781 24782 # need to invert adjustment value if the <ea 24782 # need to invert adjustment value if the <ea> was predec 24783 rest_dec: 24783 rest_dec: 24784 neg.l %d0 24784 neg.l %d0 24785 bra.b rest_inc 24785 bra.b rest_inc
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.