kernel_ex.sa revision 1.1 1 * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
2 * M68000 Hi-Performance Microprocessor Division
3 * M68040 Software Package
4 *
5 * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
6 * All rights reserved.
7 *
8 * THE SOFTWARE is provided on an "AS IS" basis and without warranty.
9 * To the maximum extent permitted by applicable law,
10 * MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
11 * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
12 * PARTICULAR PURPOSE and any warranty against infringement with
13 * regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
14 * and any accompanying written materials.
15 *
16 * To the maximum extent permitted by applicable law,
17 * IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
18 * (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
19 * PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
20 * OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
21 * SOFTWARE. Motorola assumes no responsibility for the maintenance
22 * and support of the SOFTWARE.
23 *
24 * You are hereby granted a copyright license to use, modify, and
25 * distribute the SOFTWARE so long as this entire notice is retained
26 * without alteration in any modified and/or redistributed versions,
27 * and that such modified versions are clearly identified as such.
28 * No licenses are granted by implication, estoppel or otherwise
29 * under any patents or trademarks of Motorola, Inc.
30
31 *
32 * kernel_ex.sa 3.3 12/19/90
33 *
34 * This file contains routines to force exception status in the
35 * fpu for exceptional cases detected or reported within the
36 * transcendental functions. Typically, the t_xx routine will
37 * set the appropriate bits in the USER_FPSR word on the stack.
38 * The bits are tested in gen_except.sa to determine if an exceptional
39 * situation needs to be created on return from the FPSP.
40 *
41
42 KERNEL_EX IDNT 2,1 Motorola 040 Floating Point Software Package
43
44 section 8
45
46 include fpsp.h
47
48 mns_inf dc.l $ffff0000,$00000000,$00000000
49 pls_inf dc.l $7fff0000,$00000000,$00000000
50 nan dc.l $7fff0000,$ffffffff,$ffffffff
51 huge dc.l $7ffe0000,$ffffffff,$ffffffff
52
53 xref ovf_r_k
54 xref unf_sub
55 xref nrm_set
56
57 xdef t_dz
58 xdef t_dz2
59 xdef t_operr
60 xdef t_unfl
61 xdef t_ovfl
62 xdef t_ovfl2
63 xdef t_inx2
64 xdef t_frcinx
65 xdef t_extdnrm
66 xdef t_resdnrm
67 xdef dst_nan
68 xdef src_nan
69 *
70 * DZ exception
71 *
72 *
73 * if dz trap disabled
74 * store properly signed inf (use sign of etemp) into fp0
75 * set FPSR exception status dz bit, condition code
76 * inf bit, and accrued dz bit
77 * return
78 * frestore the frame into the machine (done by unimp_hd)
79 *
80 * else dz trap enabled
81 * set exception status bit & accrued bits in FPSR
82 * set flag to disable sto_res from corrupting fp register
83 * return
84 * frestore the frame into the machine (done by unimp_hd)
85 *
86 * t_dz2 is used by monadic functions such as flogn (from do_func).
87 * t_dz is used by monadic functions such as satanh (from the
88 * transcendental function).
89 *
90 t_dz2:
91 bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR
92 fmove.l #0,FPSR ;clr status bits (Z set)
93 btst.b #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled
94 bne.b dz_ena_end
95 bra.b m_inf ;flogx always returns -inf
96 t_dz:
97 fmove.l #0,FPSR ;clr status bits (Z set)
98 btst.b #dz_bit,FPCR_ENABLE(a6) ;test FPCR for dz exc enabled
99 bne.b dz_ena
100 *
101 * dz disabled
102 *
103 btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos
104 beq.b p_inf ;branch if pos sign
105
106 m_inf:
107 fmovem.x mns_inf,fp0 ;load -inf
108 bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR
109 bra.b set_fpsr
110 p_inf:
111 fmovem.x pls_inf,fp0 ;load +inf
112 set_fpsr:
113 or.l #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
114 rts
115 *
116 * dz enabled
117 *
118 dz_ena:
119 btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos
120 beq.b dz_ena_end
121 bset.b #neg_bit,FPSR_CC(a6) ;set neg bit in FPSR
122 dz_ena_end:
123 or.l #dzinf_mask,USER_FPSR(a6) ;set I,DZ,ADZ
124 st.b STORE_FLG(a6)
125 rts
126 *
127 * OPERR exception
128 *
129 * if (operr trap disabled)
130 * set FPSR exception status operr bit, condition code
131 * nan bit; Store default NAN into fp0
132 * frestore the frame into the machine (done by unimp_hd)
133 *
134 * else (operr trap enabled)
135 * set FPSR exception status operr bit, accrued operr bit
136 * set flag to disable sto_res from corrupting fp register
137 * frestore the frame into the machine (done by unimp_hd)
138 *
139 t_operr:
140 or.l #opnan_mask,USER_FPSR(a6) ;set NaN, OPERR, AIOP
141
142 btst.b #operr_bit,FPCR_ENABLE(a6) ;test FPCR for operr enabled
143 bne.b op_ena
144
145 fmovem.x nan,fp0 ;load default nan
146 rts
147 op_ena:
148 st.b STORE_FLG(a6) ;do not corrupt destination
149 rts
150
151 *
152 * t_unfl --- UNFL exception
153 *
154 * This entry point is used by all routines requiring unfl, inex2,
155 * aunfl, and ainex to be set on exit.
156 *
157 * On entry, a0 points to the exceptional operand. The final exceptional
158 * operand is built in FP_SCR1 and only the sign from the original operand
159 * is used.
160 *
161 t_unfl:
162 clr.l FP_SCR1(a6) ;set exceptional operand to zero
163 clr.l FP_SCR1+4(a6)
164 clr.l FP_SCR1+8(a6)
165 tst.b (a0) ;extract sign from caller's exop
166 bpl.b unfl_signok
167 bset #sign_bit,FP_SCR1(a6)
168 unfl_signok:
169 lea.l FP_SCR1(a6),a0
170 or.l #unfinx_mask,USER_FPSR(a6)
171 * ;set UNFL, INEX2, AUNFL, AINEX
172 unfl_con:
173 btst.b #unfl_bit,FPCR_ENABLE(a6)
174 beq.b unfl_dis
175
176 unfl_ena:
177 bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0
178 bset.b #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
179 bset.b #sticky_bit,STICKY(a6) ;set sticky bit
180
181 bclr.b #E1,E_BYTE(a6)
182
183 unfl_dis:
184 bfextu FPCR_MODE(a6){0:2},d0 ;get round precision
185
186 bclr.b #sign_bit,LOCAL_EX(a0)
187 sne LOCAL_SGN(a0) ;convert to internal ext format
188
189 bsr unf_sub ;returns IEEE result at a0
190 * ;and sets FPSR_CC accordingly
191
192 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
193 beq.b unfl_fin
194
195 bset.b #sign_bit,LOCAL_EX(a0)
196 bset.b #sign_bit,FP_SCR1(a6) ;set sign bit of exc operand
197
198 unfl_fin:
199 fmovem.x (a0),fp0 ;store result in fp0
200 rts
201
202
203 *
204 * t_ovfl2 --- OVFL exception (without inex2 returned)
205 *
206 * This entry is used by scale to force catastrophic overflow. The
207 * ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
208 *
209 t_ovfl2:
210 or.l #ovfl_inx_mask,USER_FPSR(a6)
211 move.l ETEMP(a6),FP_SCR1(a6)
212 move.l ETEMP_HI(a6),FP_SCR1+4(a6)
213 move.l ETEMP_LO(a6),FP_SCR1+8(a6)
214 *
215 * Check for single or double round precision. If single, check if
216 * the lower 40 bits of ETEMP are zero; if not, set inex2. If double,
217 * check if the lower 21 bits are zero; if not, set inex2.
218 *
219 move.b FPCR_MODE(a6),d0
220 andi.b #$c0,d0
221 beq.w t_work ;if extended, finish ovfl processing
222 cmpi.b #$40,d0 ;test for single
223 bne.b t_dbl
224 t_sgl:
225 tst.b ETEMP_LO(a6)
226 bne.b t_setinx2
227 move.l ETEMP_HI(a6),d0
228 andi.l #$ff,d0 ;look at only lower 8 bits
229 bne.b t_setinx2
230 bra.w t_work
231 t_dbl:
232 move.l ETEMP_LO(a6),d0
233 andi.l #$7ff,d0 ;look at only lower 11 bits
234 beq.w t_work
235 t_setinx2:
236 or.l #inex2_mask,USER_FPSR(a6)
237 bra.b t_work
238 *
239 * t_ovfl --- OVFL exception
240 *
241 *** Note: the exc operand is returned in ETEMP.
242 *
243 t_ovfl:
244 or.l #ovfinx_mask,USER_FPSR(a6)
245 t_work:
246 btst.b #ovfl_bit,FPCR_ENABLE(a6) ;test FPCR for ovfl enabled
247 beq.b ovf_dis
248
249 ovf_ena:
250 clr.l FP_SCR1(a6) ;set exceptional operand
251 clr.l FP_SCR1+4(a6)
252 clr.l FP_SCR1+8(a6)
253
254 bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0
255 bclr.b #wbtemp15_bit,WB_BYTE(a6) ;clear wbtemp15
256 bset.b #sticky_bit,STICKY(a6) ;set sticky bit
257
258 bclr.b #E1,E_BYTE(a6)
259 * ;fall through to disabled case
260
261 * For disabled overflow call 'ovf_r_k'. This routine loads the
262 * correct result based on the rounding precision, destination
263 * format, rounding mode and sign.
264 *
265 ovf_dis:
266 bsr ovf_r_k ;returns unsigned ETEMP_EX
267 * ;and sets FPSR_CC accordingly.
268 bfclr ETEMP_SGN(a6){0:8} ;fix sign
269 beq.b ovf_pos
270 bset.b #sign_bit,ETEMP_EX(a6)
271 bset.b #sign_bit,FP_SCR1(a6) ;set exceptional operand sign
272 ovf_pos:
273 fmovem.x ETEMP(a6),fp0 ;move the result to fp0
274 rts
275
276
277 *
278 * INEX2 exception
279 *
280 * The inex2 and ainex bits are set.
281 *
282 t_inx2:
283 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
284 rts
285
286 *
287 * Force Inex2
288 *
289 * This routine is called by the transcendental routines to force
290 * the inex2 exception bits set in the FPSR. If the underflow bit
291 * is set, but the underflow trap was not taken, the aunfl bit in
292 * the FPSR must be set.
293 *
294 t_frcinx:
295 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
296 btst.b #unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
297 beq.b no_uacc1 ;if clear, do not set aunfl
298 bset.b #aunfl_bit,FPSR_AEXCEPT(a6)
299 no_uacc1:
300 rts
301
302 *
303 * DST_NAN
304 *
305 * Determine if the destination nan is signalling or non-signalling,
306 * and set the FPSR bits accordingly. See the MC68040 User's Manual
307 * section 3.2.2.5 NOT-A-NUMBERS.
308 *
309 dst_nan:
310 btst.b #sign_bit,FPTEMP_EX(a6) ;test sign of nan
311 beq.b dst_pos ;if clr, it was positive
312 bset.b #neg_bit,FPSR_CC(a6) ;set N bit
313 dst_pos:
314 btst.b #signan_bit,FPTEMP_HI(a6) ;check if signalling
315 beq.b dst_snan ;branch if signalling
316
317 fmove.l d1,fpcr ;restore user's rmode/prec
318 fmove.x FPTEMP(a6),fp0 ;return the non-signalling nan
319 *
320 * Check the source nan. If it is signalling, snan will be reported.
321 *
322 move.b STAG(a6),d0
323 andi.b #$e0,d0
324 cmpi.b #$60,d0
325 bne.b no_snan
326 btst.b #signan_bit,ETEMP_HI(a6) ;check if signalling
327 bne.b no_snan
328 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
329 no_snan:
330 rts
331
332 dst_snan:
333 btst.b #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
334 beq.b dst_dis ;branch if disabled
335
336 or.b #nan_tag,DTAG(a6) ;set up dtag for nan
337 st.b STORE_FLG(a6) ;do not store a result
338 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
339 rts
340
341 dst_dis:
342 bset.b #signan_bit,FPTEMP_HI(a6) ;set SNAN bit in sop
343 fmove.l d1,fpcr ;restore user's rmode/prec
344 fmove.x FPTEMP(a6),fp0 ;load non-sign. nan
345 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
346 rts
347
348 *
349 * SRC_NAN
350 *
351 * Determine if the source nan is signalling or non-signalling,
352 * and set the FPSR bits accordingly. See the MC68040 User's Manual
353 * section 3.2.2.5 NOT-A-NUMBERS.
354 *
355 src_nan:
356 btst.b #sign_bit,ETEMP_EX(a6) ;test sign of nan
357 beq.b src_pos ;if clr, it was positive
358 bset.b #neg_bit,FPSR_CC(a6) ;set N bit
359 src_pos:
360 btst.b #signan_bit,ETEMP_HI(a6) ;check if signalling
361 beq.b src_snan ;branch if signalling
362 fmove.l d1,fpcr ;restore user's rmode/prec
363 fmove.x ETEMP(a6),fp0 ;return the non-signalling nan
364 rts
365
366 src_snan:
367 btst.b #snan_bit,FPCR_ENABLE(a6) ;check if trap enabled
368 beq.b src_dis ;branch if disabled
369 bset.b #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
370 or.b #norm_tag,DTAG(a6) ;set up dtag for norm
371 or.b #nan_tag,STAG(a6) ;set up stag for nan
372 st.b STORE_FLG(a6) ;do not store a result
373 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
374 rts
375
376 src_dis:
377 bset.b #signan_bit,ETEMP_HI(a6) ;set SNAN bit in sop
378 fmove.l d1,fpcr ;restore user's rmode/prec
379 fmove.x ETEMP(a6),fp0 ;load non-sign. nan
380 or.l #snaniop_mask,USER_FPSR(a6) ;set NAN, SNAN, AIOP
381 rts
382
383 *
384 * For all functions that have a denormalized input and that f(x)=x,
385 * this is the entry point
386 *
387 t_extdnrm:
388 or.l #unfinx_mask,USER_FPSR(a6)
389 * ;set UNFL, INEX2, AUNFL, AINEX
390 bra.b xdnrm_con
391 *
392 * Entry point for scale with extended denorm. The function does
393 * not set inex2, aunfl, or ainex.
394 *
395 t_resdnrm:
396 or.l #unfl_mask,USER_FPSR(a6)
397
398 xdnrm_con:
399 btst.b #unfl_bit,FPCR_ENABLE(a6)
400 beq.b xdnrm_dis
401
402 *
403 * If exceptions are enabled, the additional task of setting up WBTEMP
404 * is needed so that when the underflow exception handler is entered,
405 * the user perceives no difference between what the 040 provides vs.
406 * what the FPSP provides.
407 *
408 xdnrm_ena:
409 move.l a0,-(a7)
410
411 move.l LOCAL_EX(a0),FP_SCR1(a6)
412 move.l LOCAL_HI(a0),FP_SCR1+4(a6)
413 move.l LOCAL_LO(a0),FP_SCR1+8(a6)
414
415 lea FP_SCR1(a6),a0
416
417 bclr.b #sign_bit,LOCAL_EX(a0)
418 sne LOCAL_SGN(a0) ;convert to internal ext format
419 tst.w LOCAL_EX(a0) ;check if input is denorm
420 beq.b xdnrm_dn ;if so, skip nrm_set
421 bsr nrm_set ;normalize the result (exponent
422 * ;will be negative
423 xdnrm_dn:
424 bclr.b #sign_bit,LOCAL_EX(a0) ;take off false sign
425 bfclr LOCAL_SGN(a0){0:8} ;change back to IEEE ext format
426 beq.b xdep
427 bset.b #sign_bit,LOCAL_EX(a0)
428 xdep:
429 bfclr STAG(a6){5:3} ;clear wbtm66,wbtm1,wbtm0
430 bset.b #wbtemp15_bit,WB_BYTE(a6) ;set wbtemp15
431 bclr.b #sticky_bit,STICKY(a6) ;clear sticky bit
432 bclr.b #E1,E_BYTE(a6)
433 move.l (a7)+,a0
434 xdnrm_dis:
435 bfextu FPCR_MODE(a6){0:2},d0 ;get round precision
436 bne.b not_ext ;if not round extended, store
437 * ;IEEE defaults
438 is_ext:
439 btst.b #sign_bit,LOCAL_EX(a0)
440 beq.b xdnrm_store
441
442 bset.b #neg_bit,FPSR_CC(a6) ;set N bit in FPSR_CC
443
444 bra.b xdnrm_store
445
446 not_ext:
447 bclr.b #sign_bit,LOCAL_EX(a0)
448 sne LOCAL_SGN(a0) ;convert to internal ext format
449 bsr unf_sub ;returns IEEE result pointed by
450 * ;a0; sets FPSR_CC accordingly
451 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
452 beq.b xdnrm_store
453 bset.b #sign_bit,LOCAL_EX(a0)
454 xdnrm_store:
455 fmovem.x (a0),fp0 ;store result in fp0
456 rts
457
458 *
459 * This subroutine is used for dyadic operations that use an extended
460 * denorm within the kernel. The approach used is to capture the frame,
461 * fix/restore.
462 *
463 xdef t_avoid_unsupp
464 t_avoid_unsupp:
465 link a2,#-LOCAL_SIZE ;so that a2 fpsp.h negative
466 * ;offsets may be used
467 fsave -(a7)
468 tst.b 1(a7) ;check if idle, exit if so
469 beq.w idle_end
470 btst.b #E1,E_BYTE(a2) ;check for an E1 exception if
471 * ;enabled, there is an unsupp
472 beq.w end_avun ;else, exit
473 btst.b #7,DTAG(a2) ;check for denorm destination
474 beq.b src_den ;else, must be a source denorm
475 *
476 * handle destination denorm
477 *
478 lea FPTEMP(a2),a0
479 btst.b #sign_bit,LOCAL_EX(a0)
480 sne LOCAL_SGN(a0) ;convert to internal ext format
481 bclr.b #7,DTAG(a2) ;set DTAG to norm
482 bsr nrm_set ;normalize result, exponent
483 * ;will become negative
484 bclr.b #sign_bit,LOCAL_EX(a0) ;get rid of fake sign
485 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
486 beq.b ck_src_den ;check if source is also denorm
487 bset.b #sign_bit,LOCAL_EX(a0)
488 ck_src_den:
489 btst.b #7,STAG(a2)
490 beq.b end_avun
491 src_den:
492 lea ETEMP(a2),a0
493 btst.b #sign_bit,LOCAL_EX(a0)
494 sne LOCAL_SGN(a0) ;convert to internal ext format
495 bclr.b #7,STAG(a2) ;set STAG to norm
496 bsr nrm_set ;normalize result, exponent
497 * ;will become negative
498 bclr.b #sign_bit,LOCAL_EX(a0) ;get rid of fake sign
499 bfclr LOCAL_SGN(a0){0:8} ;convert back to IEEE ext format
500 beq.b den_com
501 bset.b #sign_bit,LOCAL_EX(a0)
502 den_com:
503 move.b #$fe,CU_SAVEPC(a2) ;set continue frame
504 clr.w NMNEXC(a2) ;clear NMNEXC
505 bclr.b #E1,E_BYTE(a2)
506 * fmove.l FPSR,FPSR_SHADOW(a2)
507 * bset.b #SFLAG,E_BYTE(a2)
508 * bset.b #XFLAG,T_BYTE(a2)
509 end_avun:
510 frestore (a7)+
511 unlk a2
512 rts
513 idle_end:
514 add.l #4,a7
515 unlk a2
516 rts
517 end
518