Annotation of sys/arch/m68k/fpsp/x_unfl.sa, Revision 1.1.1.1
1.1 nbrk 1: * $OpenBSD: x_unfl.sa,v 1.3 2001/09/20 17:02:30 mpech Exp $
2: * $NetBSD: x_unfl.sa,v 1.3 1994/10/26 07:50:30 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: * x_unfl.sa 3.4 7/1/91
36: *
37: * fpsp_unfl --- FPSP handler for underflow exception
38: *
39: * Trap disabled results
40: * For 881/2 compatibility, sw must denormalize the intermediate
41: * result, then store the result. Denormalization is accomplished
42: * by taking the intermediate result (which is always normalized) and
43: * shifting the mantissa right while incrementing the exponent until
44: * it is equal to the denormalized exponent for the destination
45: * format. After denormalizatoin, the result is rounded to the
46: * destination format.
47: *
48: * Trap enabled results
49: * All trap disabled code applies. In addition the exceptional
50: * operand needs to made available to the user with a bias of $6000
51: * added to the exponent.
52: *
53:
54: X_UNFL IDNT 2,1 Motorola 040 Floating Point Software Package
55:
56: section 8
57:
58: include fpsp.h
59:
60: xref denorm
61: xref round
62: xref store
63: xref g_rndpr
64: xref g_opcls
65: xref g_dfmtou
66: xref real_unfl
67: xref real_inex
68: xref fpsp_done
69: xref b1238_fix
70:
71: xdef fpsp_unfl
72: fpsp_unfl:
73: link a6,#-LOCAL_SIZE
74: fsave -(a7)
75: movem.l d0-d1/a0-a1,USER_DA(a6)
76: fmovem.x fp0-fp3,USER_FP0(a6)
77: fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6)
78:
79: *
80: bsr.l unf_res ;denormalize, round & store interm op
81: *
82: * If underflow exceptions are not enabled, check for inexact
83: * exception
84: *
85: btst.b #unfl_bit,FPCR_ENABLE(a6)
86: beq.b ck_inex
87:
88: btst.b #E3,E_BYTE(a6)
89: beq.b no_e3_1
90: *
91: * Clear dirty bit on dest resister in the frame before branching
92: * to b1238_fix.
93: *
94: bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
95: bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
96: bsr.l b1238_fix ;test for bug1238 case
97: move.l USER_FPSR(a6),FPSR_SHADOW(a6)
98: or.l #sx_mask,E_BYTE(a6)
99: no_e3_1:
100: movem.l USER_DA(a6),d0-d1/a0-a1
101: fmovem.x USER_FP0(a6),fp0-fp3
102: fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
103: frestore (a7)+
104: unlk a6
105: bra.l real_unfl
106: *
107: * It is possible to have either inex2 or inex1 exceptions with the
108: * unfl. If the inex enable bit is set in the FPCR, and either
109: * inex2 or inex1 occurred, we must clean up and branch to the
110: * real inex handler.
111: *
112: ck_inex:
113: move.b FPCR_ENABLE(a6),d0
114: and.b FPSR_EXCEPT(a6),d0
115: andi.b #$3,d0
116: beq.b unfl_done
117:
118: *
119: * Inexact enabled and reported, and we must take an inexact exception
120: *
121: take_inex:
122: btst.b #E3,E_BYTE(a6)
123: beq.b no_e3_2
124: *
125: * Clear dirty bit on dest resister in the frame before branching
126: * to b1238_fix.
127: *
128: bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
129: bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
130: bsr.l b1238_fix ;test for bug1238 case
131: move.l USER_FPSR(a6),FPSR_SHADOW(a6)
132: or.l #sx_mask,E_BYTE(a6)
133: no_e3_2:
134: move.b #INEX_VEC,EXC_VEC+1(a6)
135: movem.l USER_DA(a6),d0-d1/a0-a1
136: fmovem.x USER_FP0(a6),fp0-fp3
137: fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
138: frestore (a7)+
139: unlk a6
140: bra.l real_inex
141:
142: unfl_done:
143: bclr.b #E3,E_BYTE(a6)
144: beq.b e1_set ;if set then branch
145: *
146: * Clear dirty bit on dest resister in the frame before branching
147: * to b1238_fix.
148: *
149: bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
150: bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
151: bsr.l b1238_fix ;test for bug1238 case
152: move.l USER_FPSR(a6),FPSR_SHADOW(a6)
153: or.l #sx_mask,E_BYTE(a6)
154: movem.l USER_DA(a6),d0-d1/a0-a1
155: fmovem.x USER_FP0(a6),fp0-fp3
156: fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
157: frestore (a7)+
158: unlk a6
159: bra.l fpsp_done
160: e1_set:
161: movem.l USER_DA(a6),d0-d1/a0-a1
162: fmovem.x USER_FP0(a6),fp0-fp3
163: fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
164: unlk a6
165: bra.l fpsp_done
166: *
167: * unf_res --- underflow result calculation
168: *
169: unf_res:
170: bsr.l g_rndpr ;returns RND_PREC in d0 0=ext,
171: * ;1=sgl, 2=dbl
172: * ;we need the RND_PREC in the
173: * ;upper word for round
174: clr.w -(a7)
175: move.w d0,-(a7) ;copy RND_PREC to stack
176: *
177: *
178: * If the exception bit set is E3, the exceptional operand from the
179: * fpu is in WBTEMP; else it is in FPTEMP.
180: *
181: btst.b #E3,E_BYTE(a6)
182: beq.b unf_E1
183: unf_E3:
184: lea WBTEMP(a6),a0 ;a0 now points to operand
185: *
186: * Test for fsgldiv and fsglmul. If the inst was one of these, then
187: * force the precision to extended for the denorm routine. Use
188: * the user's precision for the round routine.
189: *
190: move.w CMDREG3B(a6),d1 ;check for fsgldiv or fsglmul
191: andi.w #$7f,d1
192: cmpi.w #$30,d1 ;check for sgldiv
193: beq.b unf_sgl
194: cmpi.w #$33,d1 ;check for sglmul
195: bne.b unf_cont ;if not, use fpcr prec in round
196: unf_sgl:
197: clr.l d0
198: move.w #$1,(a7) ;override g_rndpr precision
199: * ;force single
200: bra.b unf_cont
201: unf_E1:
202: lea FPTEMP(a6),a0 ;a0 now points to operand
203: unf_cont:
204: bclr.b #sign_bit,LOCAL_EX(a0) ;clear sign bit
205: sne LOCAL_SGN(a0) ;store sign
206:
207: bsr.l denorm ;returns denorm, a0 points to it
208: *
209: * WARNING:
210: * ;d0 has guard,round sticky bit
211: * ;make sure that it is not corrupted
212: * ;before it reaches the round subroutine
213: * ;also ensure that a0 isn't corrupted
214:
215: *
216: * Set up d1 for round subroutine d1 contains the PREC/MODE
217: * information respectively on upper/lower register halves.
218: *
219: bfextu FPCR_MODE(a6){2:2},d1 ;get mode from FPCR
220: * ;mode in lower d1
221: add.l (a7)+,d1 ;merge PREC/MODE
222: *
223: * WARNING: a0 and d0 are assumed to be intact between the denorm and
224: * round subroutines. All code between these two subroutines
225: * must not corrupt a0 and d0.
226: *
227: *
228: * Perform Round
229: * Input: a0 points to input operand
230: * d0{31:29} has guard, round, sticky
231: * d1{01:00} has rounding mode
232: * d1{17:16} has rounding precision
233: * Output: a0 points to rounded operand
234: *
235:
236: bsr.l round ;returns rounded denorm at (a0)
237: *
238: * Differentiate between store to memory vs. store to register
239: *
240: unf_store:
241: bsr.l g_opcls ;returns opclass in d0{2:0}
242: cmpi.b #$3,d0
243: bne.b not_opc011
244: *
245: * At this point, a store to memory is pending
246: *
247: opc011:
248: bsr.l g_dfmtou
249: tst.b d0
250: beq.b ext_opc011 ;If extended, do not subtract
251: * ;If destination format is sgl/dbl,
252: tst.b LOCAL_HI(a0) ;If rounded result is normal,don't
253: * ;subtract
254: bmi.b ext_opc011
255: subq.w #1,LOCAL_EX(a0) ;account for denorm bias vs.
256: * ;normalized bias
257: * ; normalized denormalized
258: * ;single $7f $7e
259: * ;double $3ff $3fe
260: *
261: ext_opc011:
262: bsr.l store ;stores to memory
263: bra.b unf_done ;finish up
264:
265: *
266: * At this point, a store to a float register is pending
267: *
268: not_opc011:
269: bsr.l store ;stores to float register
270: * ;a0 is not corrupted on a store to a
271: * ;float register.
272: *
273: * Set the condition codes according to result
274: *
275: tst.l LOCAL_HI(a0) ;check upper mantissa
276: bne.b ck_sgn
277: tst.l LOCAL_LO(a0) ;check lower mantissa
278: bne.b ck_sgn
279: bset.b #z_bit,FPSR_CC(a6) ;set condition codes if zero
280: ck_sgn:
281: btst.b #sign_bit,LOCAL_EX(a0) ;check the sign bit
282: beq.b unf_done
283: bset.b #neg_bit,FPSR_CC(a6)
284:
285: *
286: * Finish.
287: *
288: unf_done:
289: btst.b #inex2_bit,FPSR_EXCEPT(a6)
290: beq.b no_aunfl
291: bset.b #aunfl_bit,FPSR_AEXCEPT(a6)
292: no_aunfl:
293: rts
294:
295: end
CVSweb