1 * $NetBSD: x_unfl.sa,v 1.4 2001/09/16 16:34:32 wiz 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 * x_unfl.sa 3.4 7/1/91
36 * fpsp_unfl --- FPSP handler for underflow exception
38 * Trap disabled results
39 * For 881/2 compatibility, sw must denormalize the intermediate
40 * result, then store the result. Denormalization is accomplished
41 * by taking the intermediate result (which is always normalized) and
42 * shifting the mantissa right while incrementing the exponent until
43 * it is equal to the denormalized exponent for the destination
44 * format. After denormalizatoin, the result is rounded to the
47 * Trap enabled results
48 * All trap disabled code applies. In addition the exceptional
49 * operand needs to made available to the user with a bias of $6000
50 * added to the exponent.
53 X_UNFL IDNT 2,1 Motorola 040 Floating Point Software Package
74 movem.l d0-d1/a0-a1,USER_DA(a6)
75 fmovem.x fp0-fp3,USER_FP0(a6)
76 fmovem.l fpcr/fpsr/fpiar,USER_FPCR(a6)
79 bsr.l unf_res ;denormalize, round & store interm op
81 * If underflow exceptions are not enabled, check for inexact
84 btst.b #unfl_bit,FPCR_ENABLE(a6)
90 * Clear dirty bit on dest resister in the frame before branching
93 bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
94 bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
95 bsr.l b1238_fix ;test for bug1238 case
96 move.l USER_FPSR(a6),FPSR_SHADOW(a6)
97 or.l #sx_mask,E_BYTE(a6)
99 movem.l USER_DA(a6),d0-d1/a0-a1
100 fmovem.x USER_FP0(a6),fp0-fp3
101 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
106 * It is possible to have either inex2 or inex1 exceptions with the
107 * unfl. If the inex enable bit is set in the FPCR, and either
108 * inex2 or inex1 occurred, we must clean up and branch to the
112 move.b FPCR_ENABLE(a6),d0
113 and.b FPSR_EXCEPT(a6),d0
118 * Inexact enabled and reported, and we must take an inexact exception
121 btst.b #E3,E_BYTE(a6)
124 * Clear dirty bit on dest resister in the frame before branching
127 bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
128 bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
129 bsr.l b1238_fix ;test for bug1238 case
130 move.l USER_FPSR(a6),FPSR_SHADOW(a6)
131 or.l #sx_mask,E_BYTE(a6)
133 move.b #INEX_VEC,EXC_VEC+1(a6)
134 movem.l USER_DA(a6),d0-d1/a0-a1
135 fmovem.x USER_FP0(a6),fp0-fp3
136 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
142 bclr.b #E3,E_BYTE(a6)
143 beq.b e1_set ;if set then branch
145 * Clear dirty bit on dest resister in the frame before branching
148 bfextu CMDREG3B(a6){6:3},d0 ;get dest reg no
149 bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
150 bsr.l b1238_fix ;test for bug1238 case
151 move.l USER_FPSR(a6),FPSR_SHADOW(a6)
152 or.l #sx_mask,E_BYTE(a6)
153 movem.l USER_DA(a6),d0-d1/a0-a1
154 fmovem.x USER_FP0(a6),fp0-fp3
155 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
160 movem.l USER_DA(a6),d0-d1/a0-a1
161 fmovem.x USER_FP0(a6),fp0-fp3
162 fmovem.l USER_FPCR(a6),fpcr/fpsr/fpiar
166 * unf_res --- underflow result calculation
169 bsr.l g_rndpr ;returns RND_PREC in d0 0=ext,
171 * ;we need the RND_PREC in the
172 * ;upper word for round
174 move.w d0,-(a7) ;copy RND_PREC to stack
177 * If the exception bit set is E3, the exceptional operand from the
178 * fpu is in WBTEMP; else it is in FPTEMP.
180 btst.b #E3,E_BYTE(a6)
183 lea WBTEMP(a6),a0 ;a0 now points to operand
185 * Test for fsgldiv and fsglmul. If the inst was one of these, then
186 * force the precision to extended for the denorm routine. Use
187 * the user's precision for the round routine.
189 move.w CMDREG3B(a6),d1 ;check for fsgldiv or fsglmul
191 cmpi.w #$30,d1 ;check for sgldiv
193 cmpi.w #$33,d1 ;check for sglmul
194 bne.b unf_cont ;if not, use fpcr prec in round
197 move.w #$1,(a7) ;override g_rndpr precision
201 lea FPTEMP(a6),a0 ;a0 now points to operand
203 bclr.b #sign_bit,LOCAL_EX(a0) ;clear sign bit
204 sne LOCAL_SGN(a0) ;store sign
206 bsr.l denorm ;returns denorm, a0 points to it
209 * ;d0 has guard,round sticky bit
210 * ;make sure that it is not corrupted
211 * ;before it reaches the round subroutine
212 * ;also ensure that a0 isn't corrupted
215 * Set up d1 for round subroutine d1 contains the PREC/MODE
216 * information respectively on upper/lower register halves.
218 bfextu FPCR_MODE(a6){2:2},d1 ;get mode from FPCR
220 add.l (a7)+,d1 ;merge PREC/MODE
222 * WARNING: a0 and d0 are assumed to be intact between the denorm and
223 * round subroutines. All code between these two subroutines
224 * must not corrupt a0 and d0.
228 * Input: a0 points to input operand
229 * d0{31:29} has guard, round, sticky
230 * d1{01:00} has rounding mode
231 * d1{17:16} has rounding precision
232 * Output: a0 points to rounded operand
235 bsr.l round ;returns rounded denorm at (a0)
237 * Differentiate between store to memory vs. store to register
240 bsr.l g_opcls ;returns opclass in d0{2:0}
244 * At this point, a store to memory is pending
249 beq.b ext_opc011 ;If extended, do not subtract
250 * ;If destination format is sgl/dbl,
251 tst.b LOCAL_HI(a0) ;If rounded result is normal,don't
254 subq.w #1,LOCAL_EX(a0) ;account for denorm bias vs.
256 * ; normalized denormalized
261 bsr.l store ;stores to memory
262 bra.b unf_done ;finish up
265 * At this point, a store to a float register is pending
268 bsr.l store ;stores to float register
269 * ;a0 is not corrupted on a store to a
272 * Set the condition codes according to result
274 tst.l LOCAL_HI(a0) ;check upper mantissa
276 tst.l LOCAL_LO(a0) ;check lower mantissa
278 bset.b #z_bit,FPSR_CC(a6) ;set condition codes if zero
280 btst.b #sign_bit,LOCAL_EX(a0) ;check the sign bit
282 bset.b #neg_bit,FPSR_CC(a6)
288 btst.b #inex2_bit,FPSR_EXCEPT(a6)
290 bset.b #aunfl_bit,FPSR_AEXCEPT(a6)