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