1 * $NetBSD: kernel_ex.sa,v 1.2 1994/10/26 07:49:12 cgd Exp $
3 * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 * M68000 Hi-Performance Microprocessor Division
5 * M68040 Software Package
7 * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
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.
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.
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.
34 * kernel_ex.sa 3.3 12/19/90
36 * This file contains routines to force exception status in the
37 * fpu for exceptional cases detected or reported within the
38 * transcendental functions. Typically, the t_xx routine will
39 * set the appropriate bits in the USER_FPSR word on the stack.
40 * The bits are tested in gen_except.sa to determine if an exceptional
41 * situation needs to be created on return from the FPSP.
44 KERNEL_EX IDNT 2,1 Motorola 040 Floating Point Software Package
50 mns_inf dc.l $ffff0000,$00000000,$00000000
51 pls_inf dc.l $7fff0000,$00000000,$00000000
52 nan dc.l $7fff0000,$ffffffff,$ffffffff
53 huge dc.l $7ffe0000,$ffffffff,$ffffffff
76 * store properly signed inf (use sign of etemp) into fp0
77 * set FPSR exception status dz bit, condition code
78 * inf bit, and accrued dz bit
80 * frestore the frame into the machine (done by unimp_hd)
82 * else dz trap enabled
83 * set exception status bit & accrued bits in FPSR
84 * set flag to disable sto_res from corrupting fp register
86 * frestore the frame into the machine (done by unimp_hd)
88 * t_dz2 is used by monadic functions such as flogn (from do_func).
89 * t_dz is used by monadic functions such as satanh (from the
90 * transcendental function).
93 bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR
94 fmove.l #0,FPSR ;clr status bits (Z set)
95 btst.b #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled
97 bra.b m_inf ;flogx always returns -inf
99 fmove.l #0,FPSR ;clr status bits (Z set)
100 btst.b #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled
105 btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos
106 beq.b p_inf ;branch if pos sign
109 fmovem.x mns_inf,fp0 ;load -inf
110 bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR
113 fmovem.x pls_inf,fp0 ;load +inf
115 or.l #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
121 btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos
123 bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR
125 or.l #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
131 * if (operr trap disabled)
132 * set FPSR exception status operr bit, condition code
133 * nan bit; Store default NAN into fp0
134 * frestore the frame into the machine (done by unimp_hd)
136 * else (operr trap enabled)
137 * set FPSR exception status operr bit, accrued operr bit
138 * set flag to disable sto_res from corrupting fp register
139 * frestore the frame into the machine (done by unimp_hd)
142 or.l #opnan_mask,USER_FPSR(a6) ;set NaN, OPERR, AIOP
144 btst.b #operr_bit,FPCR_ENABLE(a6) ;test FPCR for operr enabled
147 fmovem.x nan,fp0 ;load default nan
150 st.b STORE_FLG(a6) ;do not corrupt destination
154 * t_unfl --- UNFL exception
156 * This entry point is used by all routines requiring unfl, inex2,
157 * aunfl, and ainex to be set on exit.
159 * On entry, a0 points to the exceptional operand. The final exceptional
160 * operand is built in FP_SCR1 and only the sign from the original operand
164 clr.l FP_SCR1(a6) ;set exceptional operand to zero
167 tst.b (a0) ;extract sign from caller's exop
169 bset #sign_bit,FP_SCR1(a6)
172 or.l #unfinx_mask,USER_FPSR(a6)
173 * ;set UNFL, INEX2, AUNFL, AINEX
175 btst.b #unfl_bit,FPCR_ENABLE(a6)
179 bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0
180 bset.b #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
181 bset.b #sticky_bit,STICKY(a6) ;set sticky bit
183 bclr.b #E1,E_BYTE(a6)
186 bfextu FPCR_MODE(a6){0:2},d0 ;get round precision
188 bclr.b #sign_bit,LOCAL_EX(a0)
189 sne LOCAL_SGN(a0) ;convert to internal ext format
191 bsr unf_sub ;returns IEEE result at a0
192 * ;and sets FPSR_CC accordingly
194 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
197 bset.b #sign_bit,LOCAL_EX(a0)
198 bset.b #sign_bit,FP_SCR1(a6) ;set sign bit of exc operand
201 fmovem.x (a0),fp0 ;store result in fp0
206 * t_ovfl2 --- OVFL exception (without inex2 returned)
208 * This entry is used by scale to force catastrophic overflow. The
209 * ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
212 or.l #ovfl_inx_mask,USER_FPSR(a6)
213 move.l ETEMP(a6),FP_SCR1(a6)
214 move.l ETEMP_HI(a6),FP_SCR1+4(a6)
215 move.l ETEMP_LO(a6),FP_SCR1+8(a6)
217 * Check for single or double round precision. If single, check if
218 * the lower 40 bits of ETEMP are zero; if not, set inex2. If double,
219 * check if the lower 21 bits are zero; if not, set inex2.
221 move.b FPCR_MODE(a6),d0
223 beq.w t_work ;if extended, finish ovfl processing
224 cmpi.b #$40,d0 ;test for single
229 move.l ETEMP_HI(a6),d0
230 andi.l #$ff,d0 ;look at only lower 8 bits
234 move.l ETEMP_LO(a6),d0
235 andi.l #$7ff,d0 ;look at only lower 11 bits
238 or.l #inex2_mask,USER_FPSR(a6)
241 * t_ovfl --- OVFL exception
243 *** Note: the exc operand is returned in ETEMP.
246 or.l #ovfinx_mask,USER_FPSR(a6)
248 btst.b #ovfl_bit,FPCR_ENABLE(a6) ;test FPCR for ovfl enabled
252 clr.l FP_SCR1(a6) ;set exceptional operand
256 bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0
257 bclr.b #wbtemp15_bit,WB_BYTE(a6) ;clear wbtemp15
258 bset.b #sticky_bit,STICKY(a6) ;set sticky bit
260 bclr.b #E1,E_BYTE(a6)
261 * ;fall through to disabled case
263 * For disabled overflow call 'ovf_r_k'. This routine loads the
264 * correct result based on the rounding precision, destination
265 * format, rounding mode and sign.
268 bsr ovf_r_k ;returns unsigned ETEMP_EX
269 * ;and sets FPSR_CC accordingly.
270 bfclr ETEMP_SGN(a6){0:8} ;fix sign
272 bset.b #sign_bit,ETEMP_EX(a6)
273 bset.b #sign_bit,FP_SCR1(a6) ;set exceptional operand sign
275 fmovem.x ETEMP(a6),fp0 ;move the result to fp0
282 * The inex2 and ainex bits are set.
285 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
291 * This routine is called by the transcendental routines to force
292 * the inex2 exception bits set in the FPSR. If the underflow bit
293 * is set, but the underflow trap was not taken, the aunfl bit in
294 * the FPSR must be set.
297 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
298 btst.b #unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
299 beq.b no_uacc1 ;if clear, do not set aunfl
300 bset.b #aunfl_bit,FPSR_AEXCEPT(a6)
307 * Determine if the destination nan is signalling or non-signalling,
308 * and set the FPSR bits accordingly. See the MC68040 User's Manual
309 * section 3.2.2.5 NOT-A-NUMBERS.
312 btst.b #sign_bit,FPTEMP_EX(a6) ;test sign of nan
313 beq.b dst_pos ;if clr, it was positive
314 bset.b #neg_bit,FPSR_CC(a6) ;set N bit
316 btst.b #signan_bit,FPTEMP_HI(a6) ;check if signalling
317 beq.b dst_snan ;branch if signalling
319 fmove.l d1,fpcr ;restore user's rmode/prec
320 fmove.x FPTEMP(a6),fp0 ;return the non-signalling nan
322 * Check the source nan. If it is signalling, snan will be reported.
328 btst.b #signan_bit,ETEMP_HI(a6) ;check if signalling
330 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
335 btst.b #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
336 beq.b dst_dis ;branch if disabled
338 or.b #nan_tag,DTAG(a6) ;set up dtag for nan
339 st.b STORE_FLG(a6) ;do not store a result
340 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
344 bset.b #signan_bit,FPTEMP_HI(a6) ;set SNAN bit in sop
345 fmove.l d1,fpcr ;restore user's rmode/prec
346 fmove.x FPTEMP(a6),fp0 ;load non-sign. nan
347 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
353 * Determine if the source nan is signalling or non-signalling,
354 * and set the FPSR bits accordingly. See the MC68040 User's Manual
355 * section 3.2.2.5 NOT-A-NUMBERS.
358 btst.b #sign_bit,ETEMP_EX(a6) ;test sign of nan
359 beq.b src_pos ;if clr, it was positive
360 bset.b #neg_bit,FPSR_CC(a6) ;set N bit
362 btst.b #signan_bit,ETEMP_HI(a6) ;check if signalling
363 beq.b src_snan ;branch if signalling
364 fmove.l d1,fpcr ;restore user's rmode/prec
365 fmove.x ETEMP(a6),fp0 ;return the non-signalling nan
369 btst.b #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
370 beq.b src_dis ;branch if disabled
371 bset.b #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
372 or.b #norm_tag,DTAG(a6) ;set up dtag for norm
373 or.b #nan_tag,STAG(a6) ;set up stag for nan
374 st.b STORE_FLG(a6) ;do not store a result
375 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
379 bset.b #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
380 fmove.l d1,fpcr ;restore user's rmode/prec
381 fmove.x ETEMP(a6),fp0 ;load non-sign. nan
382 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
386 * For all functions that have a denormalized input and that f(x)=x,
387 * this is the entry point
390 or.l #unfinx_mask,USER_FPSR(a6)
391 * ;set UNFL, INEX2, AUNFL, AINEX
394 * Entry point for scale with extended denorm. The function does
395 * not set inex2, aunfl, or ainex.
398 or.l #unfl_mask,USER_FPSR(a6)
401 btst.b #unfl_bit,FPCR_ENABLE(a6)
405 * If exceptions are enabled, the additional task of setting up WBTEMP
406 * is needed so that when the underflow exception handler is entered,
407 * the user perceives no difference between what the 040 provides vs.
408 * what the FPSP provides.
413 move.l LOCAL_EX(a0),FP_SCR1(a6)
414 move.l LOCAL_HI(a0),FP_SCR1+4(a6)
415 move.l LOCAL_LO(a0),FP_SCR1+8(a6)
419 bclr.b #sign_bit,LOCAL_EX(a0)
420 sne LOCAL_SGN(a0) ;convert to internal ext format
421 tst.w LOCAL_EX(a0) ;check if input is denorm
422 beq.b xdnrm_dn ;if so, skip nrm_set
423 bsr nrm_set ;normalize the result (exponent
426 bclr.b #sign_bit,LOCAL_EX(a0) ;take off false sign
427 bfclr LOCAL_SGN(a0){0:8} ;change back to IEEE ext format
429 bset.b #sign_bit,LOCAL_EX(a0)
431 bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0
432 bset.b #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
433 bclr.b #sticky_bit,STICKY(a6) ;clear sticky bit
434 bclr.b #E1,E_BYTE(a6)
437 bfextu FPCR_MODE(a6){0:2},d0 ;get round precision
438 bne.b not_ext ;if not round extended, store
441 btst.b #sign_bit,LOCAL_EX(a0)
444 bset.b #neg_bit,FPSR_CC(a6) ;set N bit in FPSR_CC
449 bclr.b #sign_bit,LOCAL_EX(a0)
450 sne LOCAL_SGN(a0) ;convert to internal ext format
451 bsr unf_sub ;returns IEEE result pointed by
452 * ;a0; sets FPSR_CC accordingly
453 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
455 bset.b #sign_bit,LOCAL_EX(a0)
457 fmovem.x (a0),fp0 ;store result in fp0
461 * This subroutine is used for dyadic operations that use an extended
462 * denorm within the kernel. The approach used is to capture the frame,
467 link a2,#-LOCAL_SIZE ;so that a2 fpsp.h negative
468 * ;offsets may be used
470 tst.b 1(a7) ;check if idle, exit if so
472 btst.b #E1,E_BYTE(a2) ;check for an E1 exception if
473 * ;enabled, there is an unsupp
474 beq.w end_avun ;else, exit
475 btst.b #7,DTAG(a2) ;check for denorm destination
476 beq.b src_den ;else, must be a source denorm
478 * handle destination denorm
481 btst.b #sign_bit,LOCAL_EX(a0)
482 sne LOCAL_SGN(a0) ;convert to internal ext format
483 bclr.b #7,DTAG(a2) ;set DTAG to norm
484 bsr nrm_set ;normalize result, exponent
485 * ;will become negative
486 bclr.b #sign_bit,LOCAL_EX(a0) ;get rid of fake sign
487 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
488 beq.b ck_src_den ;check if source is also denorm
489 bset.b #sign_bit,LOCAL_EX(a0)
495 btst.b #sign_bit,LOCAL_EX(a0)
496 sne LOCAL_SGN(a0) ;convert to internal ext format
497 bclr.b #7,STAG(a2) ;set STAG to norm
498 bsr nrm_set ;normalize result, exponent
499 * ;will become negative
500 bclr.b #sign_bit,LOCAL_EX(a0) ;get rid of fake sign
501 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
503 bset.b #sign_bit,LOCAL_EX(a0)
505 move.b #$fe,CU_SAVEPC(a2) ;set continue frame
506 clr.w NMNEXC(a2) ;clear NMNEXC
507 bclr.b #E1,E_BYTE(a2)
508 * fmove.l FPSR,FPSR_SHADOW(a2)
509 * bset.b #SFLAG,E_BYTE(a2)
510 * bset.b #XFLAG,T_BYTE(a2)