l_support.sa revision 1.3 1 * $NetBSD: l_support.sa,v 1.3 1994/10/26 07:49:16 cgd Exp $
2
3 * MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
4 * M68000 Hi-Performance Microprocessor Division
5 * M68040 Software Package
6 *
7 * M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
8 * All rights reserved.
9 *
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.
17 *
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.
25 *
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.
32
33 *
34 * l_support.sa 1.2 5/1/91
35 *
36
37 L_SUPPORT IDNT 2,1 Motorola 040 Floating Point Software Package
38
39 section 8
40
41 mns_one dc.l $bfff0000,$80000000,$00000000
42 pls_one dc.l $3fff0000,$80000000,$00000000
43 pls_inf dc.l $7fff0000,$00000000,$00000000
44 pls_huge dc.l $7ffe0000,$ffffffff,$ffffffff
45 mns_huge dc.l $fffe0000,$ffffffff,$ffffffff
46 pls_tiny dc.l $00000000,$80000000,$00000000
47 mns_tiny dc.l $80000000,$80000000,$00000000
48 small dc.l $20000000,$80000000,$00000000
49 pls_zero dc.l $00000000,$00000000,$00000000
50
51 include l_fpsp.h
52
53 *
54 * tag --- determine the type of an extended precision operand
55 *
56 * The tag values returned match the way the 68040 would have
57 * tagged them.
58 *
59 * Input: a0 points to operand
60 *
61 * Output d0.b = $00 norm
62 * $20 zero
63 * $40 inf
64 * $60 nan
65 * $80 denorm
66 * All other registers are unchanged
67 *
68 xdef tag
69 tag:
70 move.w LOCAL_EX(a0),d0
71 andi.w #$7fff,d0
72 beq.b chk_zro
73 cmpi.w #$7fff,d0
74 beq.b chk_inf
75 tag_nrm:
76 clr.b d0
77 rts
78 tag_nan:
79 move.b #$60,d0
80 rts
81 tag_dnrm:
82 move.b #$80,d0
83 rts
84 chk_zro:
85 btst.b #7,LOCAL_HI(a0) # check if J-bit is set
86 bne.b tag_nrm
87 tst.l LOCAL_HI(a0)
88 bne.b tag_dnrm
89 tst.l LOCAL_LO(a0)
90 bne.b tag_dnrm
91 tag_zero:
92 move.b #$20,d0
93 rts
94 chk_inf:
95 tst.l LOCAL_HI(a0)
96 bne.b tag_nan
97 tst.l LOCAL_LO(a0)
98 bne.b tag_nan
99 tag_inf:
100 move.b #$40,d0
101 rts
102
103 *
104 * t_dz, t_dz2 --- divide by zero exception
105 *
106 * t_dz2 is used by monadic functions such as flogn (from do_func).
107 * t_dz is used by monadic functions such as satanh (from the
108 * transcendental function).
109 *
110 xdef t_dz2
111 t_dz2:
112 fmovem.x mns_one,fp0
113 fmove.l d1,fpcr
114 fdiv.x pls_zero,fp0
115 rts
116
117 xdef t_dz
118 t_dz:
119 btst.b #sign_bit,ETEMP_EX(a6) ;check sign for neg or pos
120 beq.b p_inf ;branch if pos sign
121 m_inf:
122 fmovem.x mns_one,fp0
123 fmove.l d1,fpcr
124 fdiv.x pls_zero,fp0
125 rts
126 p_inf:
127 fmovem.x pls_one,fp0
128 fmove.l d1,fpcr
129 fdiv.x pls_zero,fp0
130 rts
131 *
132 * t_operr --- Operand Error exception
133 *
134 xdef t_operr
135 t_operr:
136 fmovem.x pls_inf,fp0
137 fmove.l d1,fpcr
138 fmul.x pls_zero,fp0
139 rts
140
141 *
142 * t_unfl --- UNFL exception
143 *
144 xdef t_unfl
145 t_unfl:
146 btst.b #sign_bit,ETEMP(a6)
147 beq.b unf_pos
148 unf_neg:
149 fmovem.x mns_tiny,fp0
150 fmove.l d1,fpcr
151 fmul.x pls_tiny,fp0
152 rts
153
154 unf_pos:
155 fmovem.x pls_tiny,fp0
156 fmove.l d1,fpcr
157 fmul.x fp0,fp0
158 rts
159 *
160 * t_ovfl --- OVFL exception
161 *
162 * t_ovfl is called as an exit for monadic functions. t_ovfl2
163 * is for dyadic exits.
164 *
165 xdef t_ovfl
166 t_ovfl:
167 xdef t_ovfl2
168 move.l d1,USER_FPCR(a6) user's control register
169 move.l #ovfinx_mask,d0
170 bra.b t_work
171 t_ovfl2:
172 move.l #ovfl_inx_mask,d0
173 t_work:
174 btst.b #sign_bit,ETEMP(a6)
175 beq.b ovf_pos
176 ovf_neg:
177 fmovem.x mns_huge,fp0
178 fmove.l USER_FPCR(a6),fpcr
179 fmul.x pls_huge,fp0
180 fmove.l fpsr,d1
181 or.l d1,d0
182 fmove.l d0,fpsr
183 rts
184 ovf_pos:
185 fmovem.x pls_huge,fp0
186 fmove.l USER_FPCR(a6),fpcr
187 fmul.x pls_huge,fp0
188 fmove.l fpsr,d1
189 or.l d1,d0
190 fmove.l d0,fpsr
191 rts
192 *
193 * t_inx2 --- INEX2 exception (correct fpcr is in USER_FPCR(a6))
194 *
195 xdef t_inx2
196 t_inx2:
197 fmove.l fpsr,USER_FPSR(a6) capture incoming fpsr
198 fmove.l USER_FPCR(a6),fpcr
199 *
200 * create an inex2 exception by adding two numbers with very different exponents
201 * do the add in fp1 so as to not disturb the result sitting in fp0
202 *
203 fmove.x pls_one,fp1
204 fadd.x small,fp1
205 *
206 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
207 fmove.l USER_FPSR(a6),fpsr
208 rts
209 *
210 * t_frcinx --- Force Inex2 (for monadic functions)
211 *
212 xdef t_frcinx
213 t_frcinx:
214 fmove.l fpsr,USER_FPSR(a6) capture incoming fpsr
215 fmove.l d1,fpcr
216 *
217 * create an inex2 exception by adding two numbers with very different exponents
218 * do the add in fp1 so as to not disturb the result sitting in fp0
219 *
220 fmove.x pls_one,fp1
221 fadd.x small,fp1
222 *
223 or.l #inx2a_mask,USER_FPSR(a6) ;set INEX2, AINEX
224 btst.b #unfl_bit,FPSR_EXCEPT(a6) ;test for unfl bit set
225 beq.b no_uacc1 ;if clear, do not set aunfl
226 bset.b #aunfl_bit,FPSR_AEXCEPT(a6)
227 no_uacc1:
228 fmove.l USER_FPSR(a6),fpsr
229 rts
230 *
231 * dst_nan --- force result when destination is a NaN
232 *
233 xdef dst_nan
234 dst_nan:
235 fmove.l USER_FPCR(a6),fpcr
236 fmove.x FPTEMP(a6),fp0
237 rts
238
239 *
240 * src_nan --- force result when source is a NaN
241 *
242 xdef src_nan
243 src_nan:
244 fmove.l USER_FPCR(a6),fpcr
245 fmove.x ETEMP(a6),fp0
246 rts
247 *
248 * mon_nan --- force result when source is a NaN (monadic version)
249 *
250 * This is the same as src_nan except that the user's fpcr comes
251 * in via d1, not USER_FPCR(a6).
252 *
253 xdef mon_nan
254 mon_nan:
255 fmove.l d1,fpcr
256 fmove.x ETEMP(a6),fp0
257 rts
258 *
259 * t_extdnrm, t_resdnrm --- generate results for denorm inputs
260 *
261 * For all functions that have a denormalized input and that f(x)=x,
262 * this is the entry point.
263 *
264 xdef t_extdnrm
265 t_extdnrm:
266 fmove.l d1,fpcr
267 fmove.x LOCAL_EX(a0),fp0
268 fmove.l fpsr,d0
269 or.l #unfinx_mask,d0
270 fmove.l d0,fpsr
271 rts
272
273 xdef t_resdnrm
274 t_resdnrm:
275 fmove.l USER_FPCR(a6),fpcr
276 fmove.x LOCAL_EX(a0),fp0
277 fmove.l fpsr,d0
278 or.l #unfl_mask,d0
279 fmove.l d0,fpsr
280 rts
281 *
282 *
283 *
284 xdef t_avoid_unsupp
285 t_avoid_unsupp:
286 fmove.x fp0,fp0
287 rts
288
289 xdef sto_cos
290 sto_cos:
291 fmovem.x LOCAL_EX(a0),fp1
292 rts
293 *
294 * Native instruction support
295 *
296 * Some systems may need entry points even for 68040 native
297 * instructions. These routines are provided for
298 * convenience.
299 *
300 xdef sadd
301 sadd:
302 fmovem.x FPTEMP(a6),fp0
303 fmove.l USER_FPCR(a6),fpcr
304 fadd.x ETEMP(a6),fp0
305 rts
306
307 xdef ssub
308 ssub:
309 fmovem.x FPTEMP(a6),fp0
310 fmove.l USER_FPCR(a6),fpcr
311 fsub.x ETEMP(a6),fp0
312 rts
313
314 xdef smul
315 smul:
316 fmovem.x FPTEMP(a6),fp0
317 fmove.l USER_FPCR(a6),fpcr
318 fmul.x ETEMP(a6),fp0
319 rts
320
321 xdef sdiv
322 sdiv:
323 fmovem.x FPTEMP(a6),fp0
324 fmove.l USER_FPCR(a6),fpcr
325 fdiv.x ETEMP(a6),fp0
326 rts
327
328 xdef sabs
329 sabs:
330 fmovem.x ETEMP(a6),fp0
331 fmove.l d1,fpcr
332 fabs.x fp0
333 rts
334
335 xdef sneg
336 sneg:
337 fmovem.x ETEMP(a6),fp0
338 fmove.l d1,fpcr
339 fneg.x fp0
340 rts
341
342 xdef ssqrt
343 ssqrt:
344 fmovem.x ETEMP(a6),fp0
345 fmove.l d1,fpcr
346 fsqrt.x fp0
347 rts
348
349 *
350 * l_sint,l_sintrz,l_sintd --- special wrapper for fint and fintrz
351 *
352 * On entry, move the user's FPCR to USER_FPCR.
353 *
354 * On return from, we need to pickup the INEX2/AINEX bits
355 * that are in USER_FPSR.
356 *
357 xref sint
358 xref sintrz
359 xref sintd
360
361 xdef l_sint
362 l_sint:
363 move.l d1,USER_FPCR(a6)
364 jsr sint
365 fmove.l fpsr,d0
366 or.l USER_FPSR(a6),d0
367 fmove.l d0,fpsr
368 rts
369
370 xdef l_sintrz
371 l_sintrz:
372 move.l d1,USER_FPCR(a6)
373 jsr sintrz
374 fmove.l fpsr,d0
375 or.l USER_FPSR(a6),d0
376 fmove.l d0,fpsr
377 rts
378
379 xdef l_sintd
380 l_sintd:
381 move.l d1,USER_FPCR(a6)
382 jsr sintd
383 fmove.l fpsr,d0
384 or.l USER_FPSR(a6),d0
385 fmove.l d0,fpsr
386 rts
387
388 end
389