make.tmpl: add missing compiler attribute to build_progs
[AROS.git] / arch / m68k-all / m680x0 / fpsp / x_unfl.sa
blob776ed187d1407b816c2d4e24ca4397242f1dc373
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.
8 *       All rights reserved.
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 
45 * destination format.
46 *               
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
55         section 8
57         include fpsp.h
59         xref    denorm
60         xref    round
61         xref    store
62         xref    g_rndpr
63         xref    g_opcls
64         xref    g_dfmtou
65         xref    real_unfl
66         xref    real_inex
67         xref    fpsp_done
68         xref    b1238_fix
70         xdef    fpsp_unfl
71 fpsp_unfl:
72         link            a6,#-LOCAL_SIZE
73         fsave           -(a7)
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
82 * exception
84         btst.b          #unfl_bit,FPCR_ENABLE(a6)
85         beq.b           ck_inex
87         btst.b          #E3,E_BYTE(a6)
88         beq.b           no_e3_1
90 * Clear dirty bit on dest resister in the frame before branching
91 * to b1238_fix.
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)
98 no_e3_1:
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
102         frestore        (a7)+
103         unlk            a6
104         bra.l           real_unfl
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
109 * real inex handler.
111 ck_inex:
112         move.b          FPCR_ENABLE(a6),d0
113         and.b           FPSR_EXCEPT(a6),d0
114         andi.b          #$3,d0
115         beq.b           unfl_done
118 * Inexact enabled and reported, and we must take an inexact exception
119 *       
120 take_inex:
121         btst.b          #E3,E_BYTE(a6)
122         beq.b           no_e3_2
124 * Clear dirty bit on dest resister in the frame before branching
125 * to b1238_fix.
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)
132 no_e3_2:
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
137         frestore        (a7)+
138         unlk            a6
139         bra.l           real_inex
141 unfl_done:
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
146 * to b1238_fix.
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
156         frestore        (a7)+
157         unlk            a6
158         bra.l           fpsp_done
159 e1_set:
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
163         unlk            a6
164         bra.l           fpsp_done
166 *       unf_res --- underflow result calculation
168 unf_res:
169         bsr.l           g_rndpr         ;returns RND_PREC in d0 0=ext,
170 *                                       ;1=sgl, 2=dbl
171 *                                       ;we need the RND_PREC in the
172 *                                       ;upper word for round
173         clr.w           -(a7)   
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)
181         beq.b           unf_E1
182 unf_E3:
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
190         andi.w          #$7f,d1
191         cmpi.w          #$30,d1         ;check for sgldiv
192         beq.b           unf_sgl
193         cmpi.w          #$33,d1         ;check for sglmul
194         bne.b           unf_cont        ;if not, use fpcr prec in round
195 unf_sgl:
196         clr.l           d0
197         move.w          #$1,(a7)        ;override g_rndpr precision
198 *                                       ;force single
199         bra.b           unf_cont
200 unf_E1:
201         lea             FPTEMP(a6),a0   ;a0 now points to operand
202 unf_cont:
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
208 * WARNING:
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
219 *                                               ;mode in lower d1
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.
227 * Perform Round 
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
239 unf_store:
240         bsr.l           g_opcls         ;returns opclass in d0{2:0}
241         cmpi.b          #$3,d0
242         bne.b           not_opc011
244 * At this point, a store to memory is pending
246 opc011:
247         bsr.l           g_dfmtou
248         tst.b           d0
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
252 *                                       ;subtract
253         bmi.b           ext_opc011
254         subq.w          #1,LOCAL_EX(a0) ;account for denorm bias vs.
255 *                               ;normalized bias
256 *                               ;          normalized   denormalized
257 *                               ;single       $7f           $7e
258 *                               ;double       $3ff          $3fe
260 ext_opc011:
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
267 not_opc011:
268         bsr.l           store   ;stores to float register
269 *                               ;a0 is not corrupted on a store to a
270 *                               ;float register.
272 * Set the condition codes according to result
274         tst.l           LOCAL_HI(a0)    ;check upper mantissa
275         bne.b           ck_sgn
276         tst.l           LOCAL_LO(a0)    ;check lower mantissa
277         bne.b           ck_sgn
278         bset.b          #z_bit,FPSR_CC(a6) ;set condition codes if zero
279 ck_sgn:
280         btst.b          #sign_bit,LOCAL_EX(a0)  ;check the sign bit
281         beq.b           unf_done
282         bset.b          #neg_bit,FPSR_CC(a6)
285 * Finish.  
287 unf_done:
288         btst.b          #inex2_bit,FPSR_EXCEPT(a6)
289         beq.b           no_aunfl
290         bset.b          #aunfl_bit,FPSR_AEXCEPT(a6)
291 no_aunfl:
292         rts
294         end