1 | #include "fpsp-namespace.h" |
---|
2 | // |
---|
3 | // |
---|
4 | // kernel_ex.sa 3.3 12/19/90 |
---|
5 | // |
---|
6 | // This file contains routines to force exception status in the |
---|
7 | // fpu for exceptional cases detected or reported within the |
---|
8 | // transcendental functions. Typically, the t_xx routine will |
---|
9 | // set the appropriate bits in the USER_FPSR word on the stack. |
---|
10 | // The bits are tested in gen_except.sa to determine if an exceptional |
---|
11 | // situation needs to be created on return from the FPSP. |
---|
12 | // |
---|
13 | |
---|
14 | // Copyright (C) Motorola, Inc. 1990 |
---|
15 | // All Rights Reserved |
---|
16 | // |
---|
17 | // THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA |
---|
18 | // The copyright notice above does not evidence any |
---|
19 | // actual or intended publication of such source code. |
---|
20 | |
---|
21 | KERNEL_EX: //idnt 2,1 | Motorola 040 Floating Point Software Package |
---|
22 | |
---|
23 | |section 8 |
---|
24 | |
---|
25 | #include "fpsp.defs" |
---|
26 | |
---|
27 | mns_inf: .long 0xffff0000,0x00000000,0x00000000 |
---|
28 | pls_inf: .long 0x7fff0000,0x00000000,0x00000000 |
---|
29 | nan: .long 0x7fff0000,0xffffffff,0xffffffff |
---|
30 | huge: .long 0x7ffe0000,0xffffffff,0xffffffff |
---|
31 | |
---|
32 | |xref ovf_r_k |
---|
33 | |xref unf_sub |
---|
34 | |xref nrm_set |
---|
35 | |
---|
36 | .global t_dz |
---|
37 | .global t_dz2 |
---|
38 | .global t_operr |
---|
39 | .global t_unfl |
---|
40 | .global t_ovfl |
---|
41 | .global t_ovfl2 |
---|
42 | .global t_inx2 |
---|
43 | .global t_frcinx |
---|
44 | .global t_extdnrm |
---|
45 | .global t_resdnrm |
---|
46 | .global dst_nan |
---|
47 | .global src_nan |
---|
48 | // |
---|
49 | // DZ exception |
---|
50 | // |
---|
51 | // |
---|
52 | // if dz trap disabled |
---|
53 | // store properly signed inf (use sign of etemp) into fp0 |
---|
54 | // set FPSR exception status dz bit, condition code |
---|
55 | // inf bit, and accrued dz bit |
---|
56 | // return |
---|
57 | // frestore the frame into the machine (done by unimp_hd) |
---|
58 | // |
---|
59 | // else dz trap enabled |
---|
60 | // set exception status bit & accrued bits in FPSR |
---|
61 | // set flag to disable sto_res from corrupting fp register |
---|
62 | // return |
---|
63 | // frestore the frame into the machine (done by unimp_hd) |
---|
64 | // |
---|
65 | // t_dz2 is used by monadic functions such as flogn (from do_func). |
---|
66 | // t_dz is used by monadic functions such as satanh (from the |
---|
67 | // transcendental function). |
---|
68 | // |
---|
69 | t_dz2: |
---|
70 | bsetb #neg_bit,FPSR_CC(%a6) //set neg bit in FPSR |
---|
71 | fmovel #0,%FPSR //clr status bits (Z set) |
---|
72 | btstb #dz_bit,FPCR_ENABLE(%a6) //test FPCR for dz exc enabled |
---|
73 | bnes dz_ena_end |
---|
74 | bras m_inf //flogx always returns -inf |
---|
75 | t_dz: |
---|
76 | fmovel #0,%FPSR //clr status bits (Z set) |
---|
77 | btstb #dz_bit,FPCR_ENABLE(%a6) //test FPCR for dz exc enabled |
---|
78 | bnes dz_ena |
---|
79 | // |
---|
80 | // dz disabled |
---|
81 | // |
---|
82 | btstb #sign_bit,ETEMP_EX(%a6) //check sign for neg or pos |
---|
83 | beqs p_inf //branch if pos sign |
---|
84 | |
---|
85 | m_inf: |
---|
86 | fmovemx mns_inf,%fp0-%fp0 //load -inf |
---|
87 | bsetb #neg_bit,FPSR_CC(%a6) //set neg bit in FPSR |
---|
88 | bras set_fpsr |
---|
89 | p_inf: |
---|
90 | fmovemx pls_inf,%fp0-%fp0 //load +inf |
---|
91 | set_fpsr: |
---|
92 | orl #dzinf_mask,USER_FPSR(%a6) //set I,DZ,ADZ |
---|
93 | rts |
---|
94 | // |
---|
95 | // dz enabled |
---|
96 | // |
---|
97 | dz_ena: |
---|
98 | btstb #sign_bit,ETEMP_EX(%a6) //check sign for neg or pos |
---|
99 | beqs dz_ena_end |
---|
100 | bsetb #neg_bit,FPSR_CC(%a6) //set neg bit in FPSR |
---|
101 | dz_ena_end: |
---|
102 | orl #dzinf_mask,USER_FPSR(%a6) //set I,DZ,ADZ |
---|
103 | st STORE_FLG(%a6) |
---|
104 | rts |
---|
105 | // |
---|
106 | // OPERR exception |
---|
107 | // |
---|
108 | // if (operr trap disabled) |
---|
109 | // set FPSR exception status operr bit, condition code |
---|
110 | // nan bit; Store default NAN into fp0 |
---|
111 | // frestore the frame into the machine (done by unimp_hd) |
---|
112 | // |
---|
113 | // else (operr trap enabled) |
---|
114 | // set FPSR exception status operr bit, accrued operr bit |
---|
115 | // set flag to disable sto_res from corrupting fp register |
---|
116 | // frestore the frame into the machine (done by unimp_hd) |
---|
117 | // |
---|
118 | t_operr: |
---|
119 | orl #opnan_mask,USER_FPSR(%a6) //set NaN, OPERR, AIOP |
---|
120 | |
---|
121 | btstb #operr_bit,FPCR_ENABLE(%a6) //test FPCR for operr enabled |
---|
122 | bnes op_ena |
---|
123 | |
---|
124 | fmovemx nan,%fp0-%fp0 //load default nan |
---|
125 | rts |
---|
126 | op_ena: |
---|
127 | st STORE_FLG(%a6) //do not corrupt destination |
---|
128 | rts |
---|
129 | |
---|
130 | // |
---|
131 | // t_unfl --- UNFL exception |
---|
132 | // |
---|
133 | // This entry point is used by all routines requiring unfl, inex2, |
---|
134 | // aunfl, and ainex to be set on exit. |
---|
135 | // |
---|
136 | // On entry, a0 points to the exceptional operand. The final exceptional |
---|
137 | // operand is built in FP_SCR1 and only the sign from the original operand |
---|
138 | // is used. |
---|
139 | // |
---|
140 | t_unfl: |
---|
141 | clrl FP_SCR1(%a6) //set exceptional operand to zero |
---|
142 | clrl FP_SCR1+4(%a6) |
---|
143 | clrl FP_SCR1+8(%a6) |
---|
144 | tstb (%a0) //extract sign from caller's exop |
---|
145 | bpls unfl_signok |
---|
146 | bset #sign_bit,FP_SCR1(%a6) |
---|
147 | unfl_signok: |
---|
148 | leal FP_SCR1(%a6),%a0 |
---|
149 | orl #unfinx_mask,USER_FPSR(%a6) |
---|
150 | // ;set UNFL, INEX2, AUNFL, AINEX |
---|
151 | unfl_con: |
---|
152 | btstb #unfl_bit,FPCR_ENABLE(%a6) |
---|
153 | beqs unfl_dis |
---|
154 | |
---|
155 | unfl_ena: |
---|
156 | bfclr STAG(%a6){#5:#3} //clear wbtm66,wbtm1,wbtm0 |
---|
157 | bsetb #wbtemp15_bit,WB_BYTE(%a6) //set wbtemp15 |
---|
158 | bsetb #sticky_bit,STICKY(%a6) //set sticky bit |
---|
159 | |
---|
160 | bclrb #E1,E_BYTE(%a6) |
---|
161 | |
---|
162 | unfl_dis: |
---|
163 | bfextu FPCR_MODE(%a6){#0:#2},%d0 //get round precision |
---|
164 | |
---|
165 | bclrb #sign_bit,LOCAL_EX(%a0) |
---|
166 | sne LOCAL_SGN(%a0) //convert to internal ext format |
---|
167 | |
---|
168 | bsr unf_sub //returns IEEE result at a0 |
---|
169 | // ;and sets FPSR_CC accordingly |
---|
170 | |
---|
171 | bfclr LOCAL_SGN(%a0){#0:#8} //convert back to IEEE ext format |
---|
172 | beqs unfl_fin |
---|
173 | |
---|
174 | bsetb #sign_bit,LOCAL_EX(%a0) |
---|
175 | bsetb #sign_bit,FP_SCR1(%a6) //set sign bit of exc operand |
---|
176 | |
---|
177 | unfl_fin: |
---|
178 | fmovemx (%a0),%fp0-%fp0 //store result in fp0 |
---|
179 | rts |
---|
180 | |
---|
181 | |
---|
182 | // |
---|
183 | // t_ovfl2 --- OVFL exception (without inex2 returned) |
---|
184 | // |
---|
185 | // This entry is used by scale to force catastrophic overflow. The |
---|
186 | // ovfl, aovfl, and ainex bits are set, but not the inex2 bit. |
---|
187 | // |
---|
188 | t_ovfl2: |
---|
189 | orl #ovfl_inx_mask,USER_FPSR(%a6) |
---|
190 | movel ETEMP(%a6),FP_SCR1(%a6) |
---|
191 | movel ETEMP_HI(%a6),FP_SCR1+4(%a6) |
---|
192 | movel ETEMP_LO(%a6),FP_SCR1+8(%a6) |
---|
193 | // |
---|
194 | // Check for single or double round precision. If single, check if |
---|
195 | // the lower 40 bits of ETEMP are zero; if not, set inex2. If double, |
---|
196 | // check if the lower 21 bits are zero; if not, set inex2. |
---|
197 | // |
---|
198 | moveb FPCR_MODE(%a6),%d0 |
---|
199 | andib #0xc0,%d0 |
---|
200 | beq t_work //if extended, finish ovfl processing |
---|
201 | cmpib #0x40,%d0 //test for single |
---|
202 | bnes t_dbl |
---|
203 | t_sgl: |
---|
204 | tstb ETEMP_LO(%a6) |
---|
205 | bnes t_setinx2 |
---|
206 | movel ETEMP_HI(%a6),%d0 |
---|
207 | andil #0xff,%d0 //look at only lower 8 bits |
---|
208 | bnes t_setinx2 |
---|
209 | bra t_work |
---|
210 | t_dbl: |
---|
211 | movel ETEMP_LO(%a6),%d0 |
---|
212 | andil #0x7ff,%d0 //look at only lower 11 bits |
---|
213 | beq t_work |
---|
214 | t_setinx2: |
---|
215 | orl #inex2_mask,USER_FPSR(%a6) |
---|
216 | bras t_work |
---|
217 | // |
---|
218 | // t_ovfl --- OVFL exception |
---|
219 | // |
---|
220 | //** Note: the exc operand is returned in ETEMP. |
---|
221 | // |
---|
222 | t_ovfl: |
---|
223 | orl #ovfinx_mask,USER_FPSR(%a6) |
---|
224 | t_work: |
---|
225 | btstb #ovfl_bit,FPCR_ENABLE(%a6) //test FPCR for ovfl enabled |
---|
226 | beqs ovf_dis |
---|
227 | |
---|
228 | ovf_ena: |
---|
229 | clrl FP_SCR1(%a6) //set exceptional operand |
---|
230 | clrl FP_SCR1+4(%a6) |
---|
231 | clrl FP_SCR1+8(%a6) |
---|
232 | |
---|
233 | bfclr STAG(%a6){#5:#3} //clear wbtm66,wbtm1,wbtm0 |
---|
234 | bclrb #wbtemp15_bit,WB_BYTE(%a6) //clear wbtemp15 |
---|
235 | bsetb #sticky_bit,STICKY(%a6) //set sticky bit |
---|
236 | |
---|
237 | bclrb #E1,E_BYTE(%a6) |
---|
238 | // ;fall through to disabled case |
---|
239 | |
---|
240 | // For disabled overflow call 'ovf_r_k'. This routine loads the |
---|
241 | // correct result based on the rounding precision, destination |
---|
242 | // format, rounding mode and sign. |
---|
243 | // |
---|
244 | ovf_dis: |
---|
245 | bsr ovf_r_k //returns unsigned ETEMP_EX |
---|
246 | // ;and sets FPSR_CC accordingly. |
---|
247 | bfclr ETEMP_SGN(%a6){#0:#8} //fix sign |
---|
248 | beqs ovf_pos |
---|
249 | bsetb #sign_bit,ETEMP_EX(%a6) |
---|
250 | bsetb #sign_bit,FP_SCR1(%a6) //set exceptional operand sign |
---|
251 | ovf_pos: |
---|
252 | fmovemx ETEMP(%a6),%fp0-%fp0 //move the result to fp0 |
---|
253 | rts |
---|
254 | |
---|
255 | |
---|
256 | // |
---|
257 | // INEX2 exception |
---|
258 | // |
---|
259 | // The inex2 and ainex bits are set. |
---|
260 | // |
---|
261 | t_inx2: |
---|
262 | orl #inx2a_mask,USER_FPSR(%a6) //set INEX2, AINEX |
---|
263 | rts |
---|
264 | |
---|
265 | // |
---|
266 | // Force Inex2 |
---|
267 | // |
---|
268 | // This routine is called by the transcendental routines to force |
---|
269 | // the inex2 exception bits set in the FPSR. If the underflow bit |
---|
270 | // is set, but the underflow trap was not taken, the aunfl bit in |
---|
271 | // the FPSR must be set. |
---|
272 | // |
---|
273 | t_frcinx: |
---|
274 | orl #inx2a_mask,USER_FPSR(%a6) //set INEX2, AINEX |
---|
275 | btstb #unfl_bit,FPSR_EXCEPT(%a6) //test for unfl bit set |
---|
276 | beqs no_uacc1 //if clear, do not set aunfl |
---|
277 | bsetb #aunfl_bit,FPSR_AEXCEPT(%a6) |
---|
278 | no_uacc1: |
---|
279 | rts |
---|
280 | |
---|
281 | // |
---|
282 | // DST_NAN |
---|
283 | // |
---|
284 | // Determine if the destination nan is signalling or non-signalling, |
---|
285 | // and set the FPSR bits accordingly. See the MC68040 User's Manual |
---|
286 | // section 3.2.2.5 NOT-A-NUMBERS. |
---|
287 | // |
---|
288 | dst_nan: |
---|
289 | btstb #sign_bit,FPTEMP_EX(%a6) //test sign of nan |
---|
290 | beqs dst_pos //if clr, it was positive |
---|
291 | bsetb #neg_bit,FPSR_CC(%a6) //set N bit |
---|
292 | dst_pos: |
---|
293 | btstb #signan_bit,FPTEMP_HI(%a6) //check if signalling |
---|
294 | beqs dst_snan //branch if signalling |
---|
295 | |
---|
296 | fmovel %d1,%fpcr //restore user's rmode/prec |
---|
297 | fmovex FPTEMP(%a6),%fp0 //return the non-signalling nan |
---|
298 | // |
---|
299 | // Check the source nan. If it is signalling, snan will be reported. |
---|
300 | // |
---|
301 | moveb STAG(%a6),%d0 |
---|
302 | andib #0xe0,%d0 |
---|
303 | cmpib #0x60,%d0 |
---|
304 | bnes no_snan |
---|
305 | btstb #signan_bit,ETEMP_HI(%a6) //check if signalling |
---|
306 | bnes no_snan |
---|
307 | orl #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP |
---|
308 | no_snan: |
---|
309 | rts |
---|
310 | |
---|
311 | dst_snan: |
---|
312 | btstb #snan_bit,FPCR_ENABLE(%a6) //check if trap enabled |
---|
313 | beqs dst_dis //branch if disabled |
---|
314 | |
---|
315 | orb #nan_tag,DTAG(%a6) //set up dtag for nan |
---|
316 | st STORE_FLG(%a6) //do not store a result |
---|
317 | orl #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP |
---|
318 | rts |
---|
319 | |
---|
320 | dst_dis: |
---|
321 | bsetb #signan_bit,FPTEMP_HI(%a6) //set SNAN bit in sop |
---|
322 | fmovel %d1,%fpcr //restore user's rmode/prec |
---|
323 | fmovex FPTEMP(%a6),%fp0 //load non-sign. nan |
---|
324 | orl #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP |
---|
325 | rts |
---|
326 | |
---|
327 | // |
---|
328 | // SRC_NAN |
---|
329 | // |
---|
330 | // Determine if the source nan is signalling or non-signalling, |
---|
331 | // and set the FPSR bits accordingly. See the MC68040 User's Manual |
---|
332 | // section 3.2.2.5 NOT-A-NUMBERS. |
---|
333 | // |
---|
334 | src_nan: |
---|
335 | btstb #sign_bit,ETEMP_EX(%a6) //test sign of nan |
---|
336 | beqs src_pos //if clr, it was positive |
---|
337 | bsetb #neg_bit,FPSR_CC(%a6) //set N bit |
---|
338 | src_pos: |
---|
339 | btstb #signan_bit,ETEMP_HI(%a6) //check if signalling |
---|
340 | beqs src_snan //branch if signalling |
---|
341 | fmovel %d1,%fpcr //restore user's rmode/prec |
---|
342 | fmovex ETEMP(%a6),%fp0 //return the non-signalling nan |
---|
343 | rts |
---|
344 | |
---|
345 | src_snan: |
---|
346 | btstb #snan_bit,FPCR_ENABLE(%a6) //check if trap enabled |
---|
347 | beqs src_dis //branch if disabled |
---|
348 | bsetb #signan_bit,ETEMP_HI(%a6) //set SNAN bit in sop |
---|
349 | orb #norm_tag,DTAG(%a6) //set up dtag for norm |
---|
350 | orb #nan_tag,STAG(%a6) //set up stag for nan |
---|
351 | st STORE_FLG(%a6) //do not store a result |
---|
352 | orl #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP |
---|
353 | rts |
---|
354 | |
---|
355 | src_dis: |
---|
356 | bsetb #signan_bit,ETEMP_HI(%a6) //set SNAN bit in sop |
---|
357 | fmovel %d1,%fpcr //restore user's rmode/prec |
---|
358 | fmovex ETEMP(%a6),%fp0 //load non-sign. nan |
---|
359 | orl #snaniop_mask,USER_FPSR(%a6) //set NAN, SNAN, AIOP |
---|
360 | rts |
---|
361 | |
---|
362 | // |
---|
363 | // For all functions that have a denormalized input and that f(x)=x, |
---|
364 | // this is the entry point |
---|
365 | // |
---|
366 | t_extdnrm: |
---|
367 | orl #unfinx_mask,USER_FPSR(%a6) |
---|
368 | // ;set UNFL, INEX2, AUNFL, AINEX |
---|
369 | bras xdnrm_con |
---|
370 | // |
---|
371 | // Entry point for scale with extended denorm. The function does |
---|
372 | // not set inex2, aunfl, or ainex. |
---|
373 | // |
---|
374 | t_resdnrm: |
---|
375 | orl #unfl_mask,USER_FPSR(%a6) |
---|
376 | |
---|
377 | xdnrm_con: |
---|
378 | btstb #unfl_bit,FPCR_ENABLE(%a6) |
---|
379 | beqs xdnrm_dis |
---|
380 | |
---|
381 | // |
---|
382 | // If exceptions are enabled, the additional task of setting up WBTEMP |
---|
383 | // is needed so that when the underflow exception handler is entered, |
---|
384 | // the user perceives no difference between what the 040 provides vs. |
---|
385 | // what the FPSP provides. |
---|
386 | // |
---|
387 | xdnrm_ena: |
---|
388 | movel %a0,-(%a7) |
---|
389 | |
---|
390 | movel LOCAL_EX(%a0),FP_SCR1(%a6) |
---|
391 | movel LOCAL_HI(%a0),FP_SCR1+4(%a6) |
---|
392 | movel LOCAL_LO(%a0),FP_SCR1+8(%a6) |
---|
393 | |
---|
394 | lea FP_SCR1(%a6),%a0 |
---|
395 | |
---|
396 | bclrb #sign_bit,LOCAL_EX(%a0) |
---|
397 | sne LOCAL_SGN(%a0) //convert to internal ext format |
---|
398 | tstw LOCAL_EX(%a0) //check if input is denorm |
---|
399 | beqs xdnrm_dn //if so, skip nrm_set |
---|
400 | bsr nrm_set //normalize the result (exponent |
---|
401 | // ;will be negative |
---|
402 | xdnrm_dn: |
---|
403 | bclrb #sign_bit,LOCAL_EX(%a0) //take off false sign |
---|
404 | bfclr LOCAL_SGN(%a0){#0:#8} //change back to IEEE ext format |
---|
405 | beqs xdep |
---|
406 | bsetb #sign_bit,LOCAL_EX(%a0) |
---|
407 | xdep: |
---|
408 | bfclr STAG(%a6){#5:#3} //clear wbtm66,wbtm1,wbtm0 |
---|
409 | bsetb #wbtemp15_bit,WB_BYTE(%a6) //set wbtemp15 |
---|
410 | bclrb #sticky_bit,STICKY(%a6) //clear sticky bit |
---|
411 | bclrb #E1,E_BYTE(%a6) |
---|
412 | movel (%a7)+,%a0 |
---|
413 | xdnrm_dis: |
---|
414 | bfextu FPCR_MODE(%a6){#0:#2},%d0 //get round precision |
---|
415 | bnes not_ext //if not round extended, store |
---|
416 | // ;IEEE defaults |
---|
417 | is_ext: |
---|
418 | btstb #sign_bit,LOCAL_EX(%a0) |
---|
419 | beqs xdnrm_store |
---|
420 | |
---|
421 | bsetb #neg_bit,FPSR_CC(%a6) //set N bit in FPSR_CC |
---|
422 | |
---|
423 | bras xdnrm_store |
---|
424 | |
---|
425 | not_ext: |
---|
426 | bclrb #sign_bit,LOCAL_EX(%a0) |
---|
427 | sne LOCAL_SGN(%a0) //convert to internal ext format |
---|
428 | bsr unf_sub //returns IEEE result pointed by |
---|
429 | // ;a0; sets FPSR_CC accordingly |
---|
430 | bfclr LOCAL_SGN(%a0){#0:#8} //convert back to IEEE ext format |
---|
431 | beqs xdnrm_store |
---|
432 | bsetb #sign_bit,LOCAL_EX(%a0) |
---|
433 | xdnrm_store: |
---|
434 | fmovemx (%a0),%fp0-%fp0 //store result in fp0 |
---|
435 | rts |
---|
436 | |
---|
437 | // |
---|
438 | // This subroutine is used for dyadic operations that use an extended |
---|
439 | // denorm within the kernel. The approach used is to capture the frame, |
---|
440 | // fix/restore. |
---|
441 | // |
---|
442 | .global t_avoid_unsupp |
---|
443 | t_avoid_unsupp: |
---|
444 | link %a2,#-LOCAL_SIZE //so that a2 fpsp.h negative |
---|
445 | // ;offsets may be used |
---|
446 | fsave -(%a7) |
---|
447 | tstb 1(%a7) //check if idle, exit if so |
---|
448 | beq idle_end |
---|
449 | btstb #E1,E_BYTE(%a2) //check for an E1 exception if |
---|
450 | // ;enabled, there is an unsupp |
---|
451 | beq end_avun //else, exit |
---|
452 | btstb #7,DTAG(%a2) //check for denorm destination |
---|
453 | beqs src_den //else, must be a source denorm |
---|
454 | // |
---|
455 | // handle destination denorm |
---|
456 | // |
---|
457 | lea FPTEMP(%a2),%a0 |
---|
458 | btstb #sign_bit,LOCAL_EX(%a0) |
---|
459 | sne LOCAL_SGN(%a0) //convert to internal ext format |
---|
460 | bclrb #7,DTAG(%a2) //set DTAG to norm |
---|
461 | bsr nrm_set //normalize result, exponent |
---|
462 | // ;will become negative |
---|
463 | bclrb #sign_bit,LOCAL_EX(%a0) //get rid of fake sign |
---|
464 | bfclr LOCAL_SGN(%a0){#0:#8} //convert back to IEEE ext format |
---|
465 | beqs ck_src_den //check if source is also denorm |
---|
466 | bsetb #sign_bit,LOCAL_EX(%a0) |
---|
467 | ck_src_den: |
---|
468 | btstb #7,STAG(%a2) |
---|
469 | beqs end_avun |
---|
470 | src_den: |
---|
471 | lea ETEMP(%a2),%a0 |
---|
472 | btstb #sign_bit,LOCAL_EX(%a0) |
---|
473 | sne LOCAL_SGN(%a0) //convert to internal ext format |
---|
474 | bclrb #7,STAG(%a2) //set STAG to norm |
---|
475 | bsr nrm_set //normalize result, exponent |
---|
476 | // ;will become negative |
---|
477 | bclrb #sign_bit,LOCAL_EX(%a0) //get rid of fake sign |
---|
478 | bfclr LOCAL_SGN(%a0){#0:#8} //convert back to IEEE ext format |
---|
479 | beqs den_com |
---|
480 | bsetb #sign_bit,LOCAL_EX(%a0) |
---|
481 | den_com: |
---|
482 | moveb #0xfe,CU_SAVEPC(%a2) //set continue frame |
---|
483 | clrw NMNEXC(%a2) //clear NMNEXC |
---|
484 | bclrb #E1,E_BYTE(%a2) |
---|
485 | // fmove.l %FPSR,FPSR_SHADOW(%a2) |
---|
486 | // bset.b #SFLAG,E_BYTE(%a2) |
---|
487 | // bset.b #XFLAG,T_BYTE(%a2) |
---|
488 | end_avun: |
---|
489 | frestore (%a7)+ |
---|
490 | unlk %a2 |
---|
491 | rts |
---|
492 | idle_end: |
---|
493 | addl #4,%a7 |
---|
494 | unlk %a2 |
---|
495 | rts |
---|
496 | |end |
---|