~ [ 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 sparc64) and /arch/m68k/fpsp040/res_func.S (Architecture m68k)


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