Merge from mainline
[official-gcc.git] / gcc / config / xtensa / ieee754-sf.S
blobf669cc8ec2f48a8d8cf7a0b87b398c46a8addf60
1 /* IEEE-754 single-precision functions for Xtensa
2    Copyright (C) 2006 Free Software Foundation, Inc.
3    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5    This file is part of GCC.
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
12    In addition to the permissions in the GNU General Public License,
13    the Free Software Foundation gives you unlimited permission to link
14    the compiled version of this file into combinations with other
15    programs, and to distribute those combinations without any
16    restriction coming from the use of this file.  (The General Public
17    License restrictions do apply in other respects; for example, they
18    cover modification of the file, and distribution when not linked
19    into a combine executable.)
21    GCC is distributed in the hope that it will be useful, but WITHOUT
22    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
24    License for more details.
26    You should have received a copy of the GNU General Public License
27    along with GCC; see the file COPYING.  If not, write to the Free
28    Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29    02110-1301, USA.  */
31 #ifdef __XTENSA_EB__
32 #define xh a2
33 #define xl a3
34 #define yh a4
35 #define yl a5
36 #else
37 #define xh a3
38 #define xl a2
39 #define yh a5
40 #define yl a4
41 #endif
43 /*  Warning!  The branch displacements for some Xtensa branch instructions
44     are quite small, and this code has been carefully laid out to keep
45     branch targets in range.  If you change anything, be sure to check that
46     the assembler is not relaxing anything to branch over a jump.  */
48 #ifdef L_negsf2
50         .align  4
51         .global __negsf2
52         .type   __negsf2, @function
53 __negsf2:
54         abi_entry sp, 32
55         movi    a4, 0x80000000
56         xor     a2, a2, a4
57         abi_return
59 #endif /* L_negsf2 */
61 #ifdef L_addsubsf3
63         /* Addition */
64 __addsf3_aux:
66         /* Handle NaNs and Infinities.  (This code is placed before the
67            start of the function just to keep it in range of the limited
68            branch displacements.)  */
70 .Ladd_xnan_or_inf:
71         /* If y is neither Infinity nor NaN, return x.  */
72         bnall   a3, a6, 1f
73         /* If x is a NaN, return it.  Otherwise, return y.  */
74         slli    a7, a2, 9
75         beqz    a7, .Ladd_ynan_or_inf
76 1:      abi_return
78 .Ladd_ynan_or_inf:
79         /* Return y.  */
80         mov     a2, a3
81         abi_return
83 .Ladd_opposite_signs:
84         /* Operand signs differ.  Do a subtraction.  */
85         slli    a7, a6, 8
86         xor     a3, a3, a7
87         j       .Lsub_same_sign
89         .align  4
90         .global __addsf3
91         .type   __addsf3, @function
92 __addsf3:
93         abi_entry sp, 32
94         movi    a6, 0x7f800000
96         /* Check if the two operands have the same sign.  */
97         xor     a7, a2, a3
98         bltz    a7, .Ladd_opposite_signs
100 .Ladd_same_sign:        
101         /* Check if either exponent == 0x7f8 (i.e., NaN or Infinity).  */
102         ball    a2, a6, .Ladd_xnan_or_inf
103         ball    a3, a6, .Ladd_ynan_or_inf
105         /* Compare the exponents.  The smaller operand will be shifted
106            right by the exponent difference and added to the larger
107            one.  */
108         extui   a7, a2, 23, 9
109         extui   a8, a3, 23, 9
110         bltu    a7, a8, .Ladd_shiftx
112 .Ladd_shifty:
113         /* Check if the smaller (or equal) exponent is zero.  */
114         bnone   a3, a6, .Ladd_yexpzero
116         /* Replace y sign/exponent with 0x008.  */
117         or      a3, a3, a6
118         slli    a3, a3, 8
119         srli    a3, a3, 8
121 .Ladd_yexpdiff:
122         /* Compute the exponent difference.  */
123         sub     a10, a7, a8
125         /* Exponent difference > 32 -- just return the bigger value.  */
126         bgeui   a10, 32, 1f
127         
128         /* Shift y right by the exponent difference.  Any bits that are
129            shifted out of y are saved in a9 for rounding the result.  */
130         ssr     a10
131         movi    a9, 0
132         src     a9, a3, a9
133         srl     a3, a3
135         /* Do the addition.  */
136         add     a2, a2, a3
138         /* Check if the add overflowed into the exponent.  */
139         extui   a10, a2, 23, 9
140         beq     a10, a7, .Ladd_round
141         mov     a8, a7
142         j       .Ladd_carry
144 .Ladd_yexpzero:
145         /* y is a subnormal value.  Replace its sign/exponent with zero,
146            i.e., no implicit "1.0", and increment the apparent exponent
147            because subnormals behave as if they had the minimum (nonzero)
148            exponent.  Test for the case when both exponents are zero.  */
149         slli    a3, a3, 9
150         srli    a3, a3, 9
151         bnone   a2, a6, .Ladd_bothexpzero
152         addi    a8, a8, 1
153         j       .Ladd_yexpdiff
155 .Ladd_bothexpzero:
156         /* Both exponents are zero.  Handle this as a special case.  There
157            is no need to shift or round, and the normal code for handling
158            a carry into the exponent field will not work because it
159            assumes there is an implicit "1.0" that needs to be added.  */
160         add     a2, a2, a3
161 1:      abi_return
163 .Ladd_xexpzero:
164         /* Same as "yexpzero" except skip handling the case when both
165            exponents are zero.  */
166         slli    a2, a2, 9
167         srli    a2, a2, 9
168         addi    a7, a7, 1
169         j       .Ladd_xexpdiff
171 .Ladd_shiftx:
172         /* Same thing as the "shifty" code, but with x and y swapped.  Also,
173            because the exponent difference is always nonzero in this version,
174            the shift sequence can use SLL and skip loading a constant zero.  */
175         bnone   a2, a6, .Ladd_xexpzero
177         or      a2, a2, a6
178         slli    a2, a2, 8
179         srli    a2, a2, 8
181 .Ladd_xexpdiff:
182         sub     a10, a8, a7
183         bgeui   a10, 32, .Ladd_returny
184         
185         ssr     a10
186         sll     a9, a2
187         srl     a2, a2
189         add     a2, a2, a3
191         /* Check if the add overflowed into the exponent.  */
192         extui   a10, a2, 23, 9
193         bne     a10, a8, .Ladd_carry
195 .Ladd_round:
196         /* Round up if the leftover fraction is >= 1/2.  */
197         bgez    a9, 1f
198         addi    a2, a2, 1
200         /* Check if the leftover fraction is exactly 1/2.  */
201         slli    a9, a9, 1
202         beqz    a9, .Ladd_exactlyhalf
203 1:      abi_return
205 .Ladd_returny:
206         mov     a2, a3
207         abi_return
209 .Ladd_carry:    
210         /* The addition has overflowed into the exponent field, so the
211            value needs to be renormalized.  The mantissa of the result
212            can be recovered by subtracting the original exponent and
213            adding 0x800000 (which is the explicit "1.0" for the
214            mantissa of the non-shifted operand -- the "1.0" for the
215            shifted operand was already added).  The mantissa can then
216            be shifted right by one bit.  The explicit "1.0" of the
217            shifted mantissa then needs to be replaced by the exponent,
218            incremented by one to account for the normalizing shift.
219            It is faster to combine these operations: do the shift first
220            and combine the additions and subtractions.  If x is the
221            original exponent, the result is:
222                shifted mantissa - (x << 22) + (1 << 22) + (x << 23)
223            or:
224                shifted mantissa + ((x + 1) << 22)
225            Note that the exponent is incremented here by leaving the
226            explicit "1.0" of the mantissa in the exponent field.  */
228         /* Shift x right by one bit.  Save the lsb.  */
229         mov     a10, a2
230         srli    a2, a2, 1
232         /* See explanation above.  The original exponent is in a8.  */
233         addi    a8, a8, 1
234         slli    a8, a8, 22
235         add     a2, a2, a8
237         /* Return an Infinity if the exponent overflowed.  */
238         ball    a2, a6, .Ladd_infinity
239         
240         /* Same thing as the "round" code except the msb of the leftover
241            fraction is bit 0 of a10, with the rest of the fraction in a9.  */
242         bbci.l  a10, 0, 1f
243         addi    a2, a2, 1
244         beqz    a9, .Ladd_exactlyhalf
245 1:      abi_return
247 .Ladd_infinity:
248         /* Clear the mantissa.  */
249         srli    a2, a2, 23
250         slli    a2, a2, 23
252         /* The sign bit may have been lost in a carry-out.  Put it back.  */
253         slli    a8, a8, 1
254         or      a2, a2, a8
255         abi_return
257 .Ladd_exactlyhalf:
258         /* Round down to the nearest even value.  */
259         srli    a2, a2, 1
260         slli    a2, a2, 1
261         abi_return
264         /* Subtraction */
265 __subsf3_aux:
266         
267         /* Handle NaNs and Infinities.  (This code is placed before the
268            start of the function just to keep it in range of the limited
269            branch displacements.)  */
271 .Lsub_xnan_or_inf:
272         /* If y is neither Infinity nor NaN, return x.  */
273         bnall   a3, a6, 1f
274         /* Both x and y are either NaN or Inf, so the result is NaN.  */
275         movi    a4, 0x400000    /* make it a quiet NaN */
276         or      a2, a2, a4
277 1:      abi_return
279 .Lsub_ynan_or_inf:
280         /* Negate y and return it.  */
281         slli    a7, a6, 8
282         xor     a2, a3, a7
283         abi_return
285 .Lsub_opposite_signs:
286         /* Operand signs differ.  Do an addition.  */
287         slli    a7, a6, 8
288         xor     a3, a3, a7
289         j       .Ladd_same_sign
291         .align  4
292         .global __subsf3
293         .type   __subsf3, @function
294 __subsf3:
295         abi_entry sp, 32
296         movi    a6, 0x7f800000
298         /* Check if the two operands have the same sign.  */
299         xor     a7, a2, a3
300         bltz    a7, .Lsub_opposite_signs
302 .Lsub_same_sign:        
303         /* Check if either exponent == 0x7f8 (i.e., NaN or Infinity).  */
304         ball    a2, a6, .Lsub_xnan_or_inf
305         ball    a3, a6, .Lsub_ynan_or_inf
307         /* Compare the operands.  In contrast to addition, the entire
308            value matters here.  */
309         extui   a7, a2, 23, 8
310         extui   a8, a3, 23, 8
311         bltu    a2, a3, .Lsub_xsmaller
313 .Lsub_ysmaller:
314         /* Check if the smaller (or equal) exponent is zero.  */
315         bnone   a3, a6, .Lsub_yexpzero
317         /* Replace y sign/exponent with 0x008.  */
318         or      a3, a3, a6
319         slli    a3, a3, 8
320         srli    a3, a3, 8
322 .Lsub_yexpdiff:
323         /* Compute the exponent difference.  */
324         sub     a10, a7, a8
326         /* Exponent difference > 32 -- just return the bigger value.  */
327         bgeui   a10, 32, 1f
328         
329         /* Shift y right by the exponent difference.  Any bits that are
330            shifted out of y are saved in a9 for rounding the result.  */
331         ssr     a10
332         movi    a9, 0
333         src     a9, a3, a9
334         srl     a3, a3
336         sub     a2, a2, a3
338         /* Subtract the leftover bits in a9 from zero and propagate any
339            borrow from a2.  */
340         neg     a9, a9
341         addi    a10, a2, -1
342         movnez  a2, a10, a9
344         /* Check if the subtract underflowed into the exponent.  */
345         extui   a10, a2, 23, 8
346         beq     a10, a7, .Lsub_round
347         j       .Lsub_borrow
349 .Lsub_yexpzero:
350         /* Return zero if the inputs are equal.  (For the non-subnormal
351            case, subtracting the "1.0" will cause a borrow from the exponent
352            and this case can be detected when handling the borrow.)  */
353         beq     a2, a3, .Lsub_return_zero
355         /* y is a subnormal value.  Replace its sign/exponent with zero,
356            i.e., no implicit "1.0".  Unless x is also a subnormal, increment
357            y's apparent exponent because subnormals behave as if they had
358            the minimum (nonzero) exponent.  */
359         slli    a3, a3, 9
360         srli    a3, a3, 9
361         bnone   a2, a6, .Lsub_yexpdiff
362         addi    a8, a8, 1
363         j       .Lsub_yexpdiff
365 .Lsub_returny:
366         /* Negate and return y.  */
367         slli    a7, a6, 8
368         xor     a2, a3, a7
369 1:      abi_return
371 .Lsub_xsmaller:
372         /* Same thing as the "ysmaller" code, but with x and y swapped and
373            with y negated.  */
374         bnone   a2, a6, .Lsub_xexpzero
376         or      a2, a2, a6
377         slli    a2, a2, 8
378         srli    a2, a2, 8
380 .Lsub_xexpdiff:
381         sub     a10, a8, a7
382         bgeui   a10, 32, .Lsub_returny
383         
384         ssr     a10
385         movi    a9, 0
386         src     a9, a2, a9
387         srl     a2, a2
389         /* Negate y.  */
390         slli    a11, a6, 8
391         xor     a3, a3, a11
393         sub     a2, a3, a2
395         neg     a9, a9
396         addi    a10, a2, -1
397         movnez  a2, a10, a9
399         /* Check if the subtract underflowed into the exponent.  */
400         extui   a10, a2, 23, 8
401         bne     a10, a8, .Lsub_borrow
403 .Lsub_round:
404         /* Round up if the leftover fraction is >= 1/2.  */
405         bgez    a9, 1f
406         addi    a2, a2, 1
408         /* Check if the leftover fraction is exactly 1/2.  */
409         slli    a9, a9, 1
410         beqz    a9, .Lsub_exactlyhalf
411 1:      abi_return
413 .Lsub_xexpzero:
414         /* Same as "yexpzero".  */
415         beq     a2, a3, .Lsub_return_zero
416         slli    a2, a2, 9
417         srli    a2, a2, 9
418         bnone   a3, a6, .Lsub_xexpdiff
419         addi    a7, a7, 1
420         j       .Lsub_xexpdiff
422 .Lsub_return_zero:
423         movi    a2, 0
424         abi_return
426 .Lsub_borrow:   
427         /* The subtraction has underflowed into the exponent field, so the
428            value needs to be renormalized.  Shift the mantissa left as
429            needed to remove any leading zeros and adjust the exponent
430            accordingly.  If the exponent is not large enough to remove
431            all the leading zeros, the result will be a subnormal value.  */
433         slli    a8, a2, 9
434         beqz    a8, .Lsub_xzero
435         do_nsau a6, a8, a7, a11
436         srli    a8, a8, 9
437         bge     a6, a10, .Lsub_subnormal
438         addi    a6, a6, 1
440 .Lsub_normalize_shift:
441         /* Shift the mantissa (a8/a9) left by a6.  */
442         ssl     a6
443         src     a8, a8, a9
444         sll     a9, a9
446         /* Combine the shifted mantissa with the sign and exponent,
447            decrementing the exponent by a6.  (The exponent has already
448            been decremented by one due to the borrow from the subtraction,
449            but adding the mantissa will increment the exponent by one.)  */
450         srli    a2, a2, 23
451         sub     a2, a2, a6
452         slli    a2, a2, 23
453         add     a2, a2, a8
454         j       .Lsub_round
456 .Lsub_exactlyhalf:
457         /* Round down to the nearest even value.  */
458         srli    a2, a2, 1
459         slli    a2, a2, 1
460         abi_return
462 .Lsub_xzero:
463         /* If there was a borrow from the exponent, and the mantissa and
464            guard digits are all zero, then the inputs were equal and the
465            result should be zero.  */
466         beqz    a9, .Lsub_return_zero
468         /* Only the guard digit is nonzero.  Shift by min(24, a10).  */
469         addi    a11, a10, -24
470         movi    a6, 24
471         movltz  a6, a10, a11
472         j       .Lsub_normalize_shift
474 .Lsub_subnormal:
475         /* The exponent is too small to shift away all the leading zeros.
476            Set a6 to the current exponent (which has already been
477            decremented by the borrow) so that the exponent of the result
478            will be zero.  Do not add 1 to a6 in this case, because: (1)
479            adding the mantissa will not increment the exponent, so there is
480            no need to subtract anything extra from the exponent to
481            compensate, and (2) the effective exponent of a subnormal is 1
482            not 0 so the shift amount must be 1 smaller than normal. */
483         mov     a6, a10
484         j       .Lsub_normalize_shift
486 #endif /* L_addsubsf3 */
488 #ifdef L_mulsf3
490         /* Multiplication */
491 __mulsf3_aux:
493         /* Handle unusual cases (zeros, subnormals, NaNs and Infinities).
494            (This code is placed before the start of the function just to
495            keep it in range of the limited branch displacements.)  */
497 .Lmul_xexpzero:
498         /* Clear the sign bit of x.  */
499         slli    a2, a2, 1
500         srli    a2, a2, 1
502         /* If x is zero, return zero.  */
503         beqz    a2, .Lmul_return_zero
505         /* Normalize x.  Adjust the exponent in a8.  */
506         do_nsau a10, a2, a11, a12
507         addi    a10, a10, -8
508         ssl     a10
509         sll     a2, a2 
510         movi    a8, 1
511         sub     a8, a8, a10
512         j       .Lmul_xnormalized       
513         
514 .Lmul_yexpzero:
515         /* Clear the sign bit of y.  */
516         slli    a3, a3, 1
517         srli    a3, a3, 1
519         /* If y is zero, return zero.  */
520         beqz    a3, .Lmul_return_zero
522         /* Normalize y.  Adjust the exponent in a9.  */
523         do_nsau a10, a3, a11, a12
524         addi    a10, a10, -8
525         ssl     a10
526         sll     a3, a3
527         movi    a9, 1
528         sub     a9, a9, a10
529         j       .Lmul_ynormalized       
531 .Lmul_return_zero:
532         /* Return zero with the appropriate sign bit.  */
533         srli    a2, a7, 31
534         slli    a2, a2, 31
535         j       .Lmul_done
537 .Lmul_xnan_or_inf:
538         /* If y is zero, return NaN.  */
539         slli    a8, a3, 1
540         bnez    a8, 1f
541         movi    a4, 0x400000    /* make it a quiet NaN */
542         or      a2, a2, a4
543         j       .Lmul_done
545         /* If y is NaN, return y.  */
546         bnall   a3, a6, .Lmul_returnx
547         slli    a8, a3, 9
548         beqz    a8, .Lmul_returnx
550 .Lmul_returny:
551         mov     a2, a3
553 .Lmul_returnx:
554         /* Set the sign bit and return.  */
555         extui   a7, a7, 31, 1
556         slli    a2, a2, 1
557         ssai    1
558         src     a2, a7, a2
559         j       .Lmul_done
561 .Lmul_ynan_or_inf:
562         /* If x is zero, return NaN.  */
563         slli    a8, a2, 1
564         bnez    a8, .Lmul_returny
565         movi    a7, 0x400000    /* make it a quiet NaN */
566         or      a2, a3, a7
567         j       .Lmul_done
569         .align  4
570         .global __mulsf3
571         .type   __mulsf3, @function
572 __mulsf3:
573         abi_entry sp, 48
574 #if __XTENSA_CALL0_ABI__
575         addi    sp, sp, -32
576         s32i    a12, sp, 16
577         s32i    a13, sp, 20
578         s32i    a14, sp, 24
579         s32i    a15, sp, 28
580 #endif
581         movi    a6, 0x7f800000
583         /* Get the sign of the result.  */
584         xor     a7, a2, a3
586         /* Check for NaN and infinity.  */
587         ball    a2, a6, .Lmul_xnan_or_inf
588         ball    a3, a6, .Lmul_ynan_or_inf
590         /* Extract the exponents.  */
591         extui   a8, a2, 23, 8
592         extui   a9, a3, 23, 8
594         beqz    a8, .Lmul_xexpzero
595 .Lmul_xnormalized:      
596         beqz    a9, .Lmul_yexpzero
597 .Lmul_ynormalized:      
599         /* Add the exponents.  */
600         add     a8, a8, a9
602         /* Replace sign/exponent fields with explicit "1.0".  */
603         movi    a10, 0xffffff
604         or      a2, a2, a6
605         and     a2, a2, a10
606         or      a3, a3, a6
607         and     a3, a3, a10
609         /* Multiply 32x32 to 64 bits.  The result ends up in a2/a6.  */
611 #if XCHAL_HAVE_MUL32_HIGH
613         mull    a6, a2, a3
614         muluh   a2, a2, a3
616 #else
618         /* Break the inputs into 16-bit chunks and compute 4 32-bit partial
619            products.  These partial products are:
621                 0 xl * yl
623                 1 xl * yh
624                 2 xh * yl
626                 3 xh * yh
628            If using the Mul16 or Mul32 multiplier options, these input
629            chunks must be stored in separate registers.  For Mac16, the
630            UMUL.AA.* opcodes can specify that the inputs come from either
631            half of the registers, so there is no need to shift them out
632            ahead of time.  If there is no multiply hardware, the 16-bit
633            chunks can be extracted when setting up the arguments to the
634            separate multiply function.  */
636 #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
637         /* Calling a separate multiply function will clobber a0 and requires
638            use of a8 as a temporary, so save those values now.  (The function
639            uses a custom ABI so nothing else needs to be saved.)  */
640         s32i    a0, sp, 0
641         s32i    a8, sp, 4
642 #endif
644 #if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32
646 #define a2h a4
647 #define a3h a5
649         /* Get the high halves of the inputs into registers.  */
650         srli    a2h, a2, 16
651         srli    a3h, a3, 16
653 #define a2l a2
654 #define a3l a3
656 #if XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MUL16
657         /* Clear the high halves of the inputs.  This does not matter
658            for MUL16 because the high bits are ignored.  */
659         extui   a2, a2, 0, 16
660         extui   a3, a3, 0, 16
661 #endif
662 #endif /* MUL16 || MUL32 */
665 #if XCHAL_HAVE_MUL16
667 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
668         mul16u  dst, xreg ## xhalf, yreg ## yhalf
670 #elif XCHAL_HAVE_MUL32
672 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
673         mull    dst, xreg ## xhalf, yreg ## yhalf
675 #elif XCHAL_HAVE_MAC16
677 /* The preprocessor insists on inserting a space when concatenating after
678    a period in the definition of do_mul below.  These macros are a workaround
679    using underscores instead of periods when doing the concatenation.  */
680 #define umul_aa_ll umul.aa.ll
681 #define umul_aa_lh umul.aa.lh
682 #define umul_aa_hl umul.aa.hl
683 #define umul_aa_hh umul.aa.hh
685 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
686         umul_aa_ ## xhalf ## yhalf      xreg, yreg; \
687         rsr     dst, ACCLO
689 #else /* no multiply hardware */
690         
691 #define set_arg_l(dst, src) \
692         extui   dst, src, 0, 16
693 #define set_arg_h(dst, src) \
694         srli    dst, src, 16
696 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
697         set_arg_ ## xhalf (a13, xreg); \
698         set_arg_ ## yhalf (a14, yreg); \
699         call0   .Lmul_mulsi3; \
700         mov     dst, a12
701 #endif
703         /* Add pp1 and pp2 into a6 with carry-out in a9.  */
704         do_mul(a6, a2, l, a3, h)        /* pp 1 */
705         do_mul(a11, a2, h, a3, l)       /* pp 2 */
706         movi    a9, 0
707         add     a6, a6, a11
708         bgeu    a6, a11, 1f
709         addi    a9, a9, 1
711         /* Shift the high half of a9/a6 into position in a9.  Note that
712            this value can be safely incremented without any carry-outs.  */
713         ssai    16
714         src     a9, a9, a6
716         /* Compute the low word into a6.  */
717         do_mul(a11, a2, l, a3, l)       /* pp 0 */
718         sll     a6, a6
719         add     a6, a6, a11
720         bgeu    a6, a11, 1f
721         addi    a9, a9, 1
723         /* Compute the high word into a2.  */
724         do_mul(a2, a2, h, a3, h)        /* pp 3 */
725         add     a2, a2, a9
726         
727 #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
728         /* Restore values saved on the stack during the multiplication.  */
729         l32i    a0, sp, 0
730         l32i    a8, sp, 4
731 #endif
732 #endif
734         /* Shift left by 9 bits, unless there was a carry-out from the
735            multiply, in which case, shift by 8 bits and increment the
736            exponent.  */
737         movi    a4, 9
738         srli    a5, a2, 24 - 9
739         beqz    a5, 1f
740         addi    a4, a4, -1
741         addi    a8, a8, 1
742 1:      ssl     a4
743         src     a2, a2, a6
744         sll     a6, a6
746         /* Subtract the extra bias from the exponent sum (plus one to account
747            for the explicit "1.0" of the mantissa that will be added to the
748            exponent in the final result).  */
749         movi    a4, 0x80
750         sub     a8, a8, a4
751         
752         /* Check for over/underflow.  The value in a8 is one less than the
753            final exponent, so values in the range 0..fd are OK here.  */
754         movi    a4, 0xfe
755         bgeu    a8, a4, .Lmul_overflow
756         
757 .Lmul_round:
758         /* Round.  */
759         bgez    a6, .Lmul_rounded
760         addi    a2, a2, 1
761         slli    a6, a6, 1
762         beqz    a6, .Lmul_exactlyhalf
764 .Lmul_rounded:
765         /* Add the exponent to the mantissa.  */
766         slli    a8, a8, 23
767         add     a2, a2, a8
769 .Lmul_addsign:
770         /* Add the sign bit.  */
771         srli    a7, a7, 31
772         slli    a7, a7, 31
773         or      a2, a2, a7
775 .Lmul_done:
776 #if __XTENSA_CALL0_ABI__
777         l32i    a12, sp, 16
778         l32i    a13, sp, 20
779         l32i    a14, sp, 24
780         l32i    a15, sp, 28
781         addi    sp, sp, 32
782 #endif
783         abi_return
785 .Lmul_exactlyhalf:
786         /* Round down to the nearest even value.  */
787         srli    a2, a2, 1
788         slli    a2, a2, 1
789         j       .Lmul_rounded
791 .Lmul_overflow:
792         bltz    a8, .Lmul_underflow
793         /* Return +/- Infinity.  */
794         movi    a8, 0xff
795         slli    a2, a8, 23
796         j       .Lmul_addsign
798 .Lmul_underflow:
799         /* Create a subnormal value, where the exponent field contains zero,
800            but the effective exponent is 1.  The value of a8 is one less than
801            the actual exponent, so just negate it to get the shift amount.  */
802         neg     a8, a8
803         mov     a9, a6
804         ssr     a8
805         bgeui   a8, 32, .Lmul_flush_to_zero
806         
807         /* Shift a2 right.  Any bits that are shifted out of a2 are saved
808            in a6 (combined with the shifted-out bits currently in a6) for
809            rounding the result.  */
810         sll     a6, a2
811         srl     a2, a2
813         /* Set the exponent to zero.  */
814         movi    a8, 0
816         /* Pack any nonzero bits shifted out into a6.  */
817         beqz    a9, .Lmul_round
818         movi    a9, 1
819         or      a6, a6, a9
820         j       .Lmul_round
821         
822 .Lmul_flush_to_zero:
823         /* Return zero with the appropriate sign bit.  */
824         srli    a2, a7, 31
825         slli    a2, a2, 31
826         j       .Lmul_done
828 #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
829         
830         /* For Xtensa processors with no multiply hardware, this simplified
831            version of _mulsi3 is used for multiplying 16-bit chunks of
832            the floating-point mantissas.  It uses a custom ABI: the inputs
833            are passed in a13 and a14, the result is returned in a12, and
834            a8 and a15 are clobbered.  */
835         .align  4
836 .Lmul_mulsi3:
837         movi    a12, 0
838 .Lmul_mult_loop:
839         add     a15, a14, a12
840         extui   a8, a13, 0, 1
841         movnez  a12, a15, a8
843         do_addx2 a15, a14, a12, a15
844         extui   a8, a13, 1, 1
845         movnez  a12, a15, a8
847         do_addx4 a15, a14, a12, a15
848         extui   a8, a13, 2, 1
849         movnez  a12, a15, a8
851         do_addx8 a15, a14, a12, a15
852         extui   a8, a13, 3, 1
853         movnez  a12, a15, a8
855         srli    a13, a13, 4
856         slli    a14, a14, 4
857         bnez    a13, .Lmul_mult_loop
858         ret
859 #endif /* !MUL16 && !MUL32 && !MAC16 */
860 #endif /* L_mulsf3 */
862 #ifdef L_divsf3
864         /* Division */
865 __divsf3_aux:
867         /* Handle unusual cases (zeros, subnormals, NaNs and Infinities).
868            (This code is placed before the start of the function just to
869            keep it in range of the limited branch displacements.)  */
871 .Ldiv_yexpzero:
872         /* Clear the sign bit of y.  */
873         slli    a3, a3, 1
874         srli    a3, a3, 1
876         /* Check for division by zero.  */
877         beqz    a3, .Ldiv_yzero
879         /* Normalize y.  Adjust the exponent in a9.  */
880         do_nsau a10, a3, a4, a5
881         addi    a10, a10, -8
882         ssl     a10
883         sll     a3, a3
884         movi    a9, 1
885         sub     a9, a9, a10
886         j       .Ldiv_ynormalized       
888 .Ldiv_yzero:
889         /* y is zero.  Return NaN if x is also zero; otherwise, infinity.  */
890         slli    a4, a2, 1
891         srli    a4, a4, 1
892         srli    a2, a7, 31
893         slli    a2, a2, 31
894         or      a2, a2, a6
895         bnez    a4, 1f
896         movi    a4, 0x400000    /* make it a quiet NaN */
897         or      a2, a2, a4
898 1:      abi_return
900 .Ldiv_xexpzero:
901         /* Clear the sign bit of x.  */
902         slli    a2, a2, 1
903         srli    a2, a2, 1
905         /* If x is zero, return zero.  */
906         beqz    a2, .Ldiv_return_zero
908         /* Normalize x.  Adjust the exponent in a8.  */
909         do_nsau a10, a2, a4, a5
910         addi    a10, a10, -8
911         ssl     a10
912         sll     a2, a2
913         movi    a8, 1
914         sub     a8, a8, a10
915         j       .Ldiv_xnormalized       
916         
917 .Ldiv_return_zero:
918         /* Return zero with the appropriate sign bit.  */
919         srli    a2, a7, 31
920         slli    a2, a2, 31
921         abi_return
923 .Ldiv_xnan_or_inf:
924         /* Set the sign bit of the result.  */
925         srli    a7, a3, 31
926         slli    a7, a7, 31
927         xor     a2, a2, a7
928         /* If y is NaN or Inf, return NaN.  */
929         bnall   a3, a6, 1f
930         movi    a4, 0x400000    /* make it a quiet NaN */
931         or      a2, a2, a4
932 1:      abi_return
934 .Ldiv_ynan_or_inf:
935         /* If y is Infinity, return zero.  */
936         slli    a8, a3, 9
937         beqz    a8, .Ldiv_return_zero
938         /* y is NaN; return it.  */
939         mov     a2, a3
940         abi_return
942         .align  4
943         .global __divsf3
944         .type   __divsf3, @function
945 __divsf3:
946         abi_entry sp, 32
947         movi    a6, 0x7f800000
949         /* Get the sign of the result.  */
950         xor     a7, a2, a3
952         /* Check for NaN and infinity.  */
953         ball    a2, a6, .Ldiv_xnan_or_inf
954         ball    a3, a6, .Ldiv_ynan_or_inf
956         /* Extract the exponents.  */
957         extui   a8, a2, 23, 8
958         extui   a9, a3, 23, 8
960         beqz    a9, .Ldiv_yexpzero
961 .Ldiv_ynormalized:      
962         beqz    a8, .Ldiv_xexpzero
963 .Ldiv_xnormalized:      
965         /* Subtract the exponents.  */
966         sub     a8, a8, a9
968         /* Replace sign/exponent fields with explicit "1.0".  */
969         movi    a10, 0xffffff
970         or      a2, a2, a6
971         and     a2, a2, a10
972         or      a3, a3, a6
973         and     a3, a3, a10
975         /* The first digit of the mantissa division must be a one.
976            Shift x (and adjust the exponent) as needed to make this true.  */
977         bltu    a3, a2, 1f
978         slli    a2, a2, 1
979         addi    a8, a8, -1
981         /* Do the first subtraction and shift.  */
982         sub     a2, a2, a3
983         slli    a2, a2, 1
985         /* Put the quotient into a10.  */
986         movi    a10, 1
988         /* Divide one bit at a time for 23 bits.  */
989         movi    a9, 23
990 #if XCHAL_HAVE_LOOPS
991         loop    a9, .Ldiv_loopend
992 #endif
993 .Ldiv_loop:
994         /* Shift the quotient << 1.  */
995         slli    a10, a10, 1
997         /* Is this digit a 0 or 1?  */
998         bltu    a2, a3, 1f
1000         /* Output a 1 and subtract.  */
1001         addi    a10, a10, 1
1002         sub     a2, a2, a3
1004         /* Shift the dividend << 1.  */
1005 1:      slli    a2, a2, 1
1007 #if !XCHAL_HAVE_LOOPS
1008         addi    a9, a9, -1
1009         bnez    a9, .Ldiv_loop
1010 #endif
1011 .Ldiv_loopend:
1013         /* Add the exponent bias (less one to account for the explicit "1.0"
1014            of the mantissa that will be added to the exponent in the final
1015            result).  */
1016         addi    a8, a8, 0x7e
1017         
1018         /* Check for over/underflow.  The value in a8 is one less than the
1019            final exponent, so values in the range 0..fd are OK here.  */
1020         movi    a4, 0xfe
1021         bgeu    a8, a4, .Ldiv_overflow
1022         
1023 .Ldiv_round:
1024         /* Round.  The remainder (<< 1) is in a2.  */
1025         bltu    a2, a3, .Ldiv_rounded
1026         addi    a10, a10, 1
1027         beq     a2, a3, .Ldiv_exactlyhalf
1029 .Ldiv_rounded:
1030         /* Add the exponent to the mantissa.  */
1031         slli    a8, a8, 23
1032         add     a2, a10, a8
1034 .Ldiv_addsign:
1035         /* Add the sign bit.  */
1036         srli    a7, a7, 31
1037         slli    a7, a7, 31
1038         or      a2, a2, a7
1039         abi_return
1041 .Ldiv_overflow:
1042         bltz    a8, .Ldiv_underflow
1043         /* Return +/- Infinity.  */
1044         addi    a8, a4, 1       /* 0xff */
1045         slli    a2, a8, 23
1046         j       .Ldiv_addsign
1048 .Ldiv_exactlyhalf:
1049         /* Remainder is exactly half the divisor.  Round even.  */
1050         srli    a10, a10, 1
1051         slli    a10, a10, 1
1052         j       .Ldiv_rounded
1054 .Ldiv_underflow:
1055         /* Create a subnormal value, where the exponent field contains zero,
1056            but the effective exponent is 1.  The value of a8 is one less than
1057            the actual exponent, so just negate it to get the shift amount.  */
1058         neg     a8, a8
1059         ssr     a8
1060         bgeui   a8, 32, .Ldiv_flush_to_zero
1061         
1062         /* Shift a10 right.  Any bits that are shifted out of a10 are
1063            saved in a6 for rounding the result.  */
1064         sll     a6, a10
1065         srl     a10, a10
1067         /* Set the exponent to zero.  */
1068         movi    a8, 0
1070         /* Pack any nonzero remainder (in a2) into a6.  */
1071         beqz    a2, 1f
1072         movi    a9, 1
1073         or      a6, a6, a9
1074         
1075         /* Round a10 based on the bits shifted out into a6.  */
1076 1:      bgez    a6, .Ldiv_rounded
1077         addi    a10, a10, 1
1078         slli    a6, a6, 1
1079         bnez    a6, .Ldiv_rounded
1080         srli    a10, a10, 1
1081         slli    a10, a10, 1
1082         j       .Ldiv_rounded
1084 .Ldiv_flush_to_zero:
1085         /* Return zero with the appropriate sign bit.  */
1086         srli    a2, a7, 31
1087         slli    a2, a2, 31
1088         abi_return
1090 #endif /* L_divsf3 */
1092 #ifdef L_cmpsf2
1094         /* Equal and Not Equal */
1096         .align  4
1097         .global __eqsf2
1098         .global __nesf2
1099         .set    __nesf2, __eqsf2
1100         .type   __eqsf2, @function
1101 __eqsf2:
1102         abi_entry sp, 32
1103         bne     a2, a3, 4f
1105         /* The values are equal but NaN != NaN.  Check the exponent.  */
1106         movi    a6, 0x7f800000
1107         ball    a2, a6, 3f
1109         /* Equal.  */
1110         movi    a2, 0
1111         abi_return
1113         /* Not equal.  */
1114 2:      movi    a2, 1
1115         abi_return
1117         /* Check if the mantissas are nonzero.  */
1118 3:      slli    a7, a2, 9
1119         j       5f
1121         /* Check if x and y are zero with different signs.  */
1122 4:      or      a7, a2, a3
1123         slli    a7, a7, 1
1125         /* Equal if a7 == 0, where a7 is either abs(x | y) or the mantissa
1126            or x when exponent(x) = 0x7f8 and x == y.  */
1127 5:      movi    a2, 0
1128         movi    a3, 1
1129         movnez  a2, a3, a7      
1130         abi_return
1133         /* Greater Than */
1135         .align  4
1136         .global __gtsf2
1137         .type   __gtsf2, @function
1138 __gtsf2:
1139         abi_entry sp, 32
1140         movi    a6, 0x7f800000
1141         ball    a2, a6, 2f
1142 1:      bnall   a3, a6, .Lle_cmp
1144         /* Check if y is a NaN.  */
1145         slli    a7, a3, 9
1146         beqz    a7, .Lle_cmp
1147         movi    a2, 0
1148         abi_return
1150         /* Check if x is a NaN.  */
1151 2:      slli    a7, a2, 9
1152         beqz    a7, 1b
1153         movi    a2, 0
1154         abi_return
1157         /* Less Than or Equal */
1159         .align  4
1160         .global __lesf2
1161         .type   __lesf2, @function
1162 __lesf2:
1163         abi_entry sp, 32
1164         movi    a6, 0x7f800000
1165         ball    a2, a6, 2f
1166 1:      bnall   a3, a6, .Lle_cmp
1168         /* Check if y is a NaN.  */
1169         slli    a7, a3, 9
1170         beqz    a7, .Lle_cmp
1171         movi    a2, 1
1172         abi_return
1174         /* Check if x is a NaN.  */
1175 2:      slli    a7, a2, 9
1176         beqz    a7, 1b
1177         movi    a2, 1
1178         abi_return
1180 .Lle_cmp:
1181         /* Check if x and y have different signs.  */
1182         xor     a7, a2, a3
1183         bltz    a7, .Lle_diff_signs
1185         /* Check if x is negative.  */
1186         bltz    a2, .Lle_xneg
1188         /* Check if x <= y.  */
1189         bltu    a3, a2, 5f
1190 4:      movi    a2, 0
1191         abi_return
1193 .Lle_xneg:
1194         /* Check if y <= x.  */
1195         bgeu    a2, a3, 4b
1196 5:      movi    a2, 1
1197         abi_return
1199 .Lle_diff_signs:
1200         bltz    a2, 4b
1202         /* Check if both x and y are zero.  */
1203         or      a7, a2, a3
1204         slli    a7, a7, 1
1205         movi    a2, 1
1206         movi    a3, 0
1207         moveqz  a2, a3, a7
1208         abi_return
1211         /* Greater Than or Equal */
1213         .align  4
1214         .global __gesf2
1215         .type   __gesf2, @function
1216 __gesf2:
1217         abi_entry sp, 32
1218         movi    a6, 0x7f800000
1219         ball    a2, a6, 2f
1220 1:      bnall   a3, a6, .Llt_cmp
1222         /* Check if y is a NaN.  */
1223         slli    a7, a3, 9
1224         beqz    a7, .Llt_cmp
1225         movi    a2, -1
1226         abi_return
1228         /* Check if x is a NaN.  */
1229 2:      slli    a7, a2, 9
1230         beqz    a7, 1b
1231         movi    a2, -1
1232         abi_return
1235         /* Less Than */
1237         .align  4
1238         .global __ltsf2
1239         .type   __ltsf2, @function
1240 __ltsf2:
1241         abi_entry sp, 32
1242         movi    a6, 0x7f800000
1243         ball    a2, a6, 2f
1244 1:      bnall   a3, a6, .Llt_cmp
1246         /* Check if y is a NaN.  */
1247         slli    a7, a3, 9
1248         beqz    a7, .Llt_cmp
1249         movi    a2, 0
1250         abi_return
1252         /* Check if x is a NaN.  */
1253 2:      slli    a7, a2, 9
1254         beqz    a7, 1b
1255         movi    a2, 0
1256         abi_return
1258 .Llt_cmp:
1259         /* Check if x and y have different signs.  */
1260         xor     a7, a2, a3
1261         bltz    a7, .Llt_diff_signs
1263         /* Check if x is negative.  */
1264         bltz    a2, .Llt_xneg
1266         /* Check if x < y.  */
1267         bgeu    a2, a3, 5f
1268 4:      movi    a2, -1
1269         abi_return
1271 .Llt_xneg:
1272         /* Check if y < x.  */
1273         bltu    a3, a2, 4b
1274 5:      movi    a2, 0
1275         abi_return
1277 .Llt_diff_signs:
1278         bgez    a2, 5b
1280         /* Check if both x and y are nonzero.  */
1281         or      a7, a2, a3
1282         slli    a7, a7, 1
1283         movi    a2, 0
1284         movi    a3, -1
1285         movnez  a2, a3, a7
1286         abi_return
1289         /* Unordered */
1291         .align  4
1292         .global __unordsf2
1293         .type   __unordsf2, @function
1294 __unordsf2:
1295         abi_entry sp, 32
1296         movi    a6, 0x7f800000
1297         ball    a2, a6, 3f
1298 1:      ball    a3, a6, 4f
1299 2:      movi    a2, 0
1300         abi_return
1302 3:      slli    a7, a2, 9
1303         beqz    a7, 1b
1304         movi    a2, 1
1305         abi_return
1307 4:      slli    a7, a3, 9
1308         beqz    a7, 2b
1309         movi    a2, 1
1310         abi_return
1312 #endif /* L_cmpsf2 */
1314 #ifdef L_fixsfsi
1316         .align  4
1317         .global __fixsfsi
1318         .type   __fixsfsi, @function
1319 __fixsfsi:
1320         abi_entry sp, 32
1322         /* Check for NaN and Infinity.  */
1323         movi    a6, 0x7f800000
1324         ball    a2, a6, .Lfixsfsi_nan_or_inf
1326         /* Extract the exponent and check if 0 < (exp - 0x7e) < 32.  */
1327         extui   a4, a2, 23, 8
1328         addi    a4, a4, -0x7e
1329         bgei    a4, 32, .Lfixsfsi_maxint
1330         blti    a4, 1, .Lfixsfsi_zero
1332         /* Add explicit "1.0" and shift << 8.  */
1333         or      a7, a2, a6
1334         slli    a5, a7, 8
1336         /* Shift back to the right, based on the exponent.  */
1337         ssl     a4              /* shift by 32 - a4 */
1338         srl     a5, a5
1340         /* Negate the result if sign != 0.  */
1341         neg     a2, a5
1342         movgez  a2, a5, a7
1343         abi_return
1345 .Lfixsfsi_nan_or_inf:
1346         /* Handle Infinity and NaN.  */
1347         slli    a4, a2, 9
1348         beqz    a4, .Lfixsfsi_maxint
1350         /* Translate NaN to +maxint.  */
1351         movi    a2, 0
1353 .Lfixsfsi_maxint:
1354         slli    a4, a6, 8       /* 0x80000000 */
1355         addi    a5, a4, -1      /* 0x7fffffff */
1356         movgez  a4, a5, a2
1357         mov     a2, a4
1358         abi_return
1360 .Lfixsfsi_zero:
1361         movi    a2, 0
1362         abi_return
1364 #endif /* L_fixsfsi */
1366 #ifdef L_fixsfdi
1368         .align  4
1369         .global __fixsfdi
1370         .type   __fixsfdi, @function
1371 __fixsfdi:
1372         abi_entry sp, 32
1374         /* Check for NaN and Infinity.  */
1375         movi    a6, 0x7f800000
1376         ball    a2, a6, .Lfixsfdi_nan_or_inf
1378         /* Extract the exponent and check if 0 < (exp - 0x7e) < 64.  */
1379         extui   a4, a2, 23, 8
1380         addi    a4, a4, -0x7e
1381         bgei    a4, 64, .Lfixsfdi_maxint
1382         blti    a4, 1, .Lfixsfdi_zero
1384         /* Add explicit "1.0" and shift << 8.  */
1385         or      a7, a2, a6
1386         slli    xh, a7, 8
1388         /* Shift back to the right, based on the exponent.  */
1389         ssl     a4              /* shift by 64 - a4 */
1390         bgei    a4, 32, .Lfixsfdi_smallshift
1391         srl     xl, xh
1392         movi    xh, 0
1394 .Lfixsfdi_shifted:      
1395         /* Negate the result if sign != 0.  */
1396         bgez    a7, 1f
1397         neg     xl, xl
1398         neg     xh, xh
1399         beqz    xl, 1f
1400         addi    xh, xh, -1
1401 1:      abi_return
1403 .Lfixsfdi_smallshift:
1404         movi    xl, 0
1405         sll     xl, xh
1406         srl     xh, xh
1407         j       .Lfixsfdi_shifted
1409 .Lfixsfdi_nan_or_inf:
1410         /* Handle Infinity and NaN.  */
1411         slli    a4, a2, 9
1412         beqz    a4, .Lfixsfdi_maxint
1414         /* Translate NaN to +maxint.  */
1415         movi    a2, 0
1417 .Lfixsfdi_maxint:
1418         slli    a7, a6, 8       /* 0x80000000 */
1419         bgez    a2, 1f
1420         mov     xh, a7
1421         movi    xl, 0
1422         abi_return
1424 1:      addi    xh, a7, -1      /* 0x7fffffff */
1425         movi    xl, -1
1426         abi_return
1428 .Lfixsfdi_zero:
1429         movi    xh, 0
1430         movi    xl, 0
1431         abi_return
1433 #endif /* L_fixsfdi */
1435 #ifdef L_fixunssfsi
1437         .align  4
1438         .global __fixunssfsi
1439         .type   __fixunssfsi, @function
1440 __fixunssfsi:
1441         abi_entry sp, 32
1443         /* Check for NaN and Infinity.  */
1444         movi    a6, 0x7f800000
1445         ball    a2, a6, .Lfixunssfsi_nan_or_inf
1447         /* Extract the exponent and check if 0 <= (exp - 0x7f) < 32.  */
1448         extui   a4, a2, 23, 8
1449         addi    a4, a4, -0x7f
1450         bgei    a4, 32, .Lfixunssfsi_maxint
1451         bltz    a4, .Lfixunssfsi_zero
1453         /* Add explicit "1.0" and shift << 8.  */
1454         or      a7, a2, a6
1455         slli    a5, a7, 8
1457         /* Shift back to the right, based on the exponent.  */
1458         addi    a4, a4, 1
1459         beqi    a4, 32, .Lfixunssfsi_bigexp
1460         ssl     a4              /* shift by 32 - a4 */
1461         srl     a5, a5
1463         /* Negate the result if sign != 0.  */
1464         neg     a2, a5
1465         movgez  a2, a5, a7
1466         abi_return
1468 .Lfixunssfsi_nan_or_inf:
1469         /* Handle Infinity and NaN.  */
1470         slli    a4, a2, 9
1471         beqz    a4, .Lfixunssfsi_maxint
1473         /* Translate NaN to 0xffffffff.  */
1474         movi    a2, -1
1475         abi_return
1477 .Lfixunssfsi_maxint:
1478         slli    a4, a6, 8       /* 0x80000000 */
1479         movi    a5, -1          /* 0xffffffff */
1480         movgez  a4, a5, a2
1481         mov     a2, a4
1482         abi_return
1484 .Lfixunssfsi_zero:
1485         movi    a2, 0
1486         abi_return
1488 .Lfixunssfsi_bigexp:
1489         /* Handle unsigned maximum exponent case.  */
1490         bltz    a2, 1f
1491         mov     a2, a5          /* no shift needed */
1492         abi_return
1494         /* Return 0x80000000 if negative.  */
1495 1:      slli    a2, a6, 8
1496         abi_return
1498 #endif /* L_fixunssfsi */
1500 #ifdef L_fixunssfdi
1502         .align  4
1503         .global __fixunssfdi
1504         .type   __fixunssfdi, @function
1505 __fixunssfdi:
1506         abi_entry sp, 32
1508         /* Check for NaN and Infinity.  */
1509         movi    a6, 0x7f800000
1510         ball    a2, a6, .Lfixunssfdi_nan_or_inf
1512         /* Extract the exponent and check if 0 <= (exp - 0x7f) < 64.  */
1513         extui   a4, a2, 23, 8
1514         addi    a4, a4, -0x7f
1515         bgei    a4, 64, .Lfixunssfdi_maxint
1516         bltz    a4, .Lfixunssfdi_zero
1518         /* Add explicit "1.0" and shift << 8.  */
1519         or      a7, a2, a6
1520         slli    xh, a7, 8
1522         /* Shift back to the right, based on the exponent.  */
1523         addi    a4, a4, 1
1524         beqi    a4, 64, .Lfixunssfdi_bigexp
1525         ssl     a4              /* shift by 64 - a4 */
1526         bgei    a4, 32, .Lfixunssfdi_smallshift
1527         srl     xl, xh
1528         movi    xh, 0
1530 .Lfixunssfdi_shifted:
1531         /* Negate the result if sign != 0.  */
1532         bgez    a7, 1f
1533         neg     xl, xl
1534         neg     xh, xh
1535         beqz    xl, 1f
1536         addi    xh, xh, -1
1537 1:      abi_return
1539 .Lfixunssfdi_smallshift:
1540         movi    xl, 0
1541         src     xl, xh, xl
1542         srl     xh, xh
1543         j       .Lfixunssfdi_shifted
1545 .Lfixunssfdi_nan_or_inf:
1546         /* Handle Infinity and NaN.  */
1547         slli    a4, a2, 9
1548         beqz    a4, .Lfixunssfdi_maxint
1550         /* Translate NaN to 0xffffffff.... */
1551 1:      movi    xh, -1
1552         movi    xl, -1
1553         abi_return
1555 .Lfixunssfdi_maxint:
1556         bgez    a2, 1b
1557 2:      slli    xh, a6, 8       /* 0x80000000 */
1558         movi    xl, 0
1559         abi_return
1561 .Lfixunssfdi_zero:
1562         movi    xh, 0
1563         movi    xl, 0
1564         abi_return
1566 .Lfixunssfdi_bigexp:
1567         /* Handle unsigned maximum exponent case.  */
1568         bltz    a7, 2b
1569         movi    xl, 0
1570         abi_return              /* no shift needed */
1572 #endif /* L_fixunssfdi */
1574 #ifdef L_floatsisf
1576         .align  4
1577         .global __floatunsisf
1578         .type   __floatunsisf, @function
1579 __floatunsisf:
1580         abi_entry sp, 32
1581         beqz    a2, .Lfloatsisf_return
1583         /* Set the sign to zero and jump to the floatsisf code.  */
1584         movi    a7, 0
1585         j       .Lfloatsisf_normalize
1587         .align  4
1588         .global __floatsisf
1589         .type   __floatsisf, @function
1590 __floatsisf:
1591         abi_entry sp, 32
1593         /* Check for zero.  */
1594         beqz    a2, .Lfloatsisf_return
1596         /* Save the sign.  */
1597         extui   a7, a2, 31, 1
1599         /* Get the absolute value.  */
1600 #if XCHAL_HAVE_ABS
1601         abs     a2, a2
1602 #else
1603         neg     a4, a2
1604         movltz  a2, a4, a2
1605 #endif
1607 .Lfloatsisf_normalize:
1608         /* Normalize with the first 1 bit in the msb.  */
1609         do_nsau a4, a2, a5, a6
1610         ssl     a4
1611         sll     a5, a2
1613         /* Shift the mantissa into position, with rounding bits in a6.  */
1614         srli    a2, a5, 8
1615         slli    a6, a5, (32 - 8)
1617         /* Set the exponent.  */
1618         movi    a5, 0x9d        /* 0x7e + 31 */
1619         sub     a5, a5, a4
1620         slli    a5, a5, 23
1621         add     a2, a2, a5
1623         /* Add the sign.  */
1624         slli    a7, a7, 31
1625         or      a2, a2, a7
1627         /* Round up if the leftover fraction is >= 1/2.  */
1628         bgez    a6, .Lfloatsisf_return
1629         addi    a2, a2, 1       /* Overflow to the exponent is OK.  */
1631         /* Check if the leftover fraction is exactly 1/2.  */
1632         slli    a6, a6, 1
1633         beqz    a6, .Lfloatsisf_exactlyhalf
1635 .Lfloatsisf_return:
1636         abi_return
1638 .Lfloatsisf_exactlyhalf:
1639         /* Round down to the nearest even value.  */
1640         srli    a2, a2, 1
1641         slli    a2, a2, 1
1642         abi_return
1644 #endif /* L_floatsisf */
1646 #ifdef L_floatdisf
1648         .align  4
1649         .global __floatundisf
1650         .type   __floatundisf, @function
1651 __floatundisf:
1652         abi_entry sp, 32
1654         /* Check for zero.  */
1655         or      a4, xh, xl
1656         beqz    a4, 2f
1658         /* Set the sign to zero and jump to the floatdisf code.  */
1659         movi    a7, 0
1660         j       .Lfloatdisf_normalize
1662         .align  4
1663         .global __floatdisf
1664         .type   __floatdisf, @function
1665 __floatdisf:
1666         abi_entry sp, 32
1668         /* Check for zero.  */
1669         or      a4, xh, xl
1670         beqz    a4, 2f
1672         /* Save the sign.  */
1673         extui   a7, xh, 31, 1
1675         /* Get the absolute value.  */
1676         bgez    xh, .Lfloatdisf_normalize
1677         neg     xl, xl
1678         neg     xh, xh
1679         beqz    xl, .Lfloatdisf_normalize
1680         addi    xh, xh, -1
1682 .Lfloatdisf_normalize:
1683         /* Normalize with the first 1 bit in the msb of xh.  */
1684         beqz    xh, .Lfloatdisf_bigshift
1685         do_nsau a4, xh, a5, a6
1686         ssl     a4
1687         src     xh, xh, xl
1688         sll     xl, xl
1690 .Lfloatdisf_shifted:
1691         /* Shift the mantissa into position, with rounding bits in a6.  */
1692         ssai    8
1693         sll     a5, xl
1694         src     a6, xh, xl
1695         srl     xh, xh
1696         beqz    a5, 1f
1697         movi    a5, 1
1698         or      a6, a6, a5
1700         /* Set the exponent.  */
1701         movi    a5, 0xbd        /* 0x7e + 63 */
1702         sub     a5, a5, a4
1703         slli    a5, a5, 23
1704         add     a2, xh, a5
1706         /* Add the sign.  */
1707         slli    a7, a7, 31
1708         or      a2, a2, a7
1710         /* Round up if the leftover fraction is >= 1/2.  */
1711         bgez    a6, 2f
1712         addi    a2, a2, 1       /* Overflow to the exponent is OK.  */
1714         /* Check if the leftover fraction is exactly 1/2.  */
1715         slli    a6, a6, 1
1716         beqz    a6, .Lfloatdisf_exactlyhalf
1717 2:      abi_return
1719 .Lfloatdisf_bigshift:
1720         /* xh is zero.  Normalize with first 1 bit of xl in the msb of xh.  */
1721         do_nsau a4, xl, a5, a6
1722         ssl     a4
1723         sll     xh, xl
1724         movi    xl, 0
1725         addi    a4, a4, 32
1726         j       .Lfloatdisf_shifted
1728 .Lfloatdisf_exactlyhalf:
1729         /* Round down to the nearest even value.  */
1730         srli    a2, a2, 1
1731         slli    a2, a2, 1
1732         abi_return
1734 #endif /* L_floatdisf */