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

TOMOYO Linux Cross Reference
Linux/arch/m68k/fpsp040/scale.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 ] ~

  1 |
  2 |       scale.sa 3.3 7/30/91
  3 |
  4 |       The entry point sSCALE computes the destination operand
  5 |       scaled by the source operand.  If the absolute value of
  6 |       the source operand is (>= 2^14) an overflow or underflow
  7 |       is returned.
  8 |
  9 |       The entry point sscale is called from do_func to emulate
 10 |       the fscale unimplemented instruction.
 11 |
 12 |       Input: Double-extended destination operand in FPTEMP,
 13 |               double-extended source operand in ETEMP.
 14 |
 15 |       Output: The function returns scale(X,Y) to fp0.
 16 |
 17 |       Modifies: fp0.
 18 |
 19 |       Algorithm:
 20 |
 21 |               Copyright (C) Motorola, Inc. 1990
 22 |                       All Rights Reserved
 23 |
 24 |       For details on the license for this file, please see the
 25 |       file, README, in this same directory.
 26 
 27 |SCALE    idnt    2,1 | Motorola 040 Floating Point Software Package
 28 
 29         |section        8
 30 
 31 #include "fpsp.h"
 32 
 33         |xref   t_ovfl2
 34         |xref   t_unfl
 35         |xref   round
 36         |xref   t_resdnrm
 37 
 38 SRC_BNDS: .short        0x3fff,0x400c
 39 
 40 |
 41 | This entry point is used by the unimplemented instruction exception
 42 | handler.
 43 |
 44 |
 45 |
 46 |       FSCALE
 47 |
 48         .global sscale
 49 sscale:
 50         fmovel          #0,%fpcr                |clr user enabled exc
 51         clrl            %d1
 52         movew           FPTEMP(%a6),%d1 |get dest exponent
 53         smi             L_SCR1(%a6)     |use L_SCR1 to hold sign
 54         andil           #0x7fff,%d1     |strip sign
 55         movew           ETEMP(%a6),%d0  |check src bounds
 56         andiw           #0x7fff,%d0     |clr sign bit
 57         cmp2w           SRC_BNDS,%d0
 58         bccs            src_in
 59         cmpiw           #0x400c,%d0     |test for too large
 60         bge             src_out
 61 |
 62 | The source input is below 1, so we check for denormalized numbers
 63 | and set unfl.
 64 |
 65 src_small:
 66         moveb           DTAG(%a6),%d0
 67         andib           #0xe0,%d0
 68         tstb            %d0
 69         beqs            no_denorm
 70         st              STORE_FLG(%a6)  |dest already contains result
 71         orl             #unfl_mask,USER_FPSR(%a6) |set UNFL
 72 den_done:
 73         leal            FPTEMP(%a6),%a0
 74         bra             t_resdnrm
 75 no_denorm:
 76         fmovel          USER_FPCR(%a6),%FPCR
 77         fmovex          FPTEMP(%a6),%fp0        |simply return dest
 78         rts
 79 
 80 
 81 |
 82 | Source is within 2^14 range.  To perform the int operation,
 83 | move it to d0.
 84 |
 85 src_in:
 86         fmovex          ETEMP(%a6),%fp0 |move in src for int
 87         fmovel          #rz_mode,%fpcr  |force rz for src conversion
 88         fmovel          %fp0,%d0                |int src to d0
 89         fmovel          #0,%FPSR                |clr status from above
 90         tstw            ETEMP(%a6)      |check src sign
 91         blt             src_neg
 92 |
 93 | Source is positive.  Add the src to the dest exponent.
 94 | The result can be denormalized, if src = 0, or overflow,
 95 | if the result of the add sets a bit in the upper word.
 96 |
 97 src_pos:
 98         tstw            %d1             |check for denorm
 99         beq             dst_dnrm
100         addl            %d0,%d1         |add src to dest exp
101         beqs            denorm          |if zero, result is denorm
102         cmpil           #0x7fff,%d1     |test for overflow
103         bges            ovfl
104         tstb            L_SCR1(%a6)
105         beqs            spos_pos
106         orw             #0x8000,%d1
107 spos_pos:
108         movew           %d1,FPTEMP(%a6) |result in FPTEMP
109         fmovel          USER_FPCR(%a6),%FPCR
110         fmovex          FPTEMP(%a6),%fp0        |write result to fp0
111         rts
112 ovfl:
113         tstb            L_SCR1(%a6)
114         beqs            sovl_pos
115         orw             #0x8000,%d1
116 sovl_pos:
117         movew           FPTEMP(%a6),ETEMP(%a6)  |result in ETEMP
118         movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
119         movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
120         bra             t_ovfl2
121 
122 denorm:
123         tstb            L_SCR1(%a6)
124         beqs            den_pos
125         orw             #0x8000,%d1
126 den_pos:
127         tstl            FPTEMP_HI(%a6)  |check j bit
128         blts            nden_exit       |if set, not denorm
129         movew           %d1,ETEMP(%a6)  |input expected in ETEMP
130         movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
131         movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
132         orl             #unfl_bit,USER_FPSR(%a6)        |set unfl
133         leal            ETEMP(%a6),%a0
134         bra             t_resdnrm
135 nden_exit:
136         movew           %d1,FPTEMP(%a6) |result in FPTEMP
137         fmovel          USER_FPCR(%a6),%FPCR
138         fmovex          FPTEMP(%a6),%fp0        |write result to fp0
139         rts
140 
141 |
142 | Source is negative.  Add the src to the dest exponent.
143 | (The result exponent will be reduced).  The result can be
144 | denormalized.
145 |
146 src_neg:
147         addl            %d0,%d1         |add src to dest
148         beqs            denorm          |if zero, result is denorm
149         blts            fix_dnrm        |if negative, result is
150 |                                       ;needing denormalization
151         tstb            L_SCR1(%a6)
152         beqs            sneg_pos
153         orw             #0x8000,%d1
154 sneg_pos:
155         movew           %d1,FPTEMP(%a6) |result in FPTEMP
156         fmovel          USER_FPCR(%a6),%FPCR
157         fmovex          FPTEMP(%a6),%fp0        |write result to fp0
158         rts
159 
160 
161 |
162 | The result exponent is below denorm value.  Test for catastrophic
163 | underflow and force zero if true.  If not, try to shift the
164 | mantissa right until a zero exponent exists.
165 |
166 fix_dnrm:
167         cmpiw           #0xffc0,%d1     |lower bound for normalization
168         blt             fix_unfl        |if lower, catastrophic unfl
169         movew           %d1,%d0         |use d0 for exp
170         movel           %d2,-(%a7)      |free d2 for norm
171         movel           FPTEMP_HI(%a6),%d1
172         movel           FPTEMP_LO(%a6),%d2
173         clrl            L_SCR2(%a6)
174 fix_loop:
175         addw            #1,%d0          |drive d0 to 0
176         lsrl            #1,%d1          |while shifting the
177         roxrl           #1,%d2          |mantissa to the right
178         bccs            no_carry
179         st              L_SCR2(%a6)     |use L_SCR2 to capture inex
180 no_carry:
181         tstw            %d0             |it is finished when
182         blts            fix_loop        |d0 is zero or the mantissa
183         tstb            L_SCR2(%a6)
184         beqs            tst_zero
185         orl             #unfl_inx_mask,USER_FPSR(%a6)
186 |                                       ;set unfl, aunfl, ainex
187 |
188 | Test for zero. If zero, simply use fmove to return +/- zero
189 | to the fpu.
190 |
191 tst_zero:
192         clrw            FPTEMP_EX(%a6)
193         tstb            L_SCR1(%a6)     |test for sign
194         beqs            tst_con
195         orw             #0x8000,FPTEMP_EX(%a6) |set sign bit
196 tst_con:
197         movel           %d1,FPTEMP_HI(%a6)
198         movel           %d2,FPTEMP_LO(%a6)
199         movel           (%a7)+,%d2
200         tstl            %d1
201         bnes            not_zero
202         tstl            FPTEMP_LO(%a6)
203         bnes            not_zero
204 |
205 | Result is zero.  Check for rounding mode to set lsb.  If the
206 | mode is rp, and the zero is positive, return smallest denorm.
207 | If the mode is rm, and the zero is negative, return smallest
208 | negative denorm.
209 |
210         btstb           #5,FPCR_MODE(%a6) |test if rm or rp
211         beqs            no_dir
212         btstb           #4,FPCR_MODE(%a6) |check which one
213         beqs            zer_rm
214 zer_rp:
215         tstb            L_SCR1(%a6)     |check sign
216         bnes            no_dir          |if set, neg op, no inc
217         movel           #1,FPTEMP_LO(%a6) |set lsb
218         bras            sm_dnrm
219 zer_rm:
220         tstb            L_SCR1(%a6)     |check sign
221         beqs            no_dir          |if clr, neg op, no inc
222         movel           #1,FPTEMP_LO(%a6) |set lsb
223         orl             #neg_mask,USER_FPSR(%a6) |set N
224         bras            sm_dnrm
225 no_dir:
226         fmovel          USER_FPCR(%a6),%FPCR
227         fmovex          FPTEMP(%a6),%fp0        |use fmove to set cc's
228         rts
229 
230 |
231 | The rounding mode changed the zero to a smallest denorm. Call
232 | t_resdnrm with exceptional operand in ETEMP.
233 |
234 sm_dnrm:
235         movel           FPTEMP_EX(%a6),ETEMP_EX(%a6)
236         movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
237         movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
238         leal            ETEMP(%a6),%a0
239         bra             t_resdnrm
240 
241 |
242 | Result is still denormalized.
243 |
244 not_zero:
245         orl             #unfl_mask,USER_FPSR(%a6) |set unfl
246         tstb            L_SCR1(%a6)     |check for sign
247         beqs            fix_exit
248         orl             #neg_mask,USER_FPSR(%a6) |set N
249 fix_exit:
250         bras            sm_dnrm
251 
252 
253 |
254 | The result has underflowed to zero. Return zero and set
255 | unfl, aunfl, and ainex.
256 |
257 fix_unfl:
258         orl             #unfl_inx_mask,USER_FPSR(%a6)
259         btstb           #5,FPCR_MODE(%a6) |test if rm or rp
260         beqs            no_dir2
261         btstb           #4,FPCR_MODE(%a6) |check which one
262         beqs            zer_rm2
263 zer_rp2:
264         tstb            L_SCR1(%a6)     |check sign
265         bnes            no_dir2         |if set, neg op, no inc
266         clrl            FPTEMP_EX(%a6)
267         clrl            FPTEMP_HI(%a6)
268         movel           #1,FPTEMP_LO(%a6) |set lsb
269         bras            sm_dnrm         |return smallest denorm
270 zer_rm2:
271         tstb            L_SCR1(%a6)     |check sign
272         beqs            no_dir2         |if clr, neg op, no inc
273         movew           #0x8000,FPTEMP_EX(%a6)
274         clrl            FPTEMP_HI(%a6)
275         movel           #1,FPTEMP_LO(%a6) |set lsb
276         orl             #neg_mask,USER_FPSR(%a6) |set N
277         bra             sm_dnrm         |return smallest denorm
278 
279 no_dir2:
280         tstb            L_SCR1(%a6)
281         bges            pos_zero
282 neg_zero:
283         clrl            FP_SCR1(%a6)    |clear the exceptional operand
284         clrl            FP_SCR1+4(%a6)  |for gen_except.
285         clrl            FP_SCR1+8(%a6)
286         fmoves          #0x80000000,%fp0
287         rts
288 pos_zero:
289         clrl            FP_SCR1(%a6)    |clear the exceptional operand
290         clrl            FP_SCR1+4(%a6)  |for gen_except.
291         clrl            FP_SCR1+8(%a6)
292         fmoves          #0x00000000,%fp0
293         rts
294 
295 |
296 | The destination is a denormalized number.  It must be handled
297 | by first shifting the bits in the mantissa until it is normalized,
298 | then adding the remainder of the source to the exponent.
299 |
300 dst_dnrm:
301         moveml          %d2/%d3,-(%a7)
302         movew           FPTEMP_EX(%a6),%d1
303         movel           FPTEMP_HI(%a6),%d2
304         movel           FPTEMP_LO(%a6),%d3
305 dst_loop:
306         tstl            %d2             |test for normalized result
307         blts            dst_norm        |exit loop if so
308         tstl            %d0             |otherwise, test shift count
309         beqs            dst_fin         |if zero, shifting is done
310         subil           #1,%d0          |dec src
311         lsll            #1,%d3
312         roxll           #1,%d2
313         bras            dst_loop
314 |
315 | Destination became normalized.  Simply add the remaining
316 | portion of the src to the exponent.
317 |
318 dst_norm:
319         addw            %d0,%d1         |dst is normalized; add src
320         tstb            L_SCR1(%a6)
321         beqs            dnrm_pos
322         orl             #0x8000,%d1
323 dnrm_pos:
324         movemw          %d1,FPTEMP_EX(%a6)
325         moveml          %d2,FPTEMP_HI(%a6)
326         moveml          %d3,FPTEMP_LO(%a6)
327         fmovel          USER_FPCR(%a6),%FPCR
328         fmovex          FPTEMP(%a6),%fp0
329         moveml          (%a7)+,%d2/%d3
330         rts
331 
332 |
333 | Destination remained denormalized.  Call t_excdnrm with
334 | exceptional operand in ETEMP.
335 |
336 dst_fin:
337         tstb            L_SCR1(%a6)     |check for sign
338         beqs            dst_exit
339         orl             #neg_mask,USER_FPSR(%a6) |set N
340         orl             #0x8000,%d1
341 dst_exit:
342         movemw          %d1,ETEMP_EX(%a6)
343         moveml          %d2,ETEMP_HI(%a6)
344         moveml          %d3,ETEMP_LO(%a6)
345         orl             #unfl_mask,USER_FPSR(%a6) |set unfl
346         moveml          (%a7)+,%d2/%d3
347         leal            ETEMP(%a6),%a0
348         bra             t_resdnrm
349 
350 |
351 | Source is outside of 2^14 range.  Test the sign and branch
352 | to the appropriate exception handler.
353 |
354 src_out:
355         tstb            L_SCR1(%a6)
356         beqs            scro_pos
357         orl             #0x8000,%d1
358 scro_pos:
359         movel           FPTEMP_HI(%a6),ETEMP_HI(%a6)
360         movel           FPTEMP_LO(%a6),ETEMP_LO(%a6)
361         tstw            ETEMP(%a6)
362         blts            res_neg
363 res_pos:
364         movew           %d1,ETEMP(%a6)  |result in ETEMP
365         bra             t_ovfl2
366 res_neg:
367         movew           %d1,ETEMP(%a6)  |result in ETEMP
368         leal            ETEMP(%a6),%a0
369         bra             t_unfl
370         |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