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