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 37L_SUPPORT IDNT 2,1 Motorola 040 Floating Point Software Package 38 39 section 8 40 41mns_one dc.l $bfff0000,$80000000,$00000000 42pls_one dc.l $3fff0000,$80000000,$00000000 43pls_inf dc.l $7fff0000,$00000000,$00000000 44pls_huge dc.l $7ffe0000,$ffffffff,$ffffffff 45mns_huge dc.l $fffe0000,$ffffffff,$ffffffff 46pls_tiny dc.l $00000000,$80000000,$00000000 47mns_tiny dc.l $80000000,$80000000,$00000000 48small dc.l $20000000,$80000000,$00000000 49pls_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 69tag: 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 75tag_nrm: 76 clr.b d0 77 rts 78tag_nan: 79 move.b #$60,d0 80 rts 81tag_dnrm: 82 move.b #$80,d0 83 rts 84chk_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 91tag_zero: 92 move.b #$20,d0 93 rts 94chk_inf: 95 tst.l LOCAL_HI(a0) 96 bne.b tag_nan 97 tst.l LOCAL_LO(a0) 98 bne.b tag_nan 99tag_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 111t_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 118t_dz: 119 btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos 120 beq.b p_inf ;branch if pos sign 121m_inf: 122 fmovem.x mns_one,fp0 123 fmove.l d1,fpcr 124 fdiv.x pls_zero,fp0 125 rts 126p_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 135t_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 145t_unfl: 146 btst.b #sign_bit,ETEMP(a6) 147 beq.b unf_pos 148unf_neg: 149 fmovem.x mns_tiny,fp0 150 fmove.l d1,fpcr 151 fmul.x pls_tiny,fp0 152 rts 153 154unf_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 166t_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 171t_ovfl2: 172 move.l #ovfl_inx_mask,d0 173t_work: 174 btst.b #sign_bit,ETEMP(a6) 175 beq.b ovf_pos 176ovf_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 184ovf_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 196t_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 213t_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) 227no_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 234dst_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 243src_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 254mon_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 265t_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 274t_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 285t_avoid_unsupp: 286 fmove.x fp0,fp0 287 rts 288 289 xdef sto_cos 290sto_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 301sadd: 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 308ssub: 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 315smul: 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 322sdiv: 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 329sabs: 330 fmovem.x ETEMP(a6),fp0 331 fmove.l d1,fpcr 332 fabs.x fp0 333 rts 334 335 xdef sneg 336sneg: 337 fmovem.x ETEMP(a6),fp0 338 fmove.l d1,fpcr 339 fneg.x fp0 340 rts 341 342 xdef ssqrt 343ssqrt: 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 362l_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 371l_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 380l_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