~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/m68k/fpsp040/res_func.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/m68k/fpsp040/res_func.S (Architecture m68k) and /arch/sparc/fpsp040/res_func.S (Architecture sparc)


  1 |                                                 
  2 |       res_func.sa 3.9 7/29/91                   
  3 |                                                 
  4 | Normalizes denormalized numbers if necessary    
  5 | stack frame.  The function is then restored     
  6 | machine and the 040 completes the operation.    
  7 | is only used by the unsupported data type/fo    
  8 | (Exception vector 55).                          
  9 |                                                 
 10 | For packed move out (fmove.p fpm,<ea>) the o    
 11 | completed here; data is packed and moved to     
 12 | The stack is restored to the 040 only in the    
 13 | reportable exception in the conversion.         
 14 |                                                 
 15 |                                                 
 16 |               Copyright (C) Motorola, Inc. 1    
 17 |                       All Rights Reserved       
 18 |                                                 
 19 |       For details on the license for this fi    
 20 |       file, README, in this same directory.     
 21                                                   
 22 RES_FUNC:    |idnt    2,1 | Motorola 040 Float    
 23                                                   
 24         |section        8                         
 25                                                   
 26 #include "fpsp.h"                                 
 27                                                   
 28 sp_bnds:        .short  0x3f81,0x407e             
 29                 .short  0x3f6a,0x0000             
 30 dp_bnds:        .short  0x3c01,0x43fe             
 31                 .short  0x3bcd,0x0000             
 32                                                   
 33         |xref   mem_write                         
 34         |xref   bindec                            
 35         |xref   get_fline                         
 36         |xref   round                             
 37         |xref   denorm                            
 38         |xref   dest_ext                          
 39         |xref   dest_dbl                          
 40         |xref   dest_sgl                          
 41         |xref   unf_sub                           
 42         |xref   nrm_set                           
 43         |xref   dnrm_lp                           
 44         |xref   ovf_res                           
 45         |xref   reg_dest                          
 46         |xref   t_ovfl                            
 47         |xref   t_unfl                            
 48                                                   
 49         .global res_func                          
 50         .global p_move                            
 51                                                   
 52 res_func:                                         
 53         clrb    DNRM_FLG(%a6)                     
 54         clrb    RES_FLG(%a6)                      
 55         clrb    CU_ONLY(%a6)                      
 56         tstb    DY_MO_FLG(%a6)                    
 57         beqs    monadic                           
 58 dyadic:                                           
 59         btstb   #7,DTAG(%a6)    |if dop = norm    
 60 |                               ;inf=010 or na    
 61         beqs    monadic         |then branch      
 62 |                               ;else denorm      
 63 | HANDLE DESTINATION DENORM HERE                  
 64 |                               ;set dtag to n    
 65 |                               ;write the tag    
 66         leal    FPTEMP(%a6),%a0                   
 67                                                   
 68         bclrb   #sign_bit,LOCAL_EX(%a0)           
 69         sne     LOCAL_SGN(%a0)                    
 70                                                   
 71         bsr     nrm_set         |normalize num    
 72         bclrb   #sign_bit,LOCAL_EX(%a0) |get r    
 73         bfclr   LOCAL_SGN(%a0){#0:#8}   |chang    
 74         beqs    dpos                              
 75         bsetb   #sign_bit,LOCAL_EX(%a0)           
 76 dpos:                                             
 77         bfclr   DTAG(%a6){#0:#4}        |set t    
 78         bsetb   #4,DTAG(%a6)    |set FPTE15       
 79         orb     #0x0f,DNRM_FLG(%a6)               
 80 monadic:                                          
 81         leal    ETEMP(%a6),%a0                    
 82         btstb   #direction_bit,CMDREG1B(%a6)      
 83         bne     opclass3                          
 84 |                                                 
 85 | At this point, only opclass 0 and 2 possible    
 86 |                                                 
 87         btstb   #7,STAG(%a6)    |if sop = norm    
 88 |                               ;inf=010 or na    
 89         bne     mon_dnrm        |else denorm      
 90         tstb    DY_MO_FLG(%a6)  |all cases of     
 91         bne     normal          |require norma    
 92                                                   
 93 | At this point:                                  
 94 |       monadic instructions:   fabs  = $18  f    
 95 |                               fmove = $00  f    
 96 |                               fsqrt = $05* f    
 97 |                               (*fsqrt reenco    
 98 |                                                 
 99         movew   CMDREG1B(%a6),%d0       |get c    
100         andil   #0x7f,%d0                         
101 |                                                 
102 | At this point, fabs, fneg, fsmove, fdmove, f    
103 | fdsqrt are possible.                            
104 | For cases fabs, fneg, fsmove, and fdmove got    
105 | For cases fsqrt, fssqrt, and fdsqrt goto nrm    
106 |                                                 
107         btstl   #0,%d0                            
108         bne     normal                  |weed     
109 |                                                 
110 | cu_norm handles fmove in instructions with n    
111 | The routine round is used to correctly round    
112 | destination precision and mode.                 
113 |                                                 
114 cu_norm:                                          
115         st      CU_ONLY(%a6)            |set c    
116         movew   CMDREG1B(%a6),%d0                 
117         andib   #0x3b,%d0               |isola    
118         tstb    %d0                               
119         beql    cu_nmove        |if zero, it i    
120         cmpib   #0x18,%d0                         
121         beql    cu_nabs         |if $18, it is    
122         cmpib   #0x1a,%d0                         
123         beql    cu_nneg         |if $1a, it is    
124 |                                                 
125 | Inst is ftst.  Check the source operand and     
126 | No write is done, so simply rts.                
127 |                                                 
128 cu_ntst:                                          
129         movew   LOCAL_EX(%a0),%d0                 
130         bclrl   #15,%d0                           
131         sne     LOCAL_SGN(%a0)                    
132         beqs    cu_ntpo                           
133         orl     #neg_mask,USER_FPSR(%a6) |set     
134 cu_ntpo:                                          
135         cmpiw   #0x7fff,%d0     |test for inf/    
136         bnes    cu_ntcz                           
137         tstl    LOCAL_HI(%a0)                     
138         bnes    cu_ntn                            
139         tstl    LOCAL_LO(%a0)                     
140         bnes    cu_ntn                            
141         orl     #inf_mask,USER_FPSR(%a6)          
142         rts                                       
143 cu_ntn:                                           
144         orl     #nan_mask,USER_FPSR(%a6)          
145         movel   ETEMP_EX(%a6),FPTEMP_EX(%a6)      
146 |                                                 
147                                                   
148         rts                                       
149 cu_ntcz:                                          
150         tstl    LOCAL_HI(%a0)                     
151         bnel    cu_ntsx                           
152         tstl    LOCAL_LO(%a0)                     
153         bnel    cu_ntsx                           
154         orl     #z_mask,USER_FPSR(%a6)            
155 cu_ntsx:                                          
156         rts                                       
157 |                                                 
158 | Inst is fabs.  Execute the absolute value fu    
159 | Branch to the fmove code.  If the operand is    
160 |                                                 
161 cu_nabs:                                          
162         moveb   STAG(%a6),%d0                     
163         btstl   #5,%d0                  |test     
164         bne     wr_etemp                |if ei    
165         bclrb   #7,LOCAL_EX(%a0)                  
166         bras    cu_nmove                |fmove    
167 |                                                 
168 | Inst is fneg.  Execute the negate value func    
169 | Fall though to the fmove code.  If the opera    
170 |                                                 
171 cu_nneg:                                          
172         moveb   STAG(%a6),%d0                     
173         btstl   #5,%d0                  |test     
174         bne     wr_etemp                |if ei    
175         bchgb   #7,LOCAL_EX(%a0)                  
176 |                                                 
177 | Inst is fmove.  This code also handles all r    
178 | If bit 2 is set, round is forced to double.     
179 | and bit 6 is set, round is forced to single.    
180 | the round precision is found in the fpcr.  I    
181 | is double or single, round the result before    
182 |                                                 
183 cu_nmove:                                         
184         moveb   STAG(%a6),%d0                     
185         andib   #0xe0,%d0                         
186         bne     wr_etemp                |if no    
187         btstb   #2,CMDREG1B+1(%a6)      |check    
188         bne     cu_nmrd                           
189         btstb   #6,CMDREG1B+1(%a6)      |check    
190         bne     cu_nmrs                           
191 |                                                 
192 | The move or operation is not with forced pre    
193 | nan or inf as the input; if so, simply write    
194 | FPCR_MODE byte to get rounding on norms and     
195 |                                                 
196 cu_nmnr:                                          
197         bfextu  FPCR_MODE(%a6){#0:#2},%d0         
198         tstb    %d0                     |check    
199         beq     cu_wrexn                |if so    
200         cmpib   #1,%d0                  |check    
201         beq     cu_nmrs                 |fall     
202 |                                                 
203 | The move is fdmove or round precision is dou    
204 |                                                 
205 cu_nmrd:                                          
206         movel   #2,%d0                  |set u    
207         movew   LOCAL_EX(%a0),%d1                 
208         andw    #0x7fff,%d1                       
209         cmpw    #0x3c01,%d1                       
210         bls     cu_nunfl                          
211         bfextu  FPCR_MODE(%a6){#2:#2},%d1         
212         orl     #0x00020000,%d1         |or in    
213         clrl    %d0                     |clear    
214         bclrb   #sign_bit,LOCAL_EX(%a0) |conve    
215         sne     LOCAL_SGN(%a0)                    
216         bsrl    round                             
217         bfclr   LOCAL_SGN(%a0){#0:#8}             
218         beqs    cu_nmrdc                          
219         bsetb   #sign_bit,LOCAL_EX(%a0)           
220 cu_nmrdc:                                         
221         movew   LOCAL_EX(%a0),%d1                 
222         andw    #0x7fff,%d1                       
223         cmpw    #0x43ff,%d1                       
224         bge     cu_novfl                |take     
225         bra     cu_wrexn                          
226 |                                                 
227 | The move is fsmove or round precision is sin    
228 |                                                 
229 cu_nmrs:                                          
230         movel   #1,%d0                            
231         movew   LOCAL_EX(%a0),%d1                 
232         andw    #0x7fff,%d1                       
233         cmpw    #0x3f81,%d1                       
234         bls     cu_nunfl                          
235         bfextu  FPCR_MODE(%a6){#2:#2},%d1         
236         orl     #0x00010000,%d1                   
237         clrl    %d0                               
238         bclrb   #sign_bit,LOCAL_EX(%a0)           
239         sne     LOCAL_SGN(%a0)                    
240         bsrl    round                             
241         bfclr   LOCAL_SGN(%a0){#0:#8}             
242         beqs    cu_nmrsc                          
243         bsetb   #sign_bit,LOCAL_EX(%a0)           
244 cu_nmrsc:                                         
245         movew   LOCAL_EX(%a0),%d1                 
246         andw    #0x7FFF,%d1                       
247         cmpw    #0x407f,%d1                       
248         blt     cu_wrexn                          
249 |                                                 
250 | The operand is above precision boundaries.      
251 | generate the correct value.                     
252 |                                                 
253 cu_novfl:                                         
254         bsr     t_ovfl                            
255         bra     cu_wrexn                          
256 |                                                 
257 | The operand is below precision boundaries.      
258 | generate the correct value.                     
259 |                                                 
260 cu_nunfl:                                         
261         bclrb   #sign_bit,LOCAL_EX(%a0)           
262         sne     LOCAL_SGN(%a0)                    
263         bsr     denorm                            
264         bfclr   LOCAL_SGN(%a0){#0:#8}   |chang    
265         beqs    cu_nucont                         
266         bsetb   #sign_bit,LOCAL_EX(%a0)           
267 cu_nucont:                                        
268         bfextu  FPCR_MODE(%a6){#2:#2},%d1         
269         btstb   #2,CMDREG1B+1(%a6)      |check    
270         bne     inst_d                            
271         btstb   #6,CMDREG1B+1(%a6)      |check    
272         bne     inst_s                            
273         swap    %d1                               
274         moveb   FPCR_MODE(%a6),%d1                
275         lsrb    #6,%d1                            
276         swap    %d1                               
277         bra     inst_sd                           
278 inst_d:                                           
279         orl     #0x00020000,%d1                   
280         bra     inst_sd                           
281 inst_s:                                           
282         orl     #0x00010000,%d1                   
283 inst_sd:                                          
284         bclrb   #sign_bit,LOCAL_EX(%a0)           
285         sne     LOCAL_SGN(%a0)                    
286         bsrl    round                             
287         bfclr   LOCAL_SGN(%a0){#0:#8}             
288         beqs    cu_nuflp                          
289         bsetb   #sign_bit,LOCAL_EX(%a0)           
290 cu_nuflp:                                         
291         btstb   #inex2_bit,FPSR_EXCEPT(%a6)       
292         beqs    cu_nuninx                         
293         orl     #aunfl_mask,USER_FPSR(%a6) |if    
294 cu_nuninx:                                        
295         tstl    LOCAL_HI(%a0)           |test     
296         bnes    cu_nunzro                         
297         tstl    LOCAL_LO(%a0)                     
298         bnes    cu_nunzro                         
299 |                                                 
300 | The mantissa is zero from the denorm loop.      
301 | to see if rounding should have occurred whic    
302 |                                                 
303         movel   USER_FPCR(%a6),%d0                
304         andil   #0x30,%d0               |isola    
305         cmpil   #0x20,%d0                         
306         blts    cu_nzro                           
307         bnes    cu_nrp                            
308 cu_nrm:                                           
309         tstw    LOCAL_EX(%a0)   |if positive,     
310         bges    cu_nzro                           
311         btstb   #7,FPCR_MODE(%a6) |check for d    
312         beqs    cu_nincs                          
313         bras    cu_nincd                          
314 cu_nrp:                                           
315         tstw    LOCAL_EX(%a0)   |if positive,     
316         blts    cu_nzro                           
317         btstb   #7,FPCR_MODE(%a6) |check for d    
318         beqs    cu_nincs                          
319 cu_nincd:                                         
320         orl     #0x800,LOCAL_LO(%a0) |inc for     
321         bra     cu_nunzro                         
322 cu_nincs:                                         
323         orl     #0x100,LOCAL_HI(%a0) |inc for     
324         bra     cu_nunzro                         
325 cu_nzro:                                          
326         orl     #z_mask,USER_FPSR(%a6)            
327         moveb   STAG(%a6),%d0                     
328         andib   #0xe0,%d0                         
329         cmpib   #0x40,%d0               |check    
330         beqs    cu_numv                           
331 cu_nunzro:                                        
332         orl     #unfl_mask,USER_FPSR(%a6) |set    
333 cu_numv:                                          
334         movel   (%a0),ETEMP(%a6)                  
335         movel   4(%a0),ETEMP_HI(%a6)              
336         movel   8(%a0),ETEMP_LO(%a6)              
337 |                                                 
338 | Write the result to memory, setting the fpsr    
339 | bypass cu_wrexn.                                
340 |                                                 
341 cu_wrexn:                                         
342         tstw    LOCAL_EX(%a0)           |test     
343         beqs    cu_wrzero                         
344         cmpw    #0x8000,LOCAL_EX(%a0)   |test     
345         bnes    cu_wreon                          
346 cu_wrzero:                                        
347         orl     #z_mask,USER_FPSR(%a6)  |set Z    
348 cu_wreon:                                         
349         tstw    LOCAL_EX(%a0)                     
350         bpl     wr_etemp                          
351         orl     #neg_mask,USER_FPSR(%a6)          
352         bra     wr_etemp                          
353                                                   
354 |                                                 
355 | HANDLE SOURCE DENORM HERE                       
356 |                                                 
357 |                               ;clear denorm     
358 |                               ;write the new    
359 mon_dnrm:                                         
360 |                                                 
361 | At this point, check for the cases in which     
362 | denorm produces incorrect results.              
363 |                                                 
364         tstb    DY_MO_FLG(%a6)  |all cases of     
365         bnes    nrm_src         |require norma    
366                                                   
367 | At this point:                                  
368 |       monadic instructions:   fabs  = $18  f    
369 |                               fmove = $00  f    
370 |                               fsqrt = $05* f    
371 |                               (*fsqrt reenco    
372 |                                                 
373         movew   CMDREG1B(%a6),%d0       |get c    
374         andil   #0x7f,%d0                         
375 |                                                 
376 | At this point, fabs, fneg, fsmove, fdmove, f    
377 | fdsqrt are possible.                            
378 | For cases fabs, fneg, fsmove, and fdmove got    
379 | For cases fsqrt, fssqrt, and fdsqrt goto nrm    
380 |                                                 
381         btstl   #0,%d0                            
382         bnes    nrm_src         |weed out fsqr    
383         st      CU_ONLY(%a6)    |set cu-only i    
384         bra     cu_dnrm         |fmove, fabs,     
385 |                               ;cases go to c    
386 nrm_src:                                          
387         bclrb   #sign_bit,LOCAL_EX(%a0)           
388         sne     LOCAL_SGN(%a0)                    
389         bsr     nrm_set         |normalize num    
390 |                               ; negative)       
391         bclrb   #sign_bit,LOCAL_EX(%a0) |get r    
392                                                   
393         bfclr   LOCAL_SGN(%a0){#0:#8}   |chang    
394         beqs    spos                              
395         bsetb   #sign_bit,LOCAL_EX(%a0)           
396 spos:                                             
397         bfclr   STAG(%a6){#0:#4}        |set t    
398         bsetb   #4,STAG(%a6)    |set ETE15        
399         orb     #0xf0,DNRM_FLG(%a6)               
400 normal:                                           
401         tstb    DNRM_FLG(%a6)   |check if any     
402         bne     ck_wrap         |if so, check     
403 |                               ;wrap-around c    
404 fix_stk:                                          
405         moveb   #0xfe,CU_SAVEPC(%a6)              
406         bclrb   #E1,E_BYTE(%a6)                   
407                                                   
408         clrw    NMNEXC(%a6)                       
409                                                   
410         st      RES_FLG(%a6)    |indicate that    
411         rts                                       
412                                                   
413 |                                                 
414 | cu_dnrm handles all cu-only instructions (fm    
415 | ftst) completely in software without an fres    
416 |                                                 
417 cu_dnrm:                                          
418         st      CU_ONLY(%a6)                      
419         movew   CMDREG1B(%a6),%d0                 
420         andib   #0x3b,%d0               |isola    
421         tstb    %d0                               
422         beql    cu_dmove        |if zero, it i    
423         cmpib   #0x18,%d0                         
424         beql    cu_dabs         |if $18, it is    
425         cmpib   #0x1a,%d0                         
426         beql    cu_dneg         |if $1a, it is    
427 |                                                 
428 | Inst is ftst.  Check the source operand and     
429 | No write is done, so simply rts.                
430 |                                                 
431 cu_dtst:                                          
432         movew   LOCAL_EX(%a0),%d0                 
433         bclrl   #15,%d0                           
434         sne     LOCAL_SGN(%a0)                    
435         beqs    cu_dtpo                           
436         orl     #neg_mask,USER_FPSR(%a6) |set     
437 cu_dtpo:                                          
438         cmpiw   #0x7fff,%d0     |test for inf/    
439         bnes    cu_dtcz                           
440         tstl    LOCAL_HI(%a0)                     
441         bnes    cu_dtn                            
442         tstl    LOCAL_LO(%a0)                     
443         bnes    cu_dtn                            
444         orl     #inf_mask,USER_FPSR(%a6)          
445         rts                                       
446 cu_dtn:                                           
447         orl     #nan_mask,USER_FPSR(%a6)          
448         movel   ETEMP_EX(%a6),FPTEMP_EX(%a6)      
449 |                                                 
450         rts                                       
451 cu_dtcz:                                          
452         tstl    LOCAL_HI(%a0)                     
453         bnel    cu_dtsx                           
454         tstl    LOCAL_LO(%a0)                     
455         bnel    cu_dtsx                           
456         orl     #z_mask,USER_FPSR(%a6)            
457 cu_dtsx:                                          
458         rts                                       
459 |                                                 
460 | Inst is fabs.  Execute the absolute value fu    
461 | Branch to the fmove code.                       
462 |                                                 
463 cu_dabs:                                          
464         bclrb   #7,LOCAL_EX(%a0)                  
465         bras    cu_dmove                |fmove    
466 |                                                 
467 | Inst is fneg.  Execute the negate value func    
468 | Fall though to the fmove code.                  
469 |                                                 
470 cu_dneg:                                          
471         bchgb   #7,LOCAL_EX(%a0)                  
472 |                                                 
473 | Inst is fmove.  This code also handles all r    
474 | If bit 2 is set, round is forced to double.     
475 | and bit 6 is set, round is forced to single.    
476 | the round precision is found in the fpcr.  I    
477 | is double or single, the result is zero, and    
478 | to determine if the lsb of the result should    
479 |                                                 
480 cu_dmove:                                         
481         btstb   #2,CMDREG1B+1(%a6)      |check    
482         bne     cu_dmrd                           
483         btstb   #6,CMDREG1B+1(%a6)      |check    
484         bne     cu_dmrs                           
485 |                                                 
486 | The move or operation is not with forced pre    
487 | FPCR_MODE byte to get rounding.                 
488 |                                                 
489 cu_dmnr:                                          
490         bfextu  FPCR_MODE(%a6){#0:#2},%d0         
491         tstb    %d0                     |check    
492         beq     cu_wrexd                |if so    
493         cmpib   #1,%d0                  |check    
494         beq     cu_dmrs                 |fall     
495 |                                                 
496 | The move is fdmove or round precision is dou    
497 | Check rmode for rp or rm and set lsb accordi    
498 |                                                 
499 cu_dmrd:                                          
500         bfextu  FPCR_MODE(%a6){#2:#2},%d1         
501         tstw    LOCAL_EX(%a0)           |check    
502         blts    cu_dmdn                           
503         cmpib   #3,%d1                  |check    
504         bne     cu_dpd                  |load     
505         bra     cu_dpdr                 |load     
506 cu_dmdn:                                          
507         cmpib   #2,%d1                  |check    
508         bne     cu_dnd                  |load     
509         bra     cu_dndr                 |load     
510 |                                                 
511 | The move is fsmove or round precision is sin    
512 | Check for rp or rm and set lsb accordingly.     
513 |                                                 
514 cu_dmrs:                                          
515         bfextu  FPCR_MODE(%a6){#2:#2},%d1         
516         tstw    LOCAL_EX(%a0)           |check    
517         blts    cu_dmsn                           
518         cmpib   #3,%d1                  |check    
519         bne     cu_spd                  |load     
520         bra     cu_spdr                 |load     
521 cu_dmsn:                                          
522         cmpib   #2,%d1                  |check    
523         bne     cu_snd                  |load     
524         bra     cu_sndr                 |load     
525 |                                                 
526 | The precision is extended, so the result in     
527 | Simply set unfl (not inex2 or aunfl) and wri    
528 | the correct fp register.                        
529 cu_wrexd:                                         
530         orl     #unfl_mask,USER_FPSR(%a6)         
531         tstw    LOCAL_EX(%a0)                     
532         beq     wr_etemp                          
533         orl     #neg_mask,USER_FPSR(%a6)          
534         bra     wr_etemp                          
535 |                                                 
536 | These routines write +/- zero in double form    
537 | cu_dpdr and cu_dndr set the double lsb.         
538 |                                                 
539 cu_dpd:                                           
540         movel   #0x3c010000,LOCAL_EX(%a0)         
541         clrl    LOCAL_HI(%a0)                     
542         clrl    LOCAL_LO(%a0)                     
543         orl     #z_mask,USER_FPSR(%a6)            
544         orl     #unfinx_mask,USER_FPSR(%a6)       
545         bra     wr_etemp                          
546 cu_dpdr:                                          
547         movel   #0x3c010000,LOCAL_EX(%a0)         
548         clrl    LOCAL_HI(%a0)                     
549         movel   #0x800,LOCAL_LO(%a0)    |with     
550         orl     #unfinx_mask,USER_FPSR(%a6)       
551         bra     wr_etemp                          
552 cu_dnd:                                           
553         movel   #0xbc010000,LOCAL_EX(%a0)         
554         clrl    LOCAL_HI(%a0)                     
555         clrl    LOCAL_LO(%a0)                     
556         orl     #z_mask,USER_FPSR(%a6)            
557         orl     #neg_mask,USER_FPSR(%a6)          
558         orl     #unfinx_mask,USER_FPSR(%a6)       
559         bra     wr_etemp                          
560 cu_dndr:                                          
561         movel   #0xbc010000,LOCAL_EX(%a0)         
562         clrl    LOCAL_HI(%a0)                     
563         movel   #0x800,LOCAL_LO(%a0)    |with     
564         orl     #neg_mask,USER_FPSR(%a6)          
565         orl     #unfinx_mask,USER_FPSR(%a6)       
566         bra     wr_etemp                          
567 |                                                 
568 | These routines write +/- zero in single form    
569 | cu_dpdr and cu_dndr set the single lsb.         
570 |                                                 
571 cu_spd:                                           
572         movel   #0x3f810000,LOCAL_EX(%a0)         
573         clrl    LOCAL_HI(%a0)                     
574         clrl    LOCAL_LO(%a0)                     
575         orl     #z_mask,USER_FPSR(%a6)            
576         orl     #unfinx_mask,USER_FPSR(%a6)       
577         bra     wr_etemp                          
578 cu_spdr:                                          
579         movel   #0x3f810000,LOCAL_EX(%a0)         
580         movel   #0x100,LOCAL_HI(%a0)    |with     
581         clrl    LOCAL_LO(%a0)                     
582         orl     #unfinx_mask,USER_FPSR(%a6)       
583         bra     wr_etemp                          
584 cu_snd:                                           
585         movel   #0xbf810000,LOCAL_EX(%a0)         
586         clrl    LOCAL_HI(%a0)                     
587         clrl    LOCAL_LO(%a0)                     
588         orl     #z_mask,USER_FPSR(%a6)            
589         orl     #neg_mask,USER_FPSR(%a6)          
590         orl     #unfinx_mask,USER_FPSR(%a6)       
591         bra     wr_etemp                          
592 cu_sndr:                                          
593         movel   #0xbf810000,LOCAL_EX(%a0)         
594         movel   #0x100,LOCAL_HI(%a0)    |with     
595         clrl    LOCAL_LO(%a0)                     
596         orl     #neg_mask,USER_FPSR(%a6)          
597         orl     #unfinx_mask,USER_FPSR(%a6)       
598         bra     wr_etemp                          
599                                                   
600 |                                                 
601 | This code checks for 16-bit overflow conditi    
602 | operations which are not restorable into the    
603 | unit and must be completed in software.  Bas    
604 | condition exists with a very large norm and     
605 | of the operands must be denormalized to ente    
606 |                                                 
607 | Flags used:                                     
608 |       DY_MO_FLG contains 0 for monadic op, $    
609 |       DNRM_FLG contains $00 for neither op d    
610 |                         $0f for the destinat    
611 |                         $f0 for the source o    
612 |                         $ff for both ops den    
613 |                                                 
614 | The wrap-around condition occurs for add, su    
615 | when                                            
616 |                                                 
617 |       abs(dest_exp - src_exp) >= $8000          
618 |                                                 
619 | and for mul when                                
620 |                                                 
621 |       (dest_exp + src_exp) < $0                 
622 |                                                 
623 | we must process the operation here if this c    
624 |                                                 
625 | The rts following the frcfpn routine is the     
626 | for this condition.  The restore flag (RES_F    
627 | No frestore is done unless an exception is t    
628 |                                                 
629 | For fadd:                                       
630 |       if(sign_of(dest) != sign_of(src))         
631 |               replace exponent of src with $    
632 |               use fpu to perform dest+new_sr    
633 |               clr sticky                        
634 |       else                                      
635 |               set sticky                        
636 |       call round with user's precision and m    
637 |       move result to fpn and wbtemp             
638 |                                                 
639 | For fsub:                                       
640 |       if(sign_of(dest) == sign_of(src))         
641 |               replace exponent of src with $    
642 |               use fpu to perform dest+new_sr    
643 |               clr sticky                        
644 |       else                                      
645 |               set sticky                        
646 |       call round with user's precision and m    
647 |       move result to fpn and wbtemp             
648 |                                                 
649 | For fdiv/fsgldiv:                               
650 |       if(both operands are denorm)              
651 |               restore_to_fpu;                   
652 |       if(dest is norm)                          
653 |               force_ovf;                        
654 |       else(dest is denorm)                      
655 |               force_unf:                        
656 |                                                 
657 | For fcmp:                                       
658 |       if(dest is norm)                          
659 |               N = sign_of(dest);                
660 |       else(dest is denorm)                      
661 |               N = sign_of(src);                 
662 |                                                 
663 | For fmul:                                       
664 |       if(both operands are denorm)              
665 |               force_unf;                        
666 |       if((dest_exp + src_exp) < 0)              
667 |               force_unf:                        
668 |       else                                      
669 |               restore_to_fpu;                   
670 |                                                 
671 | local equates:                                  
672         .set    addcode,0x22                      
673         .set    subcode,0x28                      
674         .set    mulcode,0x23                      
675         .set    divcode,0x20                      
676         .set    cmpcode,0x38                      
677 ck_wrap:                                          
678         | tstb  DY_MO_FLG(%a6)  ;check for fsq    
679         beq     fix_stk         |if zero, it i    
680         movew   CMDREG1B(%a6),%d0                 
681         andiw   #0x3b,%d0               |strip    
682         cmpiw   #addcode,%d0                      
683         beq     wrap_add                          
684         cmpiw   #subcode,%d0                      
685         beq     wrap_sub                          
686         cmpiw   #mulcode,%d0                      
687         beq     wrap_mul                          
688         cmpiw   #cmpcode,%d0                      
689         beq     wrap_cmp                          
690 |                                                 
691 | Inst is fdiv.                                   
692 |                                                 
693 wrap_div:                                         
694         cmpb    #0xff,DNRM_FLG(%a6) |if both o    
695         beq     fix_stk          |restore to f    
696 |                                                 
697 | One of the ops is denormalized.  Test for wr    
698 | and force the result.                           
699 |                                                 
700         cmpb    #0x0f,DNRM_FLG(%a6) |check for    
701         bnes    div_srcd                          
702 div_destd:                                        
703         bsrl    ckinf_ns                          
704         bne     fix_stk                           
705         bfextu  ETEMP_EX(%a6){#1:#15},%d0         
706         bfexts  FPTEMP_EX(%a6){#1:#15},%d1        
707         subl    %d1,%d0                 |subtr    
708         cmpl    #0x7fff,%d0                       
709         blt     fix_stk                 |if le    
710         clrb    WBTEMP_SGN(%a6)                   
711         movew   ETEMP_EX(%a6),%d0                 
712         movew   FPTEMP_EX(%a6),%d1                
713         eorw    %d1,%d0                           
714         andiw   #0x8000,%d0                       
715         beq     force_unf                         
716         st      WBTEMP_SGN(%a6)                   
717         bra     force_unf                         
718                                                   
719 ckinf_ns:                                         
720         moveb   STAG(%a6),%d0           |check    
721         bra     ck_in_com                         
722 ckinf_nd:                                         
723         moveb   DTAG(%a6),%d0           |check    
724 ck_in_com:                                        
725         andib   #0x60,%d0                         
726         cmpb    #0x40,%d0                         
727         beq     nan_or_inf              |not w    
728         cmpb    #0x60,%d0                         
729         beq     nan_or_inf              |yes,     
730         cmpb    #0x20,%d0                         
731         beq     nan_or_inf              |yes      
732         clrl    %d0                               
733         rts                             |then     
734 |                                       ;check    
735 nan_or_inf:                                       
736         moveql  #-1,%d0                           
737         rts                                       
738                                                   
739                                                   
740                                                   
741 div_srcd:                                         
742         bsrl    ckinf_nd                          
743         bne     fix_stk                           
744         bfextu  FPTEMP_EX(%a6){#1:#15},%d0        
745         bfexts  ETEMP_EX(%a6){#1:#15},%d1         
746         subl    %d1,%d0                 |subtr    
747         cmpl    #0x8000,%d0                       
748         blt     fix_stk                 |if le    
749         clrb    WBTEMP_SGN(%a6)                   
750         movew   ETEMP_EX(%a6),%d0                 
751         movew   FPTEMP_EX(%a6),%d1                
752         eorw    %d1,%d0                           
753         andiw   #0x8000,%d0                       
754         beqs    force_ovf                         
755         st      WBTEMP_SGN(%a6)                   
756 |                                                 
757 | This code handles the case of the instructio    
758 | an overflow condition.                          
759 |                                                 
760 force_ovf:                                        
761         bclrb   #E1,E_BYTE(%a6)                   
762         orl     #ovfl_inx_mask,USER_FPSR(%a6)     
763         clrw    NMNEXC(%a6)                       
764         leal    WBTEMP(%a6),%a0         |point    
765         movew   CMDREG1B(%a6),%d0                 
766         btstl   #6,%d0                  |test     
767         beqs    frcovf_fpcr                       
768         btstl   #2,%d0                  |check    
769         bnes    frcovf_dbl                        
770         movel   #0x1,%d0                          
771         bras    frcovf_rnd                        
772 frcovf_dbl:                                       
773         movel   #0x2,%d0                          
774         bras    frcovf_rnd                        
775 frcovf_fpcr:                                      
776         bfextu  FPCR_MODE(%a6){#0:#2},%d0         
777 frcovf_rnd:                                       
778                                                   
779 | The 881/882 does not set inex2 for the follo    
780 | line is commented out to be compatible with     
781 |       tst.b   %d0                               
782 |       beq.b   frcovf_x                          
783 |       or.l    #inex2_mask,USER_FPSR(%a6) ;if    
784                                                   
785 |frcovf_x:                                        
786         bsrl    ovf_res                 |get c    
787 |                                       ;round    
788 |                                       ;sets     
789 |                                       ;retur    
790         bfclr   WBTEMP_SGN(%a6){#0:#8}            
791         beq     frcfpn                            
792         bsetb   #sign_bit,WBTEMP_EX(%a6)          
793         bra     frcfpn                            
794 |                                                 
795 | Inst is fadd.                                   
796 |                                                 
797 wrap_add:                                         
798         cmpb    #0xff,DNRM_FLG(%a6) |if both o    
799         beq     fix_stk          |restore to f    
800 |                                                 
801 | One of the ops is denormalized.  Test for wr    
802 | and complete the instruction.                   
803 |                                                 
804         cmpb    #0x0f,DNRM_FLG(%a6) |check for    
805         bnes    add_srcd                          
806 add_destd:                                        
807         bsrl    ckinf_ns                          
808         bne     fix_stk                           
809         bfextu  ETEMP_EX(%a6){#1:#15},%d0         
810         bfexts  FPTEMP_EX(%a6){#1:#15},%d1        
811         subl    %d1,%d0                 |subtr    
812         cmpl    #0x8000,%d0                       
813         blt     fix_stk                 |if le    
814         bra     add_wrap                          
815 add_srcd:                                         
816         bsrl    ckinf_nd                          
817         bne     fix_stk                           
818         bfextu  FPTEMP_EX(%a6){#1:#15},%d0        
819         bfexts  ETEMP_EX(%a6){#1:#15},%d1         
820         subl    %d1,%d0                 |subtr    
821         cmpl    #0x8000,%d0                       
822         blt     fix_stk                 |if le    
823 |                                                 
824 | Check the signs of the operands.  If they ar    
825 | can be used to add the norm and 1.0 with the    
826 | denorm and it will correctly generate the re    
827 | precision.  We can then call round with no s    
828 | will be correct for the user's rounding mode    
829 | the signs are the same, we call round with t    
830 | and the result will be correct for the user'    
831 | precision.                                      
832 |                                                 
833 add_wrap:                                         
834         movew   ETEMP_EX(%a6),%d0                 
835         movew   FPTEMP_EX(%a6),%d1                
836         eorw    %d1,%d0                           
837         andiw   #0x8000,%d0                       
838         beq     add_same                          
839 |                                                 
840 | The signs are unlike.                           
841 |                                                 
842         cmpb    #0x0f,DNRM_FLG(%a6) |is dest t    
843         bnes    add_u_srcd                        
844         movew   FPTEMP_EX(%a6),%d0                
845         andiw   #0x8000,%d0                       
846         orw     #0x3fff,%d0     |force the exp    
847         movew   %d0,FPTEMP_EX(%a6) |in the den    
848         movel   USER_FPCR(%a6),%d0                
849         andil   #0x30,%d0                         
850         fmovel  %d0,%fpcr               |set u    
851         fmovex  ETEMP(%a6),%fp0                   
852         faddx   FPTEMP(%a6),%fp0                  
853         leal    WBTEMP(%a6),%a0 |point a0 to w    
854         fmovel  %fpsr,%d1                         
855         orl     %d1,USER_FPSR(%a6) |capture cc    
856         fmovex  %fp0,WBTEMP(%a6)        |write    
857         lsrl    #4,%d0          |put rmode in     
858         movel   USER_FPCR(%a6),%d1                
859         andil   #0xc0,%d1                         
860         lsrl    #6,%d1          |put precision    
861         swap    %d1                               
862         orl     %d0,%d1         |set up for ro    
863         clrl    %d0             |force sticky     
864         bclrb   #sign_bit,WBTEMP_EX(%a6)          
865         sne     WBTEMP_SGN(%a6)                   
866         bsrl    round           |round result     
867         bfclr   WBTEMP_SGN(%a6){#0:#8}  |conve    
868         beq     frcfpnr                           
869         bsetb   #sign_bit,WBTEMP_EX(%a6)          
870         bra     frcfpnr                           
871 add_u_srcd:                                       
872         movew   ETEMP_EX(%a6),%d0                 
873         andiw   #0x8000,%d0                       
874         orw     #0x3fff,%d0     |force the exp    
875         movew   %d0,ETEMP_EX(%a6) |in the deno    
876         movel   USER_FPCR(%a6),%d0                
877         andil   #0x30,%d0                         
878         fmovel  %d0,%fpcr               |set u    
879         fmovex  ETEMP(%a6),%fp0                   
880         faddx   FPTEMP(%a6),%fp0                  
881         fmovel  %fpsr,%d1                         
882         orl     %d1,USER_FPSR(%a6) |capture cc    
883         leal    WBTEMP(%a6),%a0 |point a0 to w    
884         fmovex  %fp0,WBTEMP(%a6)        |write    
885         lsrl    #4,%d0          |put rmode in     
886         movel   USER_FPCR(%a6),%d1                
887         andil   #0xc0,%d1                         
888         lsrl    #6,%d1          |put precision    
889         swap    %d1                               
890         orl     %d0,%d1         |set up for ro    
891         clrl    %d0             |force sticky     
892         bclrb   #sign_bit,WBTEMP_EX(%a6)          
893         sne     WBTEMP_SGN(%a6) |use internal     
894         bsrl    round           |round result     
895         bfclr   WBTEMP_SGN(%a6){#0:#8}  |conve    
896         beq     frcfpnr                           
897         bsetb   #sign_bit,WBTEMP_EX(%a6)          
898         bra     frcfpnr                           
899 |                                                 
900 | Signs are alike:                                
901 |                                                 
902 add_same:                                         
903         cmpb    #0x0f,DNRM_FLG(%a6) |is dest t    
904         bnes    add_s_srcd                        
905 add_s_destd:                                      
906         leal    ETEMP(%a6),%a0                    
907         movel   USER_FPCR(%a6),%d0                
908         andil   #0x30,%d0                         
909         lsrl    #4,%d0          |put rmode in     
910         movel   USER_FPCR(%a6),%d1                
911         andil   #0xc0,%d1                         
912         lsrl    #6,%d1          |put precision    
913         swap    %d1                               
914         orl     %d0,%d1         |set up for ro    
915         movel   #0x20000000,%d0 |set sticky fo    
916         bclrb   #sign_bit,ETEMP_EX(%a6)           
917         sne     ETEMP_SGN(%a6)                    
918         bsrl    round           |round result     
919         bfclr   ETEMP_SGN(%a6){#0:#8}   |conve    
920         beqs    add_s_dclr                        
921         bsetb   #sign_bit,ETEMP_EX(%a6)           
922 add_s_dclr:                                       
923         leal    WBTEMP(%a6),%a0                   
924         movel   ETEMP(%a6),(%a0)        |write    
925         movel   ETEMP_HI(%a6),4(%a0)              
926         movel   ETEMP_LO(%a6),8(%a0)              
927         tstw    ETEMP_EX(%a6)                     
928         bgt     add_ckovf                         
929         orl     #neg_mask,USER_FPSR(%a6)          
930         bra     add_ckovf                         
931 add_s_srcd:                                       
932         leal    FPTEMP(%a6),%a0                   
933         movel   USER_FPCR(%a6),%d0                
934         andil   #0x30,%d0                         
935         lsrl    #4,%d0          |put rmode in     
936         movel   USER_FPCR(%a6),%d1                
937         andil   #0xc0,%d1                         
938         lsrl    #6,%d1          |put precision    
939         swap    %d1                               
940         orl     %d0,%d1         |set up for ro    
941         movel   #0x20000000,%d0 |set sticky fo    
942         bclrb   #sign_bit,FPTEMP_EX(%a6)          
943         sne     FPTEMP_SGN(%a6)                   
944         bsrl    round           |round result     
945         bfclr   FPTEMP_SGN(%a6){#0:#8}  |conve    
946         beqs    add_s_sclr                        
947         bsetb   #sign_bit,FPTEMP_EX(%a6)          
948 add_s_sclr:                                       
949         leal    WBTEMP(%a6),%a0                   
950         movel   FPTEMP(%a6),(%a0)       |write    
951         movel   FPTEMP_HI(%a6),4(%a0)             
952         movel   FPTEMP_LO(%a6),8(%a0)             
953         tstw    FPTEMP_EX(%a6)                    
954         bgt     add_ckovf                         
955         orl     #neg_mask,USER_FPSR(%a6)          
956 add_ckovf:                                        
957         movew   WBTEMP_EX(%a6),%d0                
958         andiw   #0x7fff,%d0                       
959         cmpiw   #0x7fff,%d0                       
960         bne     frcfpnr                           
961 |                                                 
962 | The result has overflowed to $7fff exponent.    
963 | and aovfl, and clr the mantissa (incorrectly    
964 | round routine.)                                 
965 |                                                 
966         orl     #inf_mask+ovfl_inx_mask,USER_F    
967         clrl    4(%a0)                            
968         bra     frcfpnr                           
969 |                                                 
970 | Inst is fsub.                                   
971 |                                                 
972 wrap_sub:                                         
973         cmpb    #0xff,DNRM_FLG(%a6) |if both o    
974         beq     fix_stk          |restore to f    
975 |                                                 
976 | One of the ops is denormalized.  Test for wr    
977 | and complete the instruction.                   
978 |                                                 
979         cmpb    #0x0f,DNRM_FLG(%a6) |check for    
980         bnes    sub_srcd                          
981 sub_destd:                                        
982         bsrl    ckinf_ns                          
983         bne     fix_stk                           
984         bfextu  ETEMP_EX(%a6){#1:#15},%d0         
985         bfexts  FPTEMP_EX(%a6){#1:#15},%d1        
986         subl    %d1,%d0                 |subtr    
987         cmpl    #0x8000,%d0                       
988         blt     fix_stk                 |if le    
989         bra     sub_wrap                          
990 sub_srcd:                                         
991         bsrl    ckinf_nd                          
992         bne     fix_stk                           
993         bfextu  FPTEMP_EX(%a6){#1:#15},%d0        
994         bfexts  ETEMP_EX(%a6){#1:#15},%d1         
995         subl    %d1,%d0                 |subtr    
996         cmpl    #0x8000,%d0                       
997         blt     fix_stk                 |if le    
998 |                                                 
999 | Check the signs of the operands.  If they ar    
1000 | can be used to subtract from the norm 1.0 w    
1001 | denorm and it will correctly generate the r    
1002 | precision.  We can then call round with no     
1003 | will be correct for the user's rounding mod    
1004 | the signs are unlike, we call round with th    
1005 | and the result will be correct for the user    
1006 | precision.                                     
1007 |                                                
1008 sub_wrap:                                        
1009         movew   ETEMP_EX(%a6),%d0                
1010         movew   FPTEMP_EX(%a6),%d1               
1011         eorw    %d1,%d0                          
1012         andiw   #0x8000,%d0                      
1013         bne     sub_diff                         
1014 |                                                
1015 | The signs are alike.                           
1016 |                                                
1017         cmpb    #0x0f,DNRM_FLG(%a6) |is dest     
1018         bnes    sub_u_srcd                       
1019         movew   FPTEMP_EX(%a6),%d0               
1020         andiw   #0x8000,%d0                      
1021         orw     #0x3fff,%d0     |force the ex    
1022         movew   %d0,FPTEMP_EX(%a6) |in the de    
1023         movel   USER_FPCR(%a6),%d0               
1024         andil   #0x30,%d0                        
1025         fmovel  %d0,%fpcr               |set     
1026         fmovex  FPTEMP(%a6),%fp0                 
1027         fsubx   ETEMP(%a6),%fp0                  
1028         fmovel  %fpsr,%d1                        
1029         orl     %d1,USER_FPSR(%a6) |capture c    
1030         leal    WBTEMP(%a6),%a0 |point a0 to     
1031         fmovex  %fp0,WBTEMP(%a6)        |writ    
1032         lsrl    #4,%d0          |put rmode in    
1033         movel   USER_FPCR(%a6),%d1               
1034         andil   #0xc0,%d1                        
1035         lsrl    #6,%d1          |put precisio    
1036         swap    %d1                              
1037         orl     %d0,%d1         |set up for r    
1038         clrl    %d0             |force sticky    
1039         bclrb   #sign_bit,WBTEMP_EX(%a6)         
1040         sne     WBTEMP_SGN(%a6)                  
1041         bsrl    round           |round result    
1042         bfclr   WBTEMP_SGN(%a6){#0:#8}  |conv    
1043         beq     frcfpnr                          
1044         bsetb   #sign_bit,WBTEMP_EX(%a6)         
1045         bra     frcfpnr                          
1046 sub_u_srcd:                                      
1047         movew   ETEMP_EX(%a6),%d0                
1048         andiw   #0x8000,%d0                      
1049         orw     #0x3fff,%d0     |force the ex    
1050         movew   %d0,ETEMP_EX(%a6) |in the den    
1051         movel   USER_FPCR(%a6),%d0               
1052         andil   #0x30,%d0                        
1053         fmovel  %d0,%fpcr               |set     
1054         fmovex  FPTEMP(%a6),%fp0                 
1055         fsubx   ETEMP(%a6),%fp0                  
1056         fmovel  %fpsr,%d1                        
1057         orl     %d1,USER_FPSR(%a6) |capture c    
1058         leal    WBTEMP(%a6),%a0 |point a0 to     
1059         fmovex  %fp0,WBTEMP(%a6)        |writ    
1060         lsrl    #4,%d0          |put rmode in    
1061         movel   USER_FPCR(%a6),%d1               
1062         andil   #0xc0,%d1                        
1063         lsrl    #6,%d1          |put precisio    
1064         swap    %d1                              
1065         orl     %d0,%d1         |set up for r    
1066         clrl    %d0             |force sticky    
1067         bclrb   #sign_bit,WBTEMP_EX(%a6)         
1068         sne     WBTEMP_SGN(%a6)                  
1069         bsrl    round           |round result    
1070         bfclr   WBTEMP_SGN(%a6){#0:#8}  |conv    
1071         beq     frcfpnr                          
1072         bsetb   #sign_bit,WBTEMP_EX(%a6)         
1073         bra     frcfpnr                          
1074 |                                                
1075 | Signs are unlike:                              
1076 |                                                
1077 sub_diff:                                        
1078         cmpb    #0x0f,DNRM_FLG(%a6) |is dest     
1079         bnes    sub_s_srcd                       
1080 sub_s_destd:                                     
1081         leal    ETEMP(%a6),%a0                   
1082         movel   USER_FPCR(%a6),%d0               
1083         andil   #0x30,%d0                        
1084         lsrl    #4,%d0          |put rmode in    
1085         movel   USER_FPCR(%a6),%d1               
1086         andil   #0xc0,%d1                        
1087         lsrl    #6,%d1          |put precisio    
1088         swap    %d1                              
1089         orl     %d0,%d1         |set up for r    
1090         movel   #0x20000000,%d0 |set sticky f    
1091 |                                                
1092 | Since the dest is the denorm, the sign is t    
1093 | norm sign.                                     
1094 |                                                
1095         eoriw   #0x8000,ETEMP_EX(%a6)   |flip    
1096         tstw    ETEMP_EX(%a6)                    
1097         bgts    sub_s_dwr                        
1098         orl     #neg_mask,USER_FPSR(%a6)         
1099 sub_s_dwr:                                       
1100         bclrb   #sign_bit,ETEMP_EX(%a6)          
1101         sne     ETEMP_SGN(%a6)                   
1102         bsrl    round           |round result    
1103         bfclr   ETEMP_SGN(%a6){#0:#8}   |conv    
1104         beqs    sub_s_dclr                       
1105         bsetb   #sign_bit,ETEMP_EX(%a6)          
1106 sub_s_dclr:                                      
1107         leal    WBTEMP(%a6),%a0                  
1108         movel   ETEMP(%a6),(%a0)        |writ    
1109         movel   ETEMP_HI(%a6),4(%a0)             
1110         movel   ETEMP_LO(%a6),8(%a0)             
1111         bra     sub_ckovf                        
1112 sub_s_srcd:                                      
1113         leal    FPTEMP(%a6),%a0                  
1114         movel   USER_FPCR(%a6),%d0               
1115         andil   #0x30,%d0                        
1116         lsrl    #4,%d0          |put rmode in    
1117         movel   USER_FPCR(%a6),%d1               
1118         andil   #0xc0,%d1                        
1119         lsrl    #6,%d1          |put precisio    
1120         swap    %d1                              
1121         orl     %d0,%d1         |set up for r    
1122         movel   #0x20000000,%d0 |set sticky f    
1123         bclrb   #sign_bit,FPTEMP_EX(%a6)         
1124         sne     FPTEMP_SGN(%a6)                  
1125         bsrl    round           |round result    
1126         bfclr   FPTEMP_SGN(%a6){#0:#8}  |conv    
1127         beqs    sub_s_sclr                       
1128         bsetb   #sign_bit,FPTEMP_EX(%a6)         
1129 sub_s_sclr:                                      
1130         leal    WBTEMP(%a6),%a0                  
1131         movel   FPTEMP(%a6),(%a0)       |writ    
1132         movel   FPTEMP_HI(%a6),4(%a0)            
1133         movel   FPTEMP_LO(%a6),8(%a0)            
1134         tstw    FPTEMP_EX(%a6)                   
1135         bgt     sub_ckovf                        
1136         orl     #neg_mask,USER_FPSR(%a6)         
1137 sub_ckovf:                                       
1138         movew   WBTEMP_EX(%a6),%d0               
1139         andiw   #0x7fff,%d0                      
1140         cmpiw   #0x7fff,%d0                      
1141         bne     frcfpnr                          
1142 |                                                
1143 | The result has overflowed to $7fff exponent    
1144 | and aovfl, and clr the mantissa (incorrectl    
1145 | round routine.)                                
1146 |                                                
1147         orl     #inf_mask+ovfl_inx_mask,USER_    
1148         clrl    4(%a0)                           
1149         bra     frcfpnr                          
1150 |                                                
1151 | Inst is fcmp.                                  
1152 |                                                
1153 wrap_cmp:                                        
1154         cmpb    #0xff,DNRM_FLG(%a6) |if both     
1155         beq     fix_stk          |restore to     
1156 |                                                
1157 | One of the ops is denormalized.  Test for w    
1158 | and complete the instruction.                  
1159 |                                                
1160         cmpb    #0x0f,DNRM_FLG(%a6) |check fo    
1161         bnes    cmp_srcd                         
1162 cmp_destd:                                       
1163         bsrl    ckinf_ns                         
1164         bne     fix_stk                          
1165         bfextu  ETEMP_EX(%a6){#1:#15},%d0        
1166         bfexts  FPTEMP_EX(%a6){#1:#15},%d1       
1167         subl    %d1,%d0                 |subt    
1168         cmpl    #0x8000,%d0                      
1169         blt     fix_stk                 |if l    
1170         tstw    ETEMP_EX(%a6)           |set     
1171         bge     cmp_setn                         
1172         rts                                      
1173 cmp_srcd:                                        
1174         bsrl    ckinf_nd                         
1175         bne     fix_stk                          
1176         bfextu  FPTEMP_EX(%a6){#1:#15},%d0       
1177         bfexts  ETEMP_EX(%a6){#1:#15},%d1        
1178         subl    %d1,%d0                 |subt    
1179         cmpl    #0x8000,%d0                      
1180         blt     fix_stk                 |if l    
1181         tstw    FPTEMP_EX(%a6)          |set     
1182         blt     cmp_setn                         
1183         rts                                      
1184 cmp_setn:                                        
1185         orl     #neg_mask,USER_FPSR(%a6)         
1186         rts                                      
1187                                                  
1188 |                                                
1189 | Inst is fmul.                                  
1190 |                                                
1191 wrap_mul:                                        
1192         cmpb    #0xff,DNRM_FLG(%a6) |if both     
1193         beq     force_unf       |force an und    
1194 |                                                
1195 | One of the ops is denormalized.  Test for w    
1196 | and complete the instruction.                  
1197 |                                                
1198         cmpb    #0x0f,DNRM_FLG(%a6) |check fo    
1199         bnes    mul_srcd                         
1200 mul_destd:                                       
1201         bsrl    ckinf_ns                         
1202         bne     fix_stk                          
1203         bfextu  ETEMP_EX(%a6){#1:#15},%d0        
1204         bfexts  FPTEMP_EX(%a6){#1:#15},%d1       
1205         addl    %d1,%d0                 |subt    
1206         bgt     fix_stk                          
1207         bra     force_unf                        
1208 mul_srcd:                                        
1209         bsrl    ckinf_nd                         
1210         bne     fix_stk                          
1211         bfextu  FPTEMP_EX(%a6){#1:#15},%d0       
1212         bfexts  ETEMP_EX(%a6){#1:#15},%d1        
1213         addl    %d1,%d0                 |subt    
1214         bgt     fix_stk                          
1215                                                  
1216 |                                                
1217 | This code handles the case of the instructi    
1218 | an underflow condition.                        
1219 |                                                
1220 force_unf:                                       
1221         bclrb   #E1,E_BYTE(%a6)                  
1222         orl     #unfinx_mask,USER_FPSR(%a6)      
1223         clrw    NMNEXC(%a6)                      
1224         clrb    WBTEMP_SGN(%a6)                  
1225         movew   ETEMP_EX(%a6),%d0                
1226         movew   FPTEMP_EX(%a6),%d1               
1227         eorw    %d1,%d0                          
1228         andiw   #0x8000,%d0                      
1229         beqs    frcunfcont                       
1230         st      WBTEMP_SGN(%a6)                  
1231 frcunfcont:                                      
1232         lea     WBTEMP(%a6),%a0         |poin    
1233         movew   CMDREG1B(%a6),%d0                
1234         btstl   #6,%d0                  |test    
1235         beqs    frcunf_fpcr                      
1236         btstl   #2,%d0                  |chec    
1237         bnes    frcunf_dbl                       
1238         movel   #0x1,%d0                         
1239         bras    frcunf_rnd                       
1240 frcunf_dbl:                                      
1241         movel   #0x2,%d0                         
1242         bras    frcunf_rnd                       
1243 frcunf_fpcr:                                     
1244         bfextu  FPCR_MODE(%a6){#0:#2},%d0        
1245 frcunf_rnd:                                      
1246         bsrl    unf_sub                 |get     
1247 |                                       ;roun    
1248 |                                       ;sets    
1249         bfclr   WBTEMP_SGN(%a6){#0:#8}  |conv    
1250         beqs    frcfpn                           
1251         bsetb   #sign_bit,WBTEMP_EX(%a6)         
1252         bra     frcfpn                           
1253                                                  
1254 |                                                
1255 | Write the result to the user's fpn.  All re    
1256 | written; otherwise the results would have o    
1257 | If the rounding precision is single or doub    
1258 | is needed to correctly supply the max value    
1259 |                                                
1260 frcfpnr:                                         
1261         movew   CMDREG1B(%a6),%d0                
1262         btstl   #6,%d0                  |test    
1263         beqs    frcfpn_fpcr                      
1264         btstl   #2,%d0                  |chec    
1265         bnes    frcfpn_dbl                       
1266         movel   #0x1,%d0                         
1267         bras    frcfpn_rnd                       
1268 frcfpn_dbl:                                      
1269         movel   #0x2,%d0                         
1270         bras    frcfpn_rnd                       
1271 frcfpn_fpcr:                                     
1272         bfextu  FPCR_MODE(%a6){#0:#2},%d0        
1273         tstb    %d0                              
1274         beqs    frcfpn                  |if e    
1275 frcfpn_rnd:                                      
1276         bclrb   #sign_bit,WBTEMP_EX(%a6)         
1277         sne     WBTEMP_SGN(%a6)                  
1278         bsrl    ovf_res                 |get     
1279 |                                       ;roun    
1280 |                                       ;sets    
1281         bfclr   WBTEMP_SGN(%a6){#0:#8}  |conv    
1282         beqs    frcfpn_clr                       
1283         bsetb   #sign_bit,WBTEMP_EX(%a6)         
1284 frcfpn_clr:                                      
1285         orl     #ovfinx_mask,USER_FPSR(%a6)      
1286 |                                                
1287 | Perform the write.                             
1288 |                                                
1289 frcfpn:                                          
1290         bfextu  CMDREG1B(%a6){#6:#3},%d0         
1291         cmpib   #3,%d0                           
1292         bles    frc0123                 |chec    
1293         movel   #7,%d1                           
1294         subl    %d0,%d1                          
1295         clrl    %d0                              
1296         bsetl   %d1,%d0                          
1297         fmovemx WBTEMP(%a6),%d0                  
1298         rts                                      
1299 frc0123:                                         
1300         cmpib   #0,%d0                           
1301         beqs    frc0_dst                         
1302         cmpib   #1,%d0                           
1303         beqs    frc1_dst                         
1304         cmpib   #2,%d0                           
1305         beqs    frc2_dst                         
1306 frc3_dst:                                        
1307         movel   WBTEMP_EX(%a6),USER_FP3(%a6)     
1308         movel   WBTEMP_HI(%a6),USER_FP3+4(%a6    
1309         movel   WBTEMP_LO(%a6),USER_FP3+8(%a6    
1310         rts                                      
1311 frc2_dst:                                        
1312         movel   WBTEMP_EX(%a6),USER_FP2(%a6)     
1313         movel   WBTEMP_HI(%a6),USER_FP2+4(%a6    
1314         movel   WBTEMP_LO(%a6),USER_FP2+8(%a6    
1315         rts                                      
1316 frc1_dst:                                        
1317         movel   WBTEMP_EX(%a6),USER_FP1(%a6)     
1318         movel   WBTEMP_HI(%a6),USER_FP1+4(%a6    
1319         movel   WBTEMP_LO(%a6),USER_FP1+8(%a6    
1320         rts                                      
1321 frc0_dst:                                        
1322         movel   WBTEMP_EX(%a6),USER_FP0(%a6)     
1323         movel   WBTEMP_HI(%a6),USER_FP0+4(%a6    
1324         movel   WBTEMP_LO(%a6),USER_FP0+8(%a6    
1325         rts                                      
1326                                                  
1327 |                                                
1328 | Write etemp to fpn.                            
1329 | A check is made on enabled and signalled sn    
1330 | and the destination is not overwritten if t    
1331 | This code is designed to make fmoveins of u    
1332 | faster.                                        
1333 |                                                
1334 wr_etemp:                                        
1335         btstb   #snan_bit,FPSR_EXCEPT(%a6)       
1336         beqs    fmoveinc                |enab    
1337         btstb   #snan_bit,FPCR_ENABLE(%a6) |a    
1338         beqs    fmoveinc                |the     
1339         movel   ETEMP_EX(%a6),FPTEMP_EX(%a6)     
1340 |                                                
1341         tstb    ETEMP(%a6)              |chec    
1342         blts    snan_neg                         
1343         rts                                      
1344 snan_neg:                                        
1345         orl     #neg_bit,USER_FPSR(%a6) |snan    
1346         rts                                      
1347 fmoveinc:                                        
1348         clrw    NMNEXC(%a6)                      
1349         bclrb   #E1,E_BYTE(%a6)                  
1350         moveb   STAG(%a6),%d0           |chec    
1351         andib   #0xe0,%d0                        
1352         cmpib   #0x40,%d0                        
1353         bnes    fminc_cnan                       
1354         orl     #inf_mask,USER_FPSR(%a6) |if     
1355         tstw    LOCAL_EX(%a0)           |chec    
1356         bges    fminc_con                        
1357         orl     #neg_mask,USER_FPSR(%a6)         
1358         bra     fminc_con                        
1359 fminc_cnan:                                      
1360         cmpib   #0x60,%d0                        
1361         bnes    fminc_czero                      
1362         orl     #nan_mask,USER_FPSR(%a6) |if     
1363         movel   ETEMP_EX(%a6),FPTEMP_EX(%a6)     
1364 |                                                
1365         tstw    LOCAL_EX(%a0)           |chec    
1366         bges    fminc_con                        
1367         orl     #neg_mask,USER_FPSR(%a6)         
1368         bra     fminc_con                        
1369 fminc_czero:                                     
1370         cmpib   #0x20,%d0                        
1371         bnes    fminc_con                        
1372         orl     #z_mask,USER_FPSR(%a6)  |if z    
1373         tstw    LOCAL_EX(%a0)           |chec    
1374         bges    fminc_con                        
1375         orl     #neg_mask,USER_FPSR(%a6)         
1376 fminc_con:                                       
1377         bfextu  CMDREG1B(%a6){#6:#3},%d0         
1378         cmpib   #3,%d0                           
1379         bles    fp0123                  |chec    
1380         movel   #7,%d1                           
1381         subl    %d0,%d1                          
1382         clrl    %d0                              
1383         bsetl   %d1,%d0                          
1384         fmovemx ETEMP(%a6),%d0                   
1385         rts                                      
1386                                                  
1387 fp0123:                                          
1388         cmpib   #0,%d0                           
1389         beqs    fp0_dst                          
1390         cmpib   #1,%d0                           
1391         beqs    fp1_dst                          
1392         cmpib   #2,%d0                           
1393         beqs    fp2_dst                          
1394 fp3_dst:                                         
1395         movel   ETEMP_EX(%a6),USER_FP3(%a6)      
1396         movel   ETEMP_HI(%a6),USER_FP3+4(%a6)    
1397         movel   ETEMP_LO(%a6),USER_FP3+8(%a6)    
1398         rts                                      
1399 fp2_dst:                                         
1400         movel   ETEMP_EX(%a6),USER_FP2(%a6)      
1401         movel   ETEMP_HI(%a6),USER_FP2+4(%a6)    
1402         movel   ETEMP_LO(%a6),USER_FP2+8(%a6)    
1403         rts                                      
1404 fp1_dst:                                         
1405         movel   ETEMP_EX(%a6),USER_FP1(%a6)      
1406         movel   ETEMP_HI(%a6),USER_FP1+4(%a6)    
1407         movel   ETEMP_LO(%a6),USER_FP1+8(%a6)    
1408         rts                                      
1409 fp0_dst:                                         
1410         movel   ETEMP_EX(%a6),USER_FP0(%a6)      
1411         movel   ETEMP_HI(%a6),USER_FP0+4(%a6)    
1412         movel   ETEMP_LO(%a6),USER_FP0+8(%a6)    
1413         rts                                      
1414                                                  
1415 opclass3:                                        
1416         st      CU_ONLY(%a6)                     
1417         movew   CMDREG1B(%a6),%d0       |chec    
1418         andiw   #0x0c00,%d0     |isolate last    
1419         cmpiw   #0x0c00,%d0     |if size is 0    
1420         beq     pack_out        |else it is n    
1421         bra     mv_out                           
1422                                                  
1423                                                  
1424 |                                                
1425 |       MOVE OUT                                 
1426 |                                                
1427                                                  
1428 mv_tbl:                                          
1429         .long   li                               
1430         .long   sgp                              
1431         .long   xp                               
1432         .long   mvout_end       |should never    
1433         .long   wi                               
1434         .long   dp                               
1435         .long   bi                               
1436         .long   mvout_end       |should never    
1437 mv_out:                                          
1438         bfextu  CMDREG1B(%a6){#3:#3},%d1         
1439         leal    mv_tbl,%a0                       
1440         movel   %a0@(%d1:l:4),%a0                
1441         jmp     (%a0)                            
1442                                                  
1443 |                                                
1444 | This exit is for move-out to memory.  The a    
1445 | set if the result is inex and unfl is signa    
1446 |                                                
1447 mvout_end:                                       
1448         btstb   #inex2_bit,FPSR_EXCEPT(%a6)      
1449         beqs    no_aufl                          
1450         btstb   #unfl_bit,FPSR_EXCEPT(%a6)       
1451         beqs    no_aufl                          
1452         bsetb   #aunfl_bit,FPSR_AEXCEPT(%a6)     
1453 no_aufl:                                         
1454         clrw    NMNEXC(%a6)                      
1455         bclrb   #E1,E_BYTE(%a6)                  
1456         fmovel  #0,%FPSR                         
1457 |                                                
1458 | Return ETEMP to extended format from intern    
1459 | that gen_except will have a correctly signe    
1460 | handlers.                                      
1461 |                                                
1462         bfclr   ETEMP_SGN(%a6){#0:#8}            
1463         beqs    mvout_con                        
1464         bsetb   #sign_bit,ETEMP_EX(%a6)          
1465 mvout_con:                                       
1466         rts                                      
1467 |                                                
1468 | This exit is for move-out to int register.     
1469 | not set in any case for this move.             
1470 |                                                
1471 mvouti_end:                                      
1472         clrw    NMNEXC(%a6)                      
1473         bclrb   #E1,E_BYTE(%a6)                  
1474         fmovel  #0,%FPSR                         
1475 |                                                
1476 | Return ETEMP to extended format from intern    
1477 | that gen_except will have a correctly signe    
1478 | handlers.                                      
1479 |                                                
1480         bfclr   ETEMP_SGN(%a6){#0:#8}            
1481         beqs    mvouti_con                       
1482         bsetb   #sign_bit,ETEMP_EX(%a6)          
1483 mvouti_con:                                      
1484         rts                                      
1485 |                                                
1486 | li is used to handle a long integer source     
1487 |                                                
1488                                                  
1489 li:                                              
1490         moveql  #4,%d0          |set byte cou    
1491                                                  
1492         btstb   #7,STAG(%a6)    |check for ex    
1493         bne     int_dnrm        |if so, branc    
1494                                                  
1495         fmovemx ETEMP(%a6),%fp0-%fp0             
1496         fcmpd   #0x41dfffffffc00000,%fp0         
1497 | 41dfffffffc00000 in dbl prec = 401d0000ffff    
1498         fbge    lo_plrg                          
1499         fcmpd   #0xc1e0000000000000,%fp0         
1500 | c1e0000000000000 in dbl prec = c01e00008000    
1501         fble    lo_nlrg                          
1502 |                                                
1503 | at this point, the answer is between the la    
1504 |                                                
1505         movel   USER_FPCR(%a6),%d1      |use     
1506         andil   #0x30,%d1                        
1507         fmovel  %d1,%fpcr                        
1508         fmovel  %fp0,L_SCR1(%a6)        |let     
1509         fmovel %fpsr,%d1                         
1510         orl     %d1,USER_FPSR(%a6)      |capt    
1511         bra     int_wrt                          
1512                                                  
1513                                                  
1514 lo_plrg:                                         
1515         movel   #0x7fffffff,L_SCR1(%a6) |answ    
1516         fbeq    int_wrt                 |exac    
1517         fcmpd   #0x41dfffffffe00000,%fp0         
1518 | 41dfffffffe00000 in dbl prec = 401d0000ffff    
1519         fbge    int_operr               |set     
1520         bra     int_inx                 |set     
1521                                                  
1522 lo_nlrg:                                         
1523         movel   #0x80000000,L_SCR1(%a6)          
1524         fbeq    int_wrt                 |exac    
1525         fcmpd   #0xc1e0000000100000,%fp0         
1526 | c1e0000000100000 in dbl prec = c01e00008000    
1527         fblt    int_operr               |set     
1528         bra     int_inx                 |set     
1529                                                  
1530 |                                                
1531 | wi is used to handle a word integer source     
1532 |                                                
1533                                                  
1534 wi:                                              
1535         moveql  #2,%d0          |set byte cou    
1536                                                  
1537         btstb   #7,STAG(%a6)    |check for ex    
1538         bne     int_dnrm        |branch if so    
1539                                                  
1540         fmovemx ETEMP(%a6),%fp0-%fp0             
1541         fcmps   #0x46fffe00,%fp0                 
1542 | 46fffe00 in sgl prec = 400d0000fffe00000000    
1543         fbge    wo_plrg                          
1544         fcmps   #0xc7000000,%fp0                 
1545 | c7000000 in sgl prec = c00e0000800000000000    
1546         fble    wo_nlrg                          
1547                                                  
1548 |                                                
1549 | at this point, the answer is between the la    
1550 |                                                
1551         movel   USER_FPCR(%a6),%d1      |use     
1552         andil   #0x30,%d1                        
1553         fmovel  %d1,%fpcr                        
1554         fmovew  %fp0,L_SCR1(%a6)        |let     
1555         fmovel %fpsr,%d1                         
1556         orl     %d1,USER_FPSR(%a6)      |capt    
1557         bra     int_wrt                          
1558                                                  
1559 wo_plrg:                                         
1560         movew   #0x7fff,L_SCR1(%a6)     |answ    
1561         fbeq    int_wrt                 |exac    
1562         fcmps   #0x46ffff00,%fp0                 
1563 | 46ffff00 in sgl prec = 400d0000ffff00000000    
1564         fbge    int_operr               |set     
1565         bra     int_inx                 |set     
1566                                                  
1567 wo_nlrg:                                         
1568         movew   #0x8000,L_SCR1(%a6)              
1569         fbeq    int_wrt                 |exac    
1570         fcmps   #0xc7000080,%fp0                 
1571 | c7000080 in sgl prec = c00e0000800080000000    
1572         fblt    int_operr               |set     
1573         bra     int_inx                 |set     
1574                                                  
1575 |                                                
1576 | bi is used to handle a byte integer source     
1577 |                                                
1578                                                  
1579 bi:                                              
1580         moveql  #1,%d0          |set byte cou    
1581                                                  
1582         btstb   #7,STAG(%a6)    |check for ex    
1583         bne     int_dnrm        |branch if so    
1584                                                  
1585         fmovemx ETEMP(%a6),%fp0-%fp0             
1586         fcmps   #0x42fe0000,%fp0                 
1587 | 42fe0000 in sgl prec = 40050000fe0000000000    
1588         fbge    by_plrg                          
1589         fcmps   #0xc3000000,%fp0                 
1590 | c3000000 in sgl prec = c0060000800000000000    
1591         fble    by_nlrg                          
1592                                                  
1593 |                                                
1594 | at this point, the answer is between the la    
1595 |                                                
1596         movel   USER_FPCR(%a6),%d1      |use     
1597         andil   #0x30,%d1                        
1598         fmovel  %d1,%fpcr                        
1599         fmoveb  %fp0,L_SCR1(%a6)        |let     
1600         fmovel %fpsr,%d1                         
1601         orl     %d1,USER_FPSR(%a6)      |capt    
1602         bra     int_wrt                          
1603                                                  
1604 by_plrg:                                         
1605         moveb   #0x7f,L_SCR1(%a6)                
1606         fbeq    int_wrt                 |exac    
1607         fcmps   #0x42ff0000,%fp0                 
1608 | 42ff0000 in sgl prec = 40050000ff0000000000    
1609         fbge    int_operr               |set     
1610         bra     int_inx                 |set     
1611                                                  
1612 by_nlrg:                                         
1613         moveb   #0x80,L_SCR1(%a6)                
1614         fbeq    int_wrt                 |exac    
1615         fcmps   #0xc3008000,%fp0                 
1616 | c3008000 in sgl prec = c0060000808000000000    
1617         fblt    int_operr               |set     
1618         bra     int_inx                 |set     
1619                                                  
1620 |                                                
1621 | Common integer routines                        
1622 |                                                
1623 | int_drnrm---account for possible nonzero re    
1624 | operand and round down for negative answer.    
1625 | byte-width (store in d0) of result must be     
1626 | -1 in L_SCR1(a6) will cover all contingenci    
1627                                                  
1628 int_dnrm:                                        
1629         movel   #0,L_SCR1(%a6)  | initialize     
1630         bfextu  FPCR_MODE(%a6){#2:#2},%d1        
1631         cmpb    #2,%d1                           
1632         bmis    int_inx         | if RN or RZ    
1633         bnes    int_rp          | if RP, cont    
1634         tstw    ETEMP(%a6)      | RM: store -    
1635         bpls    int_inx         | otherwise r    
1636         movel   #-1,L_SCR1(%a6)                  
1637         bras    int_inx                          
1638 int_rp:                                          
1639         tstw    ETEMP(%a6)      | RP: store +    
1640 |                               ; source is g    
1641         bmis    int_inx         | otherwise,     
1642         lea     L_SCR1(%a6),%a1 | a1 is addre    
1643         addal   %d0,%a1         | offset by d    
1644         subal   #1,%a1                           
1645         bsetb   #0,(%a1)                | set    
1646 int_inx:                                         
1647         oril    #inx2a_mask,USER_FPSR(%a6)       
1648         bras    int_wrt                          
1649 int_operr:                                       
1650         fmovemx %fp0-%fp0,FPTEMP(%a6)   |FPTE    
1651 |                               ;precision so    
1652 |                               ;converted to    
1653 |                               ;if the operr    
1654 |                               ;set operr/ai    
1655                                                  
1656         oril    #opaop_mask,USER_FPSR(%a6)       
1657 |                               ;fall through    
1658 int_wrt:                                         
1659         movel   EXC_EA(%a6),%a1 |load destina    
1660         tstl    %a1             |check to see    
1661         beqs    wrt_dn          |write data r    
1662         lea     L_SCR1(%a6),%a0 |point to sup    
1663         bsrl    mem_write                        
1664         bra     mvouti_end                       
1665                                                  
1666 wrt_dn:                                          
1667         movel   %d0,-(%sp)      |d0 currently    
1668         bsrl    get_fline       |get_fline re    
1669         andiw   #0x7,%d0                |isol    
1670         movel   (%sp)+,%d1      |get size        
1671         cmpil   #4,%d1          |most frequen    
1672         beqs    sz_long                          
1673         cmpil   #2,%d1                           
1674         bnes    sz_con                           
1675         orl     #8,%d0          |add 'word' s    
1676         bras    sz_con                           
1677 sz_long:                                         
1678         orl     #0x10,%d0               |add     
1679 sz_con:                                          
1680         movel   %d0,%d1         |reg_dest exp    
1681         bsrl    reg_dest        |load proper     
1682         bra     mvouti_end                       
1683 xp:                                              
1684         lea     ETEMP(%a6),%a0                   
1685         bclrb   #sign_bit,LOCAL_EX(%a0)          
1686         sne     LOCAL_SGN(%a0)                   
1687         btstb   #7,STAG(%a6)    |check for ex    
1688         bne     xdnrm                            
1689         clrl    %d0                              
1690         bras    do_fp           |do normal ca    
1691 sgp:                                             
1692         lea     ETEMP(%a6),%a0                   
1693         bclrb   #sign_bit,LOCAL_EX(%a0)          
1694         sne     LOCAL_SGN(%a0)                   
1695         btstb   #7,STAG(%a6)    |check for ex    
1696         bne     sp_catas        |branch if so    
1697         movew   LOCAL_EX(%a0),%d0                
1698         lea     sp_bnds,%a1                      
1699         cmpw    (%a1),%d0                        
1700         blt     sp_under                         
1701         cmpw    2(%a1),%d0                       
1702         bgt     sp_over                          
1703         movel   #1,%d0          |set destinat    
1704         bras    do_fp           |do normal ca    
1705 dp:                                              
1706         lea     ETEMP(%a6),%a0                   
1707         bclrb   #sign_bit,LOCAL_EX(%a0)          
1708         sne     LOCAL_SGN(%a0)                   
1709                                                  
1710         btstb   #7,STAG(%a6)    |check for ex    
1711         bne     dp_catas        |branch if so    
1712                                                  
1713         movew   LOCAL_EX(%a0),%d0                
1714         lea     dp_bnds,%a1                      
1715                                                  
1716         cmpw    (%a1),%d0                        
1717         blt     dp_under                         
1718         cmpw    2(%a1),%d0                       
1719         bgt     dp_over                          
1720                                                  
1721         movel   #2,%d0          |set destinat    
1722 |                               ;fall through    
1723 |                                                
1724 do_fp:                                           
1725         bfextu  FPCR_MODE(%a6){#2:#2},%d1        
1726         swap    %d0                     |rnd     
1727         addl    %d0,%d1                 |d1 h    
1728                                                  
1729         clrl    %d0                     |clea    
1730                                                  
1731         bsrl    round                   |roun    
1732                                                  
1733         movel   %a0,%a1                          
1734         movel   EXC_EA(%a6),%a0                  
1735                                                  
1736         bfextu  CMDREG1B(%a6){#3:#3},%d1         
1737 |                                       ;at t    
1738 |                                       ;form    
1739 |                                       ;poss    
1740         cmpb    #2,%d1                           
1741         bgts    ddbl                    |doub    
1742         bnes    dsgl                             
1743 |                                       ;fall    
1744 dext:                                            
1745         bsrl    dest_ext                         
1746         bra     mvout_end                        
1747 dsgl:                                            
1748         bsrl    dest_sgl                         
1749         bra     mvout_end                        
1750 ddbl:                                            
1751         bsrl    dest_dbl                         
1752         bra     mvout_end                        
1753                                                  
1754 |                                                
1755 | Handle possible denorm or catastrophic unde    
1756 |                                                
1757 xdnrm:                                           
1758         bsr     set_xop         |initialize W    
1759         bsetb   #wbtemp15_bit,WB_BYTE(%a6) |s    
1760                                                  
1761         movel   %a0,%a1                          
1762         movel   EXC_EA(%a6),%a0 |a0 has the d    
1763         bsrl    dest_ext        |store to mem    
1764         bsetb   #unfl_bit,FPSR_EXCEPT(%a6)       
1765         bra     mvout_end                        
1766                                                  
1767 sp_under:                                        
1768         bsetb   #etemp15_bit,STAG(%a6)           
1769                                                  
1770         cmpw    4(%a1),%d0                       
1771         blts    sp_catas        |catastrophic    
1772                                                  
1773         movel   #1,%d0          |load in roun    
1774         movel   #sgl_thresh,%d1 |load in sing    
1775         bsrl    dpspdnrm        |expects d1 t    
1776 |                               ;denorm thres    
1777         bsrl    dest_sgl        |stores value    
1778         bsetb   #unfl_bit,FPSR_EXCEPT(%a6)       
1779         bra     mvout_end       |exit            
1780                                                  
1781 dp_under:                                        
1782         bsetb   #etemp15_bit,STAG(%a6)           
1783                                                  
1784         cmpw    4(%a1),%d0                       
1785         blts    dp_catas        |catastrophic    
1786                                                  
1787         movel   #dbl_thresh,%d1 |load in doub    
1788         movel   #2,%d0                           
1789         bsrl    dpspdnrm        |expects d1 t    
1790 |                               ;denorm thres    
1791 |                               ;expects d0 t    
1792         bsrl    dest_dbl        |store value     
1793         bsetb   #unfl_bit,FPSR_EXCEPT(%a6)       
1794         bra     mvout_end       |exit            
1795                                                  
1796 |                                                
1797 | Handle catastrophic underflow cases here       
1798 |                                                
1799 sp_catas:                                        
1800 | Temp fix for z bit set in unf_sub              
1801         movel   USER_FPSR(%a6),-(%a7)            
1802                                                  
1803         movel   #1,%d0          |set round pr    
1804                                                  
1805         bsrl    unf_sub         |a0 points to    
1806                                                  
1807         movel   (%a7)+,USER_FPSR(%a6)            
1808                                                  
1809         movel   #1,%d0                           
1810         subw    %d0,LOCAL_EX(%a0) |account fo    
1811 |                               ;denorm/norm     
1812                                                  
1813         movel   %a0,%a1         |a1 has the o    
1814         movel   EXC_EA(%a6),%a0 |a0 has the d    
1815                                                  
1816         bsrl    dest_sgl        |store the re    
1817         oril    #unfinx_mask,USER_FPSR(%a6)      
1818         bra     mvout_end                        
1819                                                  
1820 dp_catas:                                        
1821 | Temp fix for z bit set in unf_sub              
1822         movel   USER_FPSR(%a6),-(%a7)            
1823                                                  
1824         movel   #2,%d0          |set round pr    
1825         bsrl    unf_sub         |a0 points to    
1826                                                  
1827         movel   (%a7)+,USER_FPSR(%a6)            
1828                                                  
1829         movel   #1,%d0                           
1830         subw    %d0,LOCAL_EX(%a0) |account fo    
1831 |                               ;denorm/norm     
1832                                                  
1833         movel   %a0,%a1         |a1 has the o    
1834         movel   EXC_EA(%a6),%a0 |a0 has the d    
1835                                                  
1836         bsrl    dest_dbl        |store the re    
1837         oril    #unfinx_mask,USER_FPSR(%a6)      
1838         bra     mvout_end                        
1839                                                  
1840 |                                                
1841 | Handle catastrophic overflow cases here        
1842 |                                                
1843 sp_over:                                         
1844 | Temp fix for z bit set in unf_sub              
1845         movel   USER_FPSR(%a6),-(%a7)            
1846                                                  
1847         movel   #1,%d0                           
1848         leal    FP_SCR1(%a6),%a0        |use     
1849         movel   ETEMP_EX(%a6),(%a0)              
1850         movel   ETEMP_HI(%a6),4(%a0)             
1851         movel   ETEMP_LO(%a6),8(%a0)             
1852         bsrl    ovf_res                          
1853                                                  
1854         movel   (%a7)+,USER_FPSR(%a6)            
1855                                                  
1856         movel   %a0,%a1                          
1857         movel   EXC_EA(%a6),%a0                  
1858         bsrl    dest_sgl                         
1859         orl     #ovfinx_mask,USER_FPSR(%a6)      
1860         bra     mvout_end                        
1861                                                  
1862 dp_over:                                         
1863 | Temp fix for z bit set in ovf_res              
1864         movel   USER_FPSR(%a6),-(%a7)            
1865                                                  
1866         movel   #2,%d0                           
1867         leal    FP_SCR1(%a6),%a0        |use     
1868         movel   ETEMP_EX(%a6),(%a0)              
1869         movel   ETEMP_HI(%a6),4(%a0)             
1870         movel   ETEMP_LO(%a6),8(%a0)             
1871         bsrl    ovf_res                          
1872                                                  
1873         movel   (%a7)+,USER_FPSR(%a6)            
1874                                                  
1875         movel   %a0,%a1                          
1876         movel   EXC_EA(%a6),%a0                  
1877         bsrl    dest_dbl                         
1878         orl     #ovfinx_mask,USER_FPSR(%a6)      
1879         bra     mvout_end                        
1880                                                  
1881 |                                                
1882 |       DPSPDNRM                                 
1883 |                                                
1884 | This subroutine takes an extended normalize    
1885 | it to the given round precision. This subro    
1886 | the input operand's exponent by 1 to accoun    
1887 | dest_sgl or dest_dbl expects a normalized n    
1888 |                                                
1889 | Input: a0  points to a normalized number in    
1890 |        d0  is the round precision (=1 for s    
1891 |        d1  is the single precision or doubl    
1892 |            denorm threshold                    
1893 |                                                
1894 | Output: (In the format for dest_sgl or dest    
1895 |        a0   points to the destination          
1896 |        a1   points to the operand              
1897 |                                                
1898 | Exceptions: Reports inexact 2 exception by     
1899 |                                                
1900 dpspdnrm:                                        
1901         movel   %d0,-(%a7)      |save round p    
1902         clrl    %d0             |clear initia    
1903         bsrl    dnrm_lp         |careful with    
1904                                                  
1905         bfextu  FPCR_MODE(%a6){#2:#2},%d1 |ge    
1906         swap    %d1                              
1907         movew   2(%a7),%d1      |set rounding    
1908         swap    %d1             |at this poin    
1909         bsrl    round           |round result    
1910 |                               ;USER_FPSR if    
1911                                                  
1912         movew   #1,%d0                           
1913         subw    %d0,LOCAL_EX(%a0) |account fo    
1914 |                               ;vs norm bias    
1915                                                  
1916         movel   %a0,%a1         |a1 has the o    
1917         movel   EXC_EA(%a6),%a0 |a0 has the d    
1918         addw    #4,%a7          |pop stack       
1919         rts                                      
1920 |                                                
1921 | SET_XOP initialized WBTEMP with the value p    
1922 | input: a0 points to input operand in the in    
1923 |                                                
1924 set_xop:                                         
1925         movel   LOCAL_EX(%a0),WBTEMP_EX(%a6)     
1926         movel   LOCAL_HI(%a0),WBTEMP_HI(%a6)     
1927         movel   LOCAL_LO(%a0),WBTEMP_LO(%a6)     
1928         bfclr   WBTEMP_SGN(%a6){#0:#8}           
1929         beqs    sxop                             
1930         bsetb   #sign_bit,WBTEMP_EX(%a6)         
1931 sxop:                                            
1932         bfclr   STAG(%a6){#5:#4}        |clea    
1933         rts                                      
1934 |                                                
1935 |       P_MOVE                                   
1936 |                                                
1937 p_movet:                                         
1938         .long   p_move                           
1939         .long   p_movez                          
1940         .long   p_movei                          
1941         .long   p_moven                          
1942         .long   p_move                           
1943 p_regd:                                          
1944         .long   p_dyd0                           
1945         .long   p_dyd1                           
1946         .long   p_dyd2                           
1947         .long   p_dyd3                           
1948         .long   p_dyd4                           
1949         .long   p_dyd5                           
1950         .long   p_dyd6                           
1951         .long   p_dyd7                           
1952                                                  
1953 pack_out:                                        
1954         leal    p_movet,%a0     |load jmp tab    
1955         movew   STAG(%a6),%d0   |get source t    
1956         bfextu  %d0{#16:#3},%d0 |isolate sour    
1957         movel   (%a0,%d0.w*4),%a0       |load    
1958         jmp     (%a0)           |go to the ro    
1959                                                  
1960 p_write:                                         
1961         movel   #0x0c,%d0       |get byte cou    
1962         movel   EXC_EA(%a6),%a1 |get the dest    
1963         bsr     mem_write       |write the us    
1964         moveb   #0,CU_SAVEPC(%a6) |set the cu    
1965                                                  
1966 |                                                
1967 | Also note that the dtag must be set to norm    
1968 | the 040 uses the dtag to execute the correc    
1969 |                                                
1970         bfclr    DTAG(%a6){#0:#3}  |set dtag     
1971                                                  
1972         rts                                      
1973                                                  
1974 | Notes on handling of special case (zero, in    
1975 |       1. Operr is not signalled if the k-fa    
1976 |       2. Per the manual, status bits are no    
1977 |                                                
1978                                                  
1979 p_move:                                          
1980         movew   CMDREG1B(%a6),%d0                
1981         btstl   #kfact_bit,%d0  |test for dyn    
1982         beqs    statick         |if clear, k-    
1983 dynamick:                                        
1984         bfextu  %d0{#25:#3},%d0 |isolate regi    
1985         lea     p_regd,%a0                       
1986         movel   %a0@(%d0:l:4),%a0                
1987         jmp     (%a0)                            
1988 statick:                                         
1989         andiw   #0x007f,%d0     |get k-factor    
1990         bfexts  %d0{#25:#7},%d0 |sign extend     
1991         leal    ETEMP(%a6),%a0  |a0 will poin    
1992         bsrl    bindec          |perform the     
1993         leal    FP_SCR1(%a6),%a0        |load    
1994         bral    p_write                          
1995 p_movez:                                         
1996         leal    ETEMP(%a6),%a0  |a0 will poin    
1997         clrw    2(%a0)          |clear lower     
1998         clrl    4(%a0)          |load second     
1999         clrl    8(%a0)          |load third l    
2000         bra     p_write         |go write res    
2001 p_movei:                                         
2002         fmovel  #0,%FPSR                |clea    
2003         leal    ETEMP(%a6),%a0  |a0 will poin    
2004         clrw    2(%a0)          |clear lower     
2005         bra     p_write         |go write the    
2006 p_moven:                                         
2007         leal    ETEMP(%a6),%a0  |a0 will poin    
2008         clrw    2(%a0)          |clear lower     
2009         bra     p_write         |go write the    
2010                                                  
2011 |                                                
2012 | Routines to read the dynamic k-factor from     
2013 |                                                
2014 p_dyd0:                                          
2015         movel   USER_D0(%a6),%d0                 
2016         bras    statick                          
2017 p_dyd1:                                          
2018         movel   USER_D1(%a6),%d0                 
2019         bras    statick                          
2020 p_dyd2:                                          
2021         movel   %d2,%d0                          
2022         bras    statick                          
2023 p_dyd3:                                          
2024         movel   %d3,%d0                          
2025         bras    statick                          
2026 p_dyd4:                                          
2027         movel   %d4,%d0                          
2028         bras    statick                          
2029 p_dyd5:                                          
2030         movel   %d5,%d0                          
2031         bras    statick                          
2032 p_dyd6:                                          
2033         movel   %d6,%d0                          
2034         bra     statick                          
2035 p_dyd7:                                          
2036         movel   %d7,%d0                          
2037         bra     statick                          
2038                                                  
2039         |end                                     
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php