1 * $NetBSD: l_support.sa,v 1.3 1994/10/26 07:49:16 cgd Exp $ 2 3 * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP 4 * M68000 Hi-Performance Microprocessor Division 5 * M68040 Software Package 6 * 7 * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc. 8 * All rights reserved. 9 * 10 * THE SOFTWARE is provided on an "AS IS" basis and without warranty. 11 * To the maximum extent permitted by applicable law, 12 * MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, 13 * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A 14 * PARTICULAR PURPOSE and any warranty against infringement with 15 * regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) 16 * and any accompanying written materials. 17 * 18 * To the maximum extent permitted by applicable law, 19 * IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER 20 * (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS 21 * PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR 22 * OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE 23 * SOFTWARE. Motorola assumes no responsibility for the maintenance 24 * and support of the SOFTWARE. 25 * 26 * You are hereby granted a copyright license to use, modify, and 27 * distribute the SOFTWARE so long as this entire notice is retained 28 * without alteration in any modified and/or redistributed versions, 29 * and that such modified versions are clearly identified as such. 30 * No licenses are granted by implication, estoppel or otherwise 31 * under any patents or trademarks of Motorola, Inc. 32 33 * 34 * l_support.sa 1.2 5/1/91 35 * 36 37 L_SUPPORT IDNT 2,1 Motorola 040 Floating Point Software Package 38 39 section 8 40 41 mns_one dc.l $bfff0000,$80000000,$00000000 42 pls_one dc.l $3fff0000,$80000000,$00000000 43 pls_inf dc.l $7fff0000,$00000000,$00000000 44 pls_huge dc.l $7ffe0000,$ffffffff,$ffffffff 45 mns_huge dc.l $fffe0000,$ffffffff,$ffffffff 46 pls_tiny dc.l $00000000,$80000000,$00000000 47 mns_tiny dc.l $80000000,$80000000,$00000000 48 small dc.l $20000000,$80000000,$00000000 49 pls_zero dc.l $00000000,$00000000,$00000000 50 51 include l_fpsp.h 52 53 * 54 * tag --- determine the type of an extended precision operand 55 * 56 * The tag values returned match the way the 68040 would have 57 * tagged them. 58 * 59 * Input: a0 points to operand 60 * 61 * Output d0.b = $00 norm 62 * $20 zero 63 * $40 inf 64 * $60 nan 65 * $80 denorm 66 * All other registers are unchanged 67 * 68 xdef tag 69 tag: 70 move.w LOCAL_EX(a0),d0 71 andi.w #$7fff,d0 72 beq.b chk_zro 73 cmpi.w #$7fff,d0 74 beq.b chk_inf 75 tag_nrm: 76 clr.b d0 77 rts 78 tag_nan: 79 move.b #$60,d0 80 rts 81 tag_dnrm: 82 move.b #$80,d0 83 rts 84 chk_zro: 85 btst.b #7,LOCAL_HI(a0) # check if J-bit is set 86 bne.b tag_nrm 87 tst.l LOCAL_HI(a0) 88 bne.b tag_dnrm 89 tst.l LOCAL_LO(a0) 90 bne.b tag_dnrm 91 tag_zero: 92 move.b #$20,d0 93 rts 94 chk_inf: 95 tst.l LOCAL_HI(a0) 96 bne.b tag_nan 97 tst.l LOCAL_LO(a0) 98 bne.b tag_nan 99 tag_inf: 100 move.b #$40,d0 101 rts 102 103 * 104 * t_dz, t_dz2 --- divide by zero exception 105 * 106 * t_dz2 is used by monadic functions such as flogn (from do_func). 107 * t_dz is used by monadic functions such as satanh (from the 108 * transcendental function). 109 * 110 xdef t_dz2 111 t_dz2: 112 fmovem.x mns_one,fp0 113 fmove.l d1,fpcr 114 fdiv.x pls_zero,fp0 115 rts 116 117 xdef t_dz 118 t_dz: 119 btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos 120 beq.b p_inf ;branch if pos sign 121 m_inf: 122 fmovem.x mns_one,fp0 123 fmove.l d1,fpcr 124 fdiv.x pls_zero,fp0 125 rts 126 p_inf: 127 fmovem.x pls_one,fp0 128 fmove.l d1,fpcr 129 fdiv.x pls_zero,fp0 130 rts 131 * 132 * t_operr --- Operand Error exception 133 * 134 xdef t_operr 135 t_operr: 136 fmovem.x pls_inf,fp0 137 fmove.l d1,fpcr 138 fmul.x pls_zero,fp0 139 rts 140 141 * 142 * t_unfl --- UNFL exception 143 * 144 xdef t_unfl 145 t_unfl: 146 btst.b #sign_bit,ETEMP(a6) 147 beq.b unf_pos 148 unf_neg: 149 fmovem.x mns_tiny,fp0 150 fmove.l d1,fpcr 151 fmul.x pls_tiny,fp0 152 rts 153 154 unf_pos: 155 fmovem.x pls_tiny,fp0 156 fmove.l d1,fpcr 157 fmul.x fp0,fp0 158 rts 159 * 160 * t_ovfl --- OVFL exception 161 * 162 * t_ovfl is called as an exit for monadic functions. t_ovfl2 163 * is for dyadic exits. 164 * 165 xdef t_ovfl 166 t_ovfl: 167 xdef t_ovfl2 168 move.l d1,USER_FPCR(a6) user's control register 169 move.l #ovfinx_mask,d0 170 bra.b t_work 171 t_ovfl2: 172 move.l #ovfl_inx_mask,d0 173 t_work: 174 btst.b #sign_bit,ETEMP(a6) 175 beq.b ovf_pos 176 ovf_neg: 177 fmovem.x mns_huge,fp0 178 fmove.l USER_FPCR(a6),fpcr 179 fmul.x pls_huge,fp0 180 fmove.l fpsr,d1 181 or.l d1,d0 182 fmove.l d0,fpsr 183 rts 184 ovf_pos: 185 fmovem.x pls_huge,fp0 186 fmove.l USER_FPCR(a6),fpcr 187 fmul.x pls_huge,fp0 188 fmove.l fpsr,d1 189 or.l d1,d0 190 fmove.l d0,fpsr 191 rts 192 * 193 * t_inx2 --- INEX2 exception (correct fpcr is in USER_FPCR(a6)) 194 * 195 xdef t_inx2 196 t_inx2: 197 fmove.l fpsr,USER_FPSR(a6) capture incoming fpsr 198 fmove.l USER_FPCR(a6),fpcr 199 * 200 * create an inex2 exception by adding two numbers with very different exponents 201 * do the add in fp1 so as to not disturb the result sitting in fp0 202 * 203 fmove.x pls_one,fp1 204 fadd.x small,fp1 205 * 206 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX 207 fmove.l USER_FPSR(a6),fpsr 208 rts 209 * 210 * t_frcinx --- Force Inex2 (for monadic functions) 211 * 212 xdef t_frcinx 213 t_frcinx: 214 fmove.l fpsr,USER_FPSR(a6) capture incoming fpsr 215 fmove.l d1,fpcr 216 * 217 * create an inex2 exception by adding two numbers with very different exponents 218 * do the add in fp1 so as to not disturb the result sitting in fp0 219 * 220 fmove.x pls_one,fp1 221 fadd.x small,fp1 222 * 223 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX 224 btst.b #unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set 225 beq.b no_uacc1 ;if clear, do not set aunfl 226 bset.b #aunfl_bit,FPSR_AEXCEPT(a6) 227 no_uacc1: 228 fmove.l USER_FPSR(a6),fpsr 229 rts 230 * 231 * dst_nan --- force result when destination is a NaN 232 * 233 xdef dst_nan 234 dst_nan: 235 fmove.l USER_FPCR(a6),fpcr 236 fmove.x FPTEMP(a6),fp0 237 rts 238 239 * 240 * src_nan --- force result when source is a NaN 241 * 242 xdef src_nan 243 src_nan: 244 fmove.l USER_FPCR(a6),fpcr 245 fmove.x ETEMP(a6),fp0 246 rts 247 * 248 * mon_nan --- force result when source is a NaN (monadic version) 249 * 250 * This is the same as src_nan except that the user's fpcr comes 251 * in via d1, not USER_FPCR(a6). 252 * 253 xdef mon_nan 254 mon_nan: 255 fmove.l d1,fpcr 256 fmove.x ETEMP(a6),fp0 257 rts 258 * 259 * t_extdnrm, t_resdnrm --- generate results for denorm inputs 260 * 261 * For all functions that have a denormalized input and that f(x)=x, 262 * this is the entry point. 263 * 264 xdef t_extdnrm 265 t_extdnrm: 266 fmove.l d1,fpcr 267 fmove.x LOCAL_EX(a0),fp0 268 fmove.l fpsr,d0 269 or.l #unfinx_mask,d0 270 fmove.l d0,fpsr 271 rts 272 273 xdef t_resdnrm 274 t_resdnrm: 275 fmove.l USER_FPCR(a6),fpcr 276 fmove.x LOCAL_EX(a0),fp0 277 fmove.l fpsr,d0 278 or.l #unfl_mask,d0 279 fmove.l d0,fpsr 280 rts 281 * 282 * 283 * 284 xdef t_avoid_unsupp 285 t_avoid_unsupp: 286 fmove.x fp0,fp0 287 rts 288 289 xdef sto_cos 290 sto_cos: 291 fmovem.x LOCAL_EX(a0),fp1 292 rts 293 * 294 * Native instruction support 295 * 296 * Some systems may need entry points even for 68040 native 297 * instructions. These routines are provided for 298 * convenience. 299 * 300 xdef sadd 301 sadd: 302 fmovem.x FPTEMP(a6),fp0 303 fmove.l USER_FPCR(a6),fpcr 304 fadd.x ETEMP(a6),fp0 305 rts 306 307 xdef ssub 308 ssub: 309 fmovem.x FPTEMP(a6),fp0 310 fmove.l USER_FPCR(a6),fpcr 311 fsub.x ETEMP(a6),fp0 312 rts 313 314 xdef smul 315 smul: 316 fmovem.x FPTEMP(a6),fp0 317 fmove.l USER_FPCR(a6),fpcr 318 fmul.x ETEMP(a6),fp0 319 rts 320 321 xdef sdiv 322 sdiv: 323 fmovem.x FPTEMP(a6),fp0 324 fmove.l USER_FPCR(a6),fpcr 325 fdiv.x ETEMP(a6),fp0 326 rts 327 328 xdef sabs 329 sabs: 330 fmovem.x ETEMP(a6),fp0 331 fmove.l d1,fpcr 332 fabs.x fp0 333 rts 334 335 xdef sneg 336 sneg: 337 fmovem.x ETEMP(a6),fp0 338 fmove.l d1,fpcr 339 fneg.x fp0 340 rts 341 342 xdef ssqrt 343 ssqrt: 344 fmovem.x ETEMP(a6),fp0 345 fmove.l d1,fpcr 346 fsqrt.x fp0 347 rts 348 349 * 350 * l_sint,l_sintrz,l_sintd --- special wrapper for fint and fintrz 351 * 352 * On entry, move the user's FPCR to USER_FPCR. 353 * 354 * On return from, we need to pickup the INEX2/AINEX bits 355 * that are in USER_FPSR. 356 * 357 xref sint 358 xref sintrz 359 xref sintd 360 361 xdef l_sint 362 l_sint: 363 move.l d1,USER_FPCR(a6) 364 jsr sint 365 fmove.l fpsr,d0 366 or.l USER_FPSR(a6),d0 367 fmove.l d0,fpsr 368 rts 369 370 xdef l_sintrz 371 l_sintrz: 372 move.l d1,USER_FPCR(a6) 373 jsr sintrz 374 fmove.l fpsr,d0 375 or.l USER_FPSR(a6),d0 376 fmove.l d0,fpsr 377 rts 378 379 xdef l_sintd 380 l_sintd: 381 move.l d1,USER_FPCR(a6) 382 jsr sintd 383 fmove.l fpsr,d0 384 or.l USER_FPSR(a6),d0 385 fmove.l d0,fpsr 386 rts 387 388 end 389