2013-06-18 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgcc / config / xtensa / ieee754-sf.S
blobe9c10b41ae8150aa2d1f1635ecf970d7ae3dd497
1 /* IEEE-754 single-precision functions for Xtensa
2    Copyright (C) 2006-2013 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 3, or (at your option)
10    any later version.
12    GCC is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
17    Under Section 7 of GPL version 3, you are granted additional
18    permissions described in the GCC Runtime Library Exception, version
19    3.1, as published by the Free Software Foundation.
21    You should have received a copy of the GNU General Public License and
22    a copy of the GCC Runtime Library Exception along with this program;
23    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24    <http://www.gnu.org/licenses/>.  */
26 #ifdef __XTENSA_EB__
27 #define xh a2
28 #define xl a3
29 #define yh a4
30 #define yl a5
31 #else
32 #define xh a3
33 #define xl a2
34 #define yh a5
35 #define yl a4
36 #endif
38 /*  Warning!  The branch displacements for some Xtensa branch instructions
39     are quite small, and this code has been carefully laid out to keep
40     branch targets in range.  If you change anything, be sure to check that
41     the assembler is not relaxing anything to branch over a jump.  */
43 #ifdef L_negsf2
45         .align  4
46         .global __negsf2
47         .type   __negsf2, @function
48 __negsf2:
49         leaf_entry sp, 16
50         movi    a4, 0x80000000
51         xor     a2, a2, a4
52         leaf_return
54 #endif /* L_negsf2 */
56 #ifdef L_addsubsf3
58         /* Addition */
59 __addsf3_aux:
61         /* Handle NaNs and Infinities.  (This code is placed before the
62            start of the function just to keep it in range of the limited
63            branch displacements.)  */
65 .Ladd_xnan_or_inf:
66         /* If y is neither Infinity nor NaN, return x.  */
67         bnall   a3, a6, 1f
68         /* If x is a NaN, return it.  Otherwise, return y.  */
69         slli    a7, a2, 9
70         beqz    a7, .Ladd_ynan_or_inf
71 1:      leaf_return
73 .Ladd_ynan_or_inf:
74         /* Return y.  */
75         mov     a2, a3
76         leaf_return
78 .Ladd_opposite_signs:
79         /* Operand signs differ.  Do a subtraction.  */
80         slli    a7, a6, 8
81         xor     a3, a3, a7
82         j       .Lsub_same_sign
84         .align  4
85         .global __addsf3
86         .type   __addsf3, @function
87 __addsf3:
88         leaf_entry sp, 16
89         movi    a6, 0x7f800000
91         /* Check if the two operands have the same sign.  */
92         xor     a7, a2, a3
93         bltz    a7, .Ladd_opposite_signs
95 .Ladd_same_sign:        
96         /* Check if either exponent == 0x7f8 (i.e., NaN or Infinity).  */
97         ball    a2, a6, .Ladd_xnan_or_inf
98         ball    a3, a6, .Ladd_ynan_or_inf
100         /* Compare the exponents.  The smaller operand will be shifted
101            right by the exponent difference and added to the larger
102            one.  */
103         extui   a7, a2, 23, 9
104         extui   a8, a3, 23, 9
105         bltu    a7, a8, .Ladd_shiftx
107 .Ladd_shifty:
108         /* Check if the smaller (or equal) exponent is zero.  */
109         bnone   a3, a6, .Ladd_yexpzero
111         /* Replace y sign/exponent with 0x008.  */
112         or      a3, a3, a6
113         slli    a3, a3, 8
114         srli    a3, a3, 8
116 .Ladd_yexpdiff:
117         /* Compute the exponent difference.  */
118         sub     a10, a7, a8
120         /* Exponent difference > 32 -- just return the bigger value.  */
121         bgeui   a10, 32, 1f
122         
123         /* Shift y right by the exponent difference.  Any bits that are
124            shifted out of y are saved in a9 for rounding the result.  */
125         ssr     a10
126         movi    a9, 0
127         src     a9, a3, a9
128         srl     a3, a3
130         /* Do the addition.  */
131         add     a2, a2, a3
133         /* Check if the add overflowed into the exponent.  */
134         extui   a10, a2, 23, 9
135         beq     a10, a7, .Ladd_round
136         mov     a8, a7
137         j       .Ladd_carry
139 .Ladd_yexpzero:
140         /* y is a subnormal value.  Replace its sign/exponent with zero,
141            i.e., no implicit "1.0", and increment the apparent exponent
142            because subnormals behave as if they had the minimum (nonzero)
143            exponent.  Test for the case when both exponents are zero.  */
144         slli    a3, a3, 9
145         srli    a3, a3, 9
146         bnone   a2, a6, .Ladd_bothexpzero
147         addi    a8, a8, 1
148         j       .Ladd_yexpdiff
150 .Ladd_bothexpzero:
151         /* Both exponents are zero.  Handle this as a special case.  There
152            is no need to shift or round, and the normal code for handling
153            a carry into the exponent field will not work because it
154            assumes there is an implicit "1.0" that needs to be added.  */
155         add     a2, a2, a3
156 1:      leaf_return
158 .Ladd_xexpzero:
159         /* Same as "yexpzero" except skip handling the case when both
160            exponents are zero.  */
161         slli    a2, a2, 9
162         srli    a2, a2, 9
163         addi    a7, a7, 1
164         j       .Ladd_xexpdiff
166 .Ladd_shiftx:
167         /* Same thing as the "shifty" code, but with x and y swapped.  Also,
168            because the exponent difference is always nonzero in this version,
169            the shift sequence can use SLL and skip loading a constant zero.  */
170         bnone   a2, a6, .Ladd_xexpzero
172         or      a2, a2, a6
173         slli    a2, a2, 8
174         srli    a2, a2, 8
176 .Ladd_xexpdiff:
177         sub     a10, a8, a7
178         bgeui   a10, 32, .Ladd_returny
179         
180         ssr     a10
181         sll     a9, a2
182         srl     a2, a2
184         add     a2, a2, a3
186         /* Check if the add overflowed into the exponent.  */
187         extui   a10, a2, 23, 9
188         bne     a10, a8, .Ladd_carry
190 .Ladd_round:
191         /* Round up if the leftover fraction is >= 1/2.  */
192         bgez    a9, 1f
193         addi    a2, a2, 1
195         /* Check if the leftover fraction is exactly 1/2.  */
196         slli    a9, a9, 1
197         beqz    a9, .Ladd_exactlyhalf
198 1:      leaf_return
200 .Ladd_returny:
201         mov     a2, a3
202         leaf_return
204 .Ladd_carry:    
205         /* The addition has overflowed into the exponent field, so the
206            value needs to be renormalized.  The mantissa of the result
207            can be recovered by subtracting the original exponent and
208            adding 0x800000 (which is the explicit "1.0" for the
209            mantissa of the non-shifted operand -- the "1.0" for the
210            shifted operand was already added).  The mantissa can then
211            be shifted right by one bit.  The explicit "1.0" of the
212            shifted mantissa then needs to be replaced by the exponent,
213            incremented by one to account for the normalizing shift.
214            It is faster to combine these operations: do the shift first
215            and combine the additions and subtractions.  If x is the
216            original exponent, the result is:
217                shifted mantissa - (x << 22) + (1 << 22) + (x << 23)
218            or:
219                shifted mantissa + ((x + 1) << 22)
220            Note that the exponent is incremented here by leaving the
221            explicit "1.0" of the mantissa in the exponent field.  */
223         /* Shift x right by one bit.  Save the lsb.  */
224         mov     a10, a2
225         srli    a2, a2, 1
227         /* See explanation above.  The original exponent is in a8.  */
228         addi    a8, a8, 1
229         slli    a8, a8, 22
230         add     a2, a2, a8
232         /* Return an Infinity if the exponent overflowed.  */
233         ball    a2, a6, .Ladd_infinity
234         
235         /* Same thing as the "round" code except the msb of the leftover
236            fraction is bit 0 of a10, with the rest of the fraction in a9.  */
237         bbci.l  a10, 0, 1f
238         addi    a2, a2, 1
239         beqz    a9, .Ladd_exactlyhalf
240 1:      leaf_return
242 .Ladd_infinity:
243         /* Clear the mantissa.  */
244         srli    a2, a2, 23
245         slli    a2, a2, 23
247         /* The sign bit may have been lost in a carry-out.  Put it back.  */
248         slli    a8, a8, 1
249         or      a2, a2, a8
250         leaf_return
252 .Ladd_exactlyhalf:
253         /* Round down to the nearest even value.  */
254         srli    a2, a2, 1
255         slli    a2, a2, 1
256         leaf_return
259         /* Subtraction */
260 __subsf3_aux:
261         
262         /* Handle NaNs and Infinities.  (This code is placed before the
263            start of the function just to keep it in range of the limited
264            branch displacements.)  */
266 .Lsub_xnan_or_inf:
267         /* If y is neither Infinity nor NaN, return x.  */
268         bnall   a3, a6, 1f
269         /* Both x and y are either NaN or Inf, so the result is NaN.  */
270         movi    a4, 0x400000    /* make it a quiet NaN */
271         or      a2, a2, a4
272 1:      leaf_return
274 .Lsub_ynan_or_inf:
275         /* Negate y and return it.  */
276         slli    a7, a6, 8
277         xor     a2, a3, a7
278         leaf_return
280 .Lsub_opposite_signs:
281         /* Operand signs differ.  Do an addition.  */
282         slli    a7, a6, 8
283         xor     a3, a3, a7
284         j       .Ladd_same_sign
286         .align  4
287         .global __subsf3
288         .type   __subsf3, @function
289 __subsf3:
290         leaf_entry sp, 16
291         movi    a6, 0x7f800000
293         /* Check if the two operands have the same sign.  */
294         xor     a7, a2, a3
295         bltz    a7, .Lsub_opposite_signs
297 .Lsub_same_sign:        
298         /* Check if either exponent == 0x7f8 (i.e., NaN or Infinity).  */
299         ball    a2, a6, .Lsub_xnan_or_inf
300         ball    a3, a6, .Lsub_ynan_or_inf
302         /* Compare the operands.  In contrast to addition, the entire
303            value matters here.  */
304         extui   a7, a2, 23, 8
305         extui   a8, a3, 23, 8
306         bltu    a2, a3, .Lsub_xsmaller
308 .Lsub_ysmaller:
309         /* Check if the smaller (or equal) exponent is zero.  */
310         bnone   a3, a6, .Lsub_yexpzero
312         /* Replace y sign/exponent with 0x008.  */
313         or      a3, a3, a6
314         slli    a3, a3, 8
315         srli    a3, a3, 8
317 .Lsub_yexpdiff:
318         /* Compute the exponent difference.  */
319         sub     a10, a7, a8
321         /* Exponent difference > 32 -- just return the bigger value.  */
322         bgeui   a10, 32, 1f
323         
324         /* Shift y right by the exponent difference.  Any bits that are
325            shifted out of y are saved in a9 for rounding the result.  */
326         ssr     a10
327         movi    a9, 0
328         src     a9, a3, a9
329         srl     a3, a3
331         sub     a2, a2, a3
333         /* Subtract the leftover bits in a9 from zero and propagate any
334            borrow from a2.  */
335         neg     a9, a9
336         addi    a10, a2, -1
337         movnez  a2, a10, a9
339         /* Check if the subtract underflowed into the exponent.  */
340         extui   a10, a2, 23, 8
341         beq     a10, a7, .Lsub_round
342         j       .Lsub_borrow
344 .Lsub_yexpzero:
345         /* Return zero if the inputs are equal.  (For the non-subnormal
346            case, subtracting the "1.0" will cause a borrow from the exponent
347            and this case can be detected when handling the borrow.)  */
348         beq     a2, a3, .Lsub_return_zero
350         /* y is a subnormal value.  Replace its sign/exponent with zero,
351            i.e., no implicit "1.0".  Unless x is also a subnormal, increment
352            y's apparent exponent because subnormals behave as if they had
353            the minimum (nonzero) exponent.  */
354         slli    a3, a3, 9
355         srli    a3, a3, 9
356         bnone   a2, a6, .Lsub_yexpdiff
357         addi    a8, a8, 1
358         j       .Lsub_yexpdiff
360 .Lsub_returny:
361         /* Negate and return y.  */
362         slli    a7, a6, 8
363         xor     a2, a3, a7
364 1:      leaf_return
366 .Lsub_xsmaller:
367         /* Same thing as the "ysmaller" code, but with x and y swapped and
368            with y negated.  */
369         bnone   a2, a6, .Lsub_xexpzero
371         or      a2, a2, a6
372         slli    a2, a2, 8
373         srli    a2, a2, 8
375 .Lsub_xexpdiff:
376         sub     a10, a8, a7
377         bgeui   a10, 32, .Lsub_returny
378         
379         ssr     a10
380         movi    a9, 0
381         src     a9, a2, a9
382         srl     a2, a2
384         /* Negate y.  */
385         slli    a11, a6, 8
386         xor     a3, a3, a11
388         sub     a2, a3, a2
390         neg     a9, a9
391         addi    a10, a2, -1
392         movnez  a2, a10, a9
394         /* Check if the subtract underflowed into the exponent.  */
395         extui   a10, a2, 23, 8
396         bne     a10, a8, .Lsub_borrow
398 .Lsub_round:
399         /* Round up if the leftover fraction is >= 1/2.  */
400         bgez    a9, 1f
401         addi    a2, a2, 1
403         /* Check if the leftover fraction is exactly 1/2.  */
404         slli    a9, a9, 1
405         beqz    a9, .Lsub_exactlyhalf
406 1:      leaf_return
408 .Lsub_xexpzero:
409         /* Same as "yexpzero".  */
410         beq     a2, a3, .Lsub_return_zero
411         slli    a2, a2, 9
412         srli    a2, a2, 9
413         bnone   a3, a6, .Lsub_xexpdiff
414         addi    a7, a7, 1
415         j       .Lsub_xexpdiff
417 .Lsub_return_zero:
418         movi    a2, 0
419         leaf_return
421 .Lsub_borrow:   
422         /* The subtraction has underflowed into the exponent field, so the
423            value needs to be renormalized.  Shift the mantissa left as
424            needed to remove any leading zeros and adjust the exponent
425            accordingly.  If the exponent is not large enough to remove
426            all the leading zeros, the result will be a subnormal value.  */
428         slli    a8, a2, 9
429         beqz    a8, .Lsub_xzero
430         do_nsau a6, a8, a7, a11
431         srli    a8, a8, 9
432         bge     a6, a10, .Lsub_subnormal
433         addi    a6, a6, 1
435 .Lsub_normalize_shift:
436         /* Shift the mantissa (a8/a9) left by a6.  */
437         ssl     a6
438         src     a8, a8, a9
439         sll     a9, a9
441         /* Combine the shifted mantissa with the sign and exponent,
442            decrementing the exponent by a6.  (The exponent has already
443            been decremented by one due to the borrow from the subtraction,
444            but adding the mantissa will increment the exponent by one.)  */
445         srli    a2, a2, 23
446         sub     a2, a2, a6
447         slli    a2, a2, 23
448         add     a2, a2, a8
449         j       .Lsub_round
451 .Lsub_exactlyhalf:
452         /* Round down to the nearest even value.  */
453         srli    a2, a2, 1
454         slli    a2, a2, 1
455         leaf_return
457 .Lsub_xzero:
458         /* If there was a borrow from the exponent, and the mantissa and
459            guard digits are all zero, then the inputs were equal and the
460            result should be zero.  */
461         beqz    a9, .Lsub_return_zero
463         /* Only the guard digit is nonzero.  Shift by min(24, a10).  */
464         addi    a11, a10, -24
465         movi    a6, 24
466         movltz  a6, a10, a11
467         j       .Lsub_normalize_shift
469 .Lsub_subnormal:
470         /* The exponent is too small to shift away all the leading zeros.
471            Set a6 to the current exponent (which has already been
472            decremented by the borrow) so that the exponent of the result
473            will be zero.  Do not add 1 to a6 in this case, because: (1)
474            adding the mantissa will not increment the exponent, so there is
475            no need to subtract anything extra from the exponent to
476            compensate, and (2) the effective exponent of a subnormal is 1
477            not 0 so the shift amount must be 1 smaller than normal. */
478         mov     a6, a10
479         j       .Lsub_normalize_shift
481 #endif /* L_addsubsf3 */
483 #ifdef L_mulsf3
485         /* Multiplication */
486 #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
487 #define XCHAL_NO_MUL 1
488 #endif
490 __mulsf3_aux:
492         /* Handle unusual cases (zeros, subnormals, NaNs and Infinities).
493            (This code is placed before the start of the function just to
494            keep it in range of the limited branch displacements.)  */
496 .Lmul_xexpzero:
497         /* Clear the sign bit of x.  */
498         slli    a2, a2, 1
499         srli    a2, a2, 1
501         /* If x is zero, return zero.  */
502         beqz    a2, .Lmul_return_zero
504         /* Normalize x.  Adjust the exponent in a8.  */
505         do_nsau a10, a2, a11, a12
506         addi    a10, a10, -8
507         ssl     a10
508         sll     a2, a2 
509         movi    a8, 1
510         sub     a8, a8, a10
511         j       .Lmul_xnormalized       
512         
513 .Lmul_yexpzero:
514         /* Clear the sign bit of y.  */
515         slli    a3, a3, 1
516         srli    a3, a3, 1
518         /* If y is zero, return zero.  */
519         beqz    a3, .Lmul_return_zero
521         /* Normalize y.  Adjust the exponent in a9.  */
522         do_nsau a10, a3, a11, a12
523         addi    a10, a10, -8
524         ssl     a10
525         sll     a3, a3
526         movi    a9, 1
527         sub     a9, a9, a10
528         j       .Lmul_ynormalized       
530 .Lmul_return_zero:
531         /* Return zero with the appropriate sign bit.  */
532         srli    a2, a7, 31
533         slli    a2, a2, 31
534         j       .Lmul_done
536 .Lmul_xnan_or_inf:
537         /* If y is zero, return NaN.  */
538         slli    a8, a3, 1
539         bnez    a8, 1f
540         movi    a4, 0x400000    /* make it a quiet NaN */
541         or      a2, a2, a4
542         j       .Lmul_done
544         /* If y is NaN, return y.  */
545         bnall   a3, a6, .Lmul_returnx
546         slli    a8, a3, 9
547         beqz    a8, .Lmul_returnx
549 .Lmul_returny:
550         mov     a2, a3
552 .Lmul_returnx:
553         /* Set the sign bit and return.  */
554         extui   a7, a7, 31, 1
555         slli    a2, a2, 1
556         ssai    1
557         src     a2, a7, a2
558         j       .Lmul_done
560 .Lmul_ynan_or_inf:
561         /* If x is zero, return NaN.  */
562         slli    a8, a2, 1
563         bnez    a8, .Lmul_returny
564         movi    a7, 0x400000    /* make it a quiet NaN */
565         or      a2, a3, a7
566         j       .Lmul_done
568         .align  4
569         .global __mulsf3
570         .type   __mulsf3, @function
571 __mulsf3:
572 #if __XTENSA_CALL0_ABI__
573         leaf_entry sp, 32
574         addi    sp, sp, -32
575         s32i    a12, sp, 16
576         s32i    a13, sp, 20
577         s32i    a14, sp, 24
578         s32i    a15, sp, 28
579 #elif XCHAL_NO_MUL
580         /* This is not really a leaf function; allocate enough stack space
581            to allow CALL12s to a helper function.  */
582         leaf_entry sp, 64
583 #else
584         leaf_entry sp, 32
585 #endif
586         movi    a6, 0x7f800000
588         /* Get the sign of the result.  */
589         xor     a7, a2, a3
591         /* Check for NaN and infinity.  */
592         ball    a2, a6, .Lmul_xnan_or_inf
593         ball    a3, a6, .Lmul_ynan_or_inf
595         /* Extract the exponents.  */
596         extui   a8, a2, 23, 8
597         extui   a9, a3, 23, 8
599         beqz    a8, .Lmul_xexpzero
600 .Lmul_xnormalized:      
601         beqz    a9, .Lmul_yexpzero
602 .Lmul_ynormalized:      
604         /* Add the exponents.  */
605         add     a8, a8, a9
607         /* Replace sign/exponent fields with explicit "1.0".  */
608         movi    a10, 0xffffff
609         or      a2, a2, a6
610         and     a2, a2, a10
611         or      a3, a3, a6
612         and     a3, a3, a10
614         /* Multiply 32x32 to 64 bits.  The result ends up in a2/a6.  */
616 #if XCHAL_HAVE_MUL32_HIGH
618         mull    a6, a2, a3
619         muluh   a2, a2, a3
621 #else
623         /* Break the inputs into 16-bit chunks and compute 4 32-bit partial
624            products.  These partial products are:
626                 0 xl * yl
628                 1 xl * yh
629                 2 xh * yl
631                 3 xh * yh
633            If using the Mul16 or Mul32 multiplier options, these input
634            chunks must be stored in separate registers.  For Mac16, the
635            UMUL.AA.* opcodes can specify that the inputs come from either
636            half of the registers, so there is no need to shift them out
637            ahead of time.  If there is no multiply hardware, the 16-bit
638            chunks can be extracted when setting up the arguments to the
639            separate multiply function.  */
641 #if __XTENSA_CALL0_ABI__ && XCHAL_NO_MUL
642         /* Calling a separate multiply function will clobber a0 and requires
643            use of a8 as a temporary, so save those values now.  (The function
644            uses a custom ABI so nothing else needs to be saved.)  */
645         s32i    a0, sp, 0
646         s32i    a8, sp, 4
647 #endif
649 #if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32
651 #define a2h a4
652 #define a3h a5
654         /* Get the high halves of the inputs into registers.  */
655         srli    a2h, a2, 16
656         srli    a3h, a3, 16
658 #define a2l a2
659 #define a3l a3
661 #if XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MUL16
662         /* Clear the high halves of the inputs.  This does not matter
663            for MUL16 because the high bits are ignored.  */
664         extui   a2, a2, 0, 16
665         extui   a3, a3, 0, 16
666 #endif
667 #endif /* MUL16 || MUL32 */
670 #if XCHAL_HAVE_MUL16
672 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
673         mul16u  dst, xreg ## xhalf, yreg ## yhalf
675 #elif XCHAL_HAVE_MUL32
677 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
678         mull    dst, xreg ## xhalf, yreg ## yhalf
680 #elif XCHAL_HAVE_MAC16
682 /* The preprocessor insists on inserting a space when concatenating after
683    a period in the definition of do_mul below.  These macros are a workaround
684    using underscores instead of periods when doing the concatenation.  */
685 #define umul_aa_ll umul.aa.ll
686 #define umul_aa_lh umul.aa.lh
687 #define umul_aa_hl umul.aa.hl
688 #define umul_aa_hh umul.aa.hh
690 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
691         umul_aa_ ## xhalf ## yhalf      xreg, yreg; \
692         rsr     dst, ACCLO
694 #else /* no multiply hardware */
695         
696 #define set_arg_l(dst, src) \
697         extui   dst, src, 0, 16
698 #define set_arg_h(dst, src) \
699         srli    dst, src, 16
701 #if __XTENSA_CALL0_ABI__
702 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
703         set_arg_ ## xhalf (a13, xreg); \
704         set_arg_ ## yhalf (a14, yreg); \
705         call0   .Lmul_mulsi3; \
706         mov     dst, a12
707 #else
708 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
709         set_arg_ ## xhalf (a14, xreg); \
710         set_arg_ ## yhalf (a15, yreg); \
711         call12  .Lmul_mulsi3; \
712         mov     dst, a14
713 #endif /* __XTENSA_CALL0_ABI__ */
715 #endif /* no multiply hardware */
717         /* Add pp1 and pp2 into a6 with carry-out in a9.  */
718         do_mul(a6, a2, l, a3, h)        /* pp 1 */
719         do_mul(a11, a2, h, a3, l)       /* pp 2 */
720         movi    a9, 0
721         add     a6, a6, a11
722         bgeu    a6, a11, 1f
723         addi    a9, a9, 1
725         /* Shift the high half of a9/a6 into position in a9.  Note that
726            this value can be safely incremented without any carry-outs.  */
727         ssai    16
728         src     a9, a9, a6
730         /* Compute the low word into a6.  */
731         do_mul(a11, a2, l, a3, l)       /* pp 0 */
732         sll     a6, a6
733         add     a6, a6, a11
734         bgeu    a6, a11, 1f
735         addi    a9, a9, 1
737         /* Compute the high word into a2.  */
738         do_mul(a2, a2, h, a3, h)        /* pp 3 */
739         add     a2, a2, a9
740         
741 #if __XTENSA_CALL0_ABI__ && XCHAL_NO_MUL
742         /* Restore values saved on the stack during the multiplication.  */
743         l32i    a0, sp, 0
744         l32i    a8, sp, 4
745 #endif
746 #endif /* ! XCHAL_HAVE_MUL32_HIGH */
748         /* Shift left by 9 bits, unless there was a carry-out from the
749            multiply, in which case, shift by 8 bits and increment the
750            exponent.  */
751         movi    a4, 9
752         srli    a5, a2, 24 - 9
753         beqz    a5, 1f
754         addi    a4, a4, -1
755         addi    a8, a8, 1
756 1:      ssl     a4
757         src     a2, a2, a6
758         sll     a6, a6
760         /* Subtract the extra bias from the exponent sum (plus one to account
761            for the explicit "1.0" of the mantissa that will be added to the
762            exponent in the final result).  */
763         movi    a4, 0x80
764         sub     a8, a8, a4
765         
766         /* Check for over/underflow.  The value in a8 is one less than the
767            final exponent, so values in the range 0..fd are OK here.  */
768         movi    a4, 0xfe
769         bgeu    a8, a4, .Lmul_overflow
770         
771 .Lmul_round:
772         /* Round.  */
773         bgez    a6, .Lmul_rounded
774         addi    a2, a2, 1
775         slli    a6, a6, 1
776         beqz    a6, .Lmul_exactlyhalf
778 .Lmul_rounded:
779         /* Add the exponent to the mantissa.  */
780         slli    a8, a8, 23
781         add     a2, a2, a8
783 .Lmul_addsign:
784         /* Add the sign bit.  */
785         srli    a7, a7, 31
786         slli    a7, a7, 31
787         or      a2, a2, a7
789 .Lmul_done:
790 #if __XTENSA_CALL0_ABI__
791         l32i    a12, sp, 16
792         l32i    a13, sp, 20
793         l32i    a14, sp, 24
794         l32i    a15, sp, 28
795         addi    sp, sp, 32
796 #endif
797         leaf_return
799 .Lmul_exactlyhalf:
800         /* Round down to the nearest even value.  */
801         srli    a2, a2, 1
802         slli    a2, a2, 1
803         j       .Lmul_rounded
805 .Lmul_overflow:
806         bltz    a8, .Lmul_underflow
807         /* Return +/- Infinity.  */
808         movi    a8, 0xff
809         slli    a2, a8, 23
810         j       .Lmul_addsign
812 .Lmul_underflow:
813         /* Create a subnormal value, where the exponent field contains zero,
814            but the effective exponent is 1.  The value of a8 is one less than
815            the actual exponent, so just negate it to get the shift amount.  */
816         neg     a8, a8
817         mov     a9, a6
818         ssr     a8
819         bgeui   a8, 32, .Lmul_flush_to_zero
820         
821         /* Shift a2 right.  Any bits that are shifted out of a2 are saved
822            in a6 (combined with the shifted-out bits currently in a6) for
823            rounding the result.  */
824         sll     a6, a2
825         srl     a2, a2
827         /* Set the exponent to zero.  */
828         movi    a8, 0
830         /* Pack any nonzero bits shifted out into a6.  */
831         beqz    a9, .Lmul_round
832         movi    a9, 1
833         or      a6, a6, a9
834         j       .Lmul_round
835         
836 .Lmul_flush_to_zero:
837         /* Return zero with the appropriate sign bit.  */
838         srli    a2, a7, 31
839         slli    a2, a2, 31
840         j       .Lmul_done
842 #if XCHAL_NO_MUL
843         
844         /* For Xtensa processors with no multiply hardware, this simplified
845            version of _mulsi3 is used for multiplying 16-bit chunks of
846            the floating-point mantissas.  When using CALL0, this function
847            uses a custom ABI: the inputs are passed in a13 and a14, the
848            result is returned in a12, and a8 and a15 are clobbered.  */
849         .align  4
850 .Lmul_mulsi3:
851         leaf_entry sp, 16
852         .macro mul_mulsi3_body dst, src1, src2, tmp1, tmp2
853         movi    \dst, 0
854 1:      add     \tmp1, \src2, \dst
855         extui   \tmp2, \src1, 0, 1
856         movnez  \dst, \tmp1, \tmp2
858         do_addx2 \tmp1, \src2, \dst, \tmp1
859         extui   \tmp2, \src1, 1, 1
860         movnez  \dst, \tmp1, \tmp2
862         do_addx4 \tmp1, \src2, \dst, \tmp1
863         extui   \tmp2, \src1, 2, 1
864         movnez  \dst, \tmp1, \tmp2
866         do_addx8 \tmp1, \src2, \dst, \tmp1
867         extui   \tmp2, \src1, 3, 1
868         movnez  \dst, \tmp1, \tmp2
870         srli    \src1, \src1, 4
871         slli    \src2, \src2, 4
872         bnez    \src1, 1b
873         .endm
874 #if __XTENSA_CALL0_ABI__
875         mul_mulsi3_body a12, a13, a14, a15, a8
876 #else
877         /* The result will be written into a2, so save that argument in a4.  */
878         mov     a4, a2
879         mul_mulsi3_body a2, a4, a3, a5, a6
880 #endif
881         leaf_return
882 #endif /* XCHAL_NO_MUL */
883 #endif /* L_mulsf3 */
885 #ifdef L_divsf3
887         /* Division */
888 __divsf3_aux:
890         /* Handle unusual cases (zeros, subnormals, NaNs and Infinities).
891            (This code is placed before the start of the function just to
892            keep it in range of the limited branch displacements.)  */
894 .Ldiv_yexpzero:
895         /* Clear the sign bit of y.  */
896         slli    a3, a3, 1
897         srli    a3, a3, 1
899         /* Check for division by zero.  */
900         beqz    a3, .Ldiv_yzero
902         /* Normalize y.  Adjust the exponent in a9.  */
903         do_nsau a10, a3, a4, a5
904         addi    a10, a10, -8
905         ssl     a10
906         sll     a3, a3
907         movi    a9, 1
908         sub     a9, a9, a10
909         j       .Ldiv_ynormalized       
911 .Ldiv_yzero:
912         /* y is zero.  Return NaN if x is also zero; otherwise, infinity.  */
913         slli    a4, a2, 1
914         srli    a4, a4, 1
915         srli    a2, a7, 31
916         slli    a2, a2, 31
917         or      a2, a2, a6
918         bnez    a4, 1f
919         movi    a4, 0x400000    /* make it a quiet NaN */
920         or      a2, a2, a4
921 1:      leaf_return
923 .Ldiv_xexpzero:
924         /* Clear the sign bit of x.  */
925         slli    a2, a2, 1
926         srli    a2, a2, 1
928         /* If x is zero, return zero.  */
929         beqz    a2, .Ldiv_return_zero
931         /* Normalize x.  Adjust the exponent in a8.  */
932         do_nsau a10, a2, a4, a5
933         addi    a10, a10, -8
934         ssl     a10
935         sll     a2, a2
936         movi    a8, 1
937         sub     a8, a8, a10
938         j       .Ldiv_xnormalized       
939         
940 .Ldiv_return_zero:
941         /* Return zero with the appropriate sign bit.  */
942         srli    a2, a7, 31
943         slli    a2, a2, 31
944         leaf_return
946 .Ldiv_xnan_or_inf:
947         /* Set the sign bit of the result.  */
948         srli    a7, a3, 31
949         slli    a7, a7, 31
950         xor     a2, a2, a7
951         /* If y is NaN or Inf, return NaN.  */
952         bnall   a3, a6, 1f
953         movi    a4, 0x400000    /* make it a quiet NaN */
954         or      a2, a2, a4
955 1:      leaf_return
957 .Ldiv_ynan_or_inf:
958         /* If y is Infinity, return zero.  */
959         slli    a8, a3, 9
960         beqz    a8, .Ldiv_return_zero
961         /* y is NaN; return it.  */
962         mov     a2, a3
963         leaf_return
965         .align  4
966         .global __divsf3
967         .type   __divsf3, @function
968 __divsf3:
969         leaf_entry sp, 16
970         movi    a6, 0x7f800000
972         /* Get the sign of the result.  */
973         xor     a7, a2, a3
975         /* Check for NaN and infinity.  */
976         ball    a2, a6, .Ldiv_xnan_or_inf
977         ball    a3, a6, .Ldiv_ynan_or_inf
979         /* Extract the exponents.  */
980         extui   a8, a2, 23, 8
981         extui   a9, a3, 23, 8
983         beqz    a9, .Ldiv_yexpzero
984 .Ldiv_ynormalized:      
985         beqz    a8, .Ldiv_xexpzero
986 .Ldiv_xnormalized:      
988         /* Subtract the exponents.  */
989         sub     a8, a8, a9
991         /* Replace sign/exponent fields with explicit "1.0".  */
992         movi    a10, 0xffffff
993         or      a2, a2, a6
994         and     a2, a2, a10
995         or      a3, a3, a6
996         and     a3, a3, a10
998         /* The first digit of the mantissa division must be a one.
999            Shift x (and adjust the exponent) as needed to make this true.  */
1000         bltu    a3, a2, 1f
1001         slli    a2, a2, 1
1002         addi    a8, a8, -1
1004         /* Do the first subtraction and shift.  */
1005         sub     a2, a2, a3
1006         slli    a2, a2, 1
1008         /* Put the quotient into a10.  */
1009         movi    a10, 1
1011         /* Divide one bit at a time for 23 bits.  */
1012         movi    a9, 23
1013 #if XCHAL_HAVE_LOOPS
1014         loop    a9, .Ldiv_loopend
1015 #endif
1016 .Ldiv_loop:
1017         /* Shift the quotient << 1.  */
1018         slli    a10, a10, 1
1020         /* Is this digit a 0 or 1?  */
1021         bltu    a2, a3, 1f
1023         /* Output a 1 and subtract.  */
1024         addi    a10, a10, 1
1025         sub     a2, a2, a3
1027         /* Shift the dividend << 1.  */
1028 1:      slli    a2, a2, 1
1030 #if !XCHAL_HAVE_LOOPS
1031         addi    a9, a9, -1
1032         bnez    a9, .Ldiv_loop
1033 #endif
1034 .Ldiv_loopend:
1036         /* Add the exponent bias (less one to account for the explicit "1.0"
1037            of the mantissa that will be added to the exponent in the final
1038            result).  */
1039         addi    a8, a8, 0x7e
1040         
1041         /* Check for over/underflow.  The value in a8 is one less than the
1042            final exponent, so values in the range 0..fd are OK here.  */
1043         movi    a4, 0xfe
1044         bgeu    a8, a4, .Ldiv_overflow
1045         
1046 .Ldiv_round:
1047         /* Round.  The remainder (<< 1) is in a2.  */
1048         bltu    a2, a3, .Ldiv_rounded
1049         addi    a10, a10, 1
1050         beq     a2, a3, .Ldiv_exactlyhalf
1052 .Ldiv_rounded:
1053         /* Add the exponent to the mantissa.  */
1054         slli    a8, a8, 23
1055         add     a2, a10, a8
1057 .Ldiv_addsign:
1058         /* Add the sign bit.  */
1059         srli    a7, a7, 31
1060         slli    a7, a7, 31
1061         or      a2, a2, a7
1062         leaf_return
1064 .Ldiv_overflow:
1065         bltz    a8, .Ldiv_underflow
1066         /* Return +/- Infinity.  */
1067         addi    a8, a4, 1       /* 0xff */
1068         slli    a2, a8, 23
1069         j       .Ldiv_addsign
1071 .Ldiv_exactlyhalf:
1072         /* Remainder is exactly half the divisor.  Round even.  */
1073         srli    a10, a10, 1
1074         slli    a10, a10, 1
1075         j       .Ldiv_rounded
1077 .Ldiv_underflow:
1078         /* Create a subnormal value, where the exponent field contains zero,
1079            but the effective exponent is 1.  The value of a8 is one less than
1080            the actual exponent, so just negate it to get the shift amount.  */
1081         neg     a8, a8
1082         ssr     a8
1083         bgeui   a8, 32, .Ldiv_flush_to_zero
1084         
1085         /* Shift a10 right.  Any bits that are shifted out of a10 are
1086            saved in a6 for rounding the result.  */
1087         sll     a6, a10
1088         srl     a10, a10
1090         /* Set the exponent to zero.  */
1091         movi    a8, 0
1093         /* Pack any nonzero remainder (in a2) into a6.  */
1094         beqz    a2, 1f
1095         movi    a9, 1
1096         or      a6, a6, a9
1097         
1098         /* Round a10 based on the bits shifted out into a6.  */
1099 1:      bgez    a6, .Ldiv_rounded
1100         addi    a10, a10, 1
1101         slli    a6, a6, 1
1102         bnez    a6, .Ldiv_rounded
1103         srli    a10, a10, 1
1104         slli    a10, a10, 1
1105         j       .Ldiv_rounded
1107 .Ldiv_flush_to_zero:
1108         /* Return zero with the appropriate sign bit.  */
1109         srli    a2, a7, 31
1110         slli    a2, a2, 31
1111         leaf_return
1113 #endif /* L_divsf3 */
1115 #ifdef L_cmpsf2
1117         /* Equal and Not Equal */
1119         .align  4
1120         .global __eqsf2
1121         .global __nesf2
1122         .set    __nesf2, __eqsf2
1123         .type   __eqsf2, @function
1124 __eqsf2:
1125         leaf_entry sp, 16
1126         bne     a2, a3, 4f
1128         /* The values are equal but NaN != NaN.  Check the exponent.  */
1129         movi    a6, 0x7f800000
1130         ball    a2, a6, 3f
1132         /* Equal.  */
1133         movi    a2, 0
1134         leaf_return
1136         /* Not equal.  */
1137 2:      movi    a2, 1
1138         leaf_return
1140         /* Check if the mantissas are nonzero.  */
1141 3:      slli    a7, a2, 9
1142         j       5f
1144         /* Check if x and y are zero with different signs.  */
1145 4:      or      a7, a2, a3
1146         slli    a7, a7, 1
1148         /* Equal if a7 == 0, where a7 is either abs(x | y) or the mantissa
1149            or x when exponent(x) = 0x7f8 and x == y.  */
1150 5:      movi    a2, 0
1151         movi    a3, 1
1152         movnez  a2, a3, a7      
1153         leaf_return
1156         /* Greater Than */
1158         .align  4
1159         .global __gtsf2
1160         .type   __gtsf2, @function
1161 __gtsf2:
1162         leaf_entry sp, 16
1163         movi    a6, 0x7f800000
1164         ball    a2, a6, 2f
1165 1:      bnall   a3, a6, .Lle_cmp
1167         /* Check if y is a NaN.  */
1168         slli    a7, a3, 9
1169         beqz    a7, .Lle_cmp
1170         movi    a2, 0
1171         leaf_return
1173         /* Check if x is a NaN.  */
1174 2:      slli    a7, a2, 9
1175         beqz    a7, 1b
1176         movi    a2, 0
1177         leaf_return
1180         /* Less Than or Equal */
1182         .align  4
1183         .global __lesf2
1184         .type   __lesf2, @function
1185 __lesf2:
1186         leaf_entry sp, 16
1187         movi    a6, 0x7f800000
1188         ball    a2, a6, 2f
1189 1:      bnall   a3, a6, .Lle_cmp
1191         /* Check if y is a NaN.  */
1192         slli    a7, a3, 9
1193         beqz    a7, .Lle_cmp
1194         movi    a2, 1
1195         leaf_return
1197         /* Check if x is a NaN.  */
1198 2:      slli    a7, a2, 9
1199         beqz    a7, 1b
1200         movi    a2, 1
1201         leaf_return
1203 .Lle_cmp:
1204         /* Check if x and y have different signs.  */
1205         xor     a7, a2, a3
1206         bltz    a7, .Lle_diff_signs
1208         /* Check if x is negative.  */
1209         bltz    a2, .Lle_xneg
1211         /* Check if x <= y.  */
1212         bltu    a3, a2, 5f
1213 4:      movi    a2, 0
1214         leaf_return
1216 .Lle_xneg:
1217         /* Check if y <= x.  */
1218         bgeu    a2, a3, 4b
1219 5:      movi    a2, 1
1220         leaf_return
1222 .Lle_diff_signs:
1223         bltz    a2, 4b
1225         /* Check if both x and y are zero.  */
1226         or      a7, a2, a3
1227         slli    a7, a7, 1
1228         movi    a2, 1
1229         movi    a3, 0
1230         moveqz  a2, a3, a7
1231         leaf_return
1234         /* Greater Than or Equal */
1236         .align  4
1237         .global __gesf2
1238         .type   __gesf2, @function
1239 __gesf2:
1240         leaf_entry sp, 16
1241         movi    a6, 0x7f800000
1242         ball    a2, a6, 2f
1243 1:      bnall   a3, a6, .Llt_cmp
1245         /* Check if y is a NaN.  */
1246         slli    a7, a3, 9
1247         beqz    a7, .Llt_cmp
1248         movi    a2, -1
1249         leaf_return
1251         /* Check if x is a NaN.  */
1252 2:      slli    a7, a2, 9
1253         beqz    a7, 1b
1254         movi    a2, -1
1255         leaf_return
1258         /* Less Than */
1260         .align  4
1261         .global __ltsf2
1262         .type   __ltsf2, @function
1263 __ltsf2:
1264         leaf_entry sp, 16
1265         movi    a6, 0x7f800000
1266         ball    a2, a6, 2f
1267 1:      bnall   a3, a6, .Llt_cmp
1269         /* Check if y is a NaN.  */
1270         slli    a7, a3, 9
1271         beqz    a7, .Llt_cmp
1272         movi    a2, 0
1273         leaf_return
1275         /* Check if x is a NaN.  */
1276 2:      slli    a7, a2, 9
1277         beqz    a7, 1b
1278         movi    a2, 0
1279         leaf_return
1281 .Llt_cmp:
1282         /* Check if x and y have different signs.  */
1283         xor     a7, a2, a3
1284         bltz    a7, .Llt_diff_signs
1286         /* Check if x is negative.  */
1287         bltz    a2, .Llt_xneg
1289         /* Check if x < y.  */
1290         bgeu    a2, a3, 5f
1291 4:      movi    a2, -1
1292         leaf_return
1294 .Llt_xneg:
1295         /* Check if y < x.  */
1296         bltu    a3, a2, 4b
1297 5:      movi    a2, 0
1298         leaf_return
1300 .Llt_diff_signs:
1301         bgez    a2, 5b
1303         /* Check if both x and y are nonzero.  */
1304         or      a7, a2, a3
1305         slli    a7, a7, 1
1306         movi    a2, 0
1307         movi    a3, -1
1308         movnez  a2, a3, a7
1309         leaf_return
1312         /* Unordered */
1314         .align  4
1315         .global __unordsf2
1316         .type   __unordsf2, @function
1317 __unordsf2:
1318         leaf_entry sp, 16
1319         movi    a6, 0x7f800000
1320         ball    a2, a6, 3f
1321 1:      ball    a3, a6, 4f
1322 2:      movi    a2, 0
1323         leaf_return
1325 3:      slli    a7, a2, 9
1326         beqz    a7, 1b
1327         movi    a2, 1
1328         leaf_return
1330 4:      slli    a7, a3, 9
1331         beqz    a7, 2b
1332         movi    a2, 1
1333         leaf_return
1335 #endif /* L_cmpsf2 */
1337 #ifdef L_fixsfsi
1339         .align  4
1340         .global __fixsfsi
1341         .type   __fixsfsi, @function
1342 __fixsfsi:
1343         leaf_entry sp, 16
1345         /* Check for NaN and Infinity.  */
1346         movi    a6, 0x7f800000
1347         ball    a2, a6, .Lfixsfsi_nan_or_inf
1349         /* Extract the exponent and check if 0 < (exp - 0x7e) < 32.  */
1350         extui   a4, a2, 23, 8
1351         addi    a4, a4, -0x7e
1352         bgei    a4, 32, .Lfixsfsi_maxint
1353         blti    a4, 1, .Lfixsfsi_zero
1355         /* Add explicit "1.0" and shift << 8.  */
1356         or      a7, a2, a6
1357         slli    a5, a7, 8
1359         /* Shift back to the right, based on the exponent.  */
1360         ssl     a4              /* shift by 32 - a4 */
1361         srl     a5, a5
1363         /* Negate the result if sign != 0.  */
1364         neg     a2, a5
1365         movgez  a2, a5, a7
1366         leaf_return
1368 .Lfixsfsi_nan_or_inf:
1369         /* Handle Infinity and NaN.  */
1370         slli    a4, a2, 9
1371         beqz    a4, .Lfixsfsi_maxint
1373         /* Translate NaN to +maxint.  */
1374         movi    a2, 0
1376 .Lfixsfsi_maxint:
1377         slli    a4, a6, 8       /* 0x80000000 */
1378         addi    a5, a4, -1      /* 0x7fffffff */
1379         movgez  a4, a5, a2
1380         mov     a2, a4
1381         leaf_return
1383 .Lfixsfsi_zero:
1384         movi    a2, 0
1385         leaf_return
1387 #endif /* L_fixsfsi */
1389 #ifdef L_fixsfdi
1391         .align  4
1392         .global __fixsfdi
1393         .type   __fixsfdi, @function
1394 __fixsfdi:
1395         leaf_entry sp, 16
1397         /* Check for NaN and Infinity.  */
1398         movi    a6, 0x7f800000
1399         ball    a2, a6, .Lfixsfdi_nan_or_inf
1401         /* Extract the exponent and check if 0 < (exp - 0x7e) < 64.  */
1402         extui   a4, a2, 23, 8
1403         addi    a4, a4, -0x7e
1404         bgei    a4, 64, .Lfixsfdi_maxint
1405         blti    a4, 1, .Lfixsfdi_zero
1407         /* Add explicit "1.0" and shift << 8.  */
1408         or      a7, a2, a6
1409         slli    xh, a7, 8
1411         /* Shift back to the right, based on the exponent.  */
1412         ssl     a4              /* shift by 64 - a4 */
1413         bgei    a4, 32, .Lfixsfdi_smallshift
1414         srl     xl, xh
1415         movi    xh, 0
1417 .Lfixsfdi_shifted:      
1418         /* Negate the result if sign != 0.  */
1419         bgez    a7, 1f
1420         neg     xl, xl
1421         neg     xh, xh
1422         beqz    xl, 1f
1423         addi    xh, xh, -1
1424 1:      leaf_return
1426 .Lfixsfdi_smallshift:
1427         movi    xl, 0
1428         sll     xl, xh
1429         srl     xh, xh
1430         j       .Lfixsfdi_shifted
1432 .Lfixsfdi_nan_or_inf:
1433         /* Handle Infinity and NaN.  */
1434         slli    a4, a2, 9
1435         beqz    a4, .Lfixsfdi_maxint
1437         /* Translate NaN to +maxint.  */
1438         movi    a2, 0
1440 .Lfixsfdi_maxint:
1441         slli    a7, a6, 8       /* 0x80000000 */
1442         bgez    a2, 1f
1443         mov     xh, a7
1444         movi    xl, 0
1445         leaf_return
1447 1:      addi    xh, a7, -1      /* 0x7fffffff */
1448         movi    xl, -1
1449         leaf_return
1451 .Lfixsfdi_zero:
1452         movi    xh, 0
1453         movi    xl, 0
1454         leaf_return
1456 #endif /* L_fixsfdi */
1458 #ifdef L_fixunssfsi
1460         .align  4
1461         .global __fixunssfsi
1462         .type   __fixunssfsi, @function
1463 __fixunssfsi:
1464         leaf_entry sp, 16
1466         /* Check for NaN and Infinity.  */
1467         movi    a6, 0x7f800000
1468         ball    a2, a6, .Lfixunssfsi_nan_or_inf
1470         /* Extract the exponent and check if 0 <= (exp - 0x7f) < 32.  */
1471         extui   a4, a2, 23, 8
1472         addi    a4, a4, -0x7f
1473         bgei    a4, 32, .Lfixunssfsi_maxint
1474         bltz    a4, .Lfixunssfsi_zero
1476         /* Add explicit "1.0" and shift << 8.  */
1477         or      a7, a2, a6
1478         slli    a5, a7, 8
1480         /* Shift back to the right, based on the exponent.  */
1481         addi    a4, a4, 1
1482         beqi    a4, 32, .Lfixunssfsi_bigexp
1483         ssl     a4              /* shift by 32 - a4 */
1484         srl     a5, a5
1486         /* Negate the result if sign != 0.  */
1487         neg     a2, a5
1488         movgez  a2, a5, a7
1489         leaf_return
1491 .Lfixunssfsi_nan_or_inf:
1492         /* Handle Infinity and NaN.  */
1493         slli    a4, a2, 9
1494         beqz    a4, .Lfixunssfsi_maxint
1496         /* Translate NaN to 0xffffffff.  */
1497         movi    a2, -1
1498         leaf_return
1500 .Lfixunssfsi_maxint:
1501         slli    a4, a6, 8       /* 0x80000000 */
1502         movi    a5, -1          /* 0xffffffff */
1503         movgez  a4, a5, a2
1504         mov     a2, a4
1505         leaf_return
1507 .Lfixunssfsi_zero:
1508         movi    a2, 0
1509         leaf_return
1511 .Lfixunssfsi_bigexp:
1512         /* Handle unsigned maximum exponent case.  */
1513         bltz    a2, 1f
1514         mov     a2, a5          /* no shift needed */
1515         leaf_return
1517         /* Return 0x80000000 if negative.  */
1518 1:      slli    a2, a6, 8
1519         leaf_return
1521 #endif /* L_fixunssfsi */
1523 #ifdef L_fixunssfdi
1525         .align  4
1526         .global __fixunssfdi
1527         .type   __fixunssfdi, @function
1528 __fixunssfdi:
1529         leaf_entry sp, 16
1531         /* Check for NaN and Infinity.  */
1532         movi    a6, 0x7f800000
1533         ball    a2, a6, .Lfixunssfdi_nan_or_inf
1535         /* Extract the exponent and check if 0 <= (exp - 0x7f) < 64.  */
1536         extui   a4, a2, 23, 8
1537         addi    a4, a4, -0x7f
1538         bgei    a4, 64, .Lfixunssfdi_maxint
1539         bltz    a4, .Lfixunssfdi_zero
1541         /* Add explicit "1.0" and shift << 8.  */
1542         or      a7, a2, a6
1543         slli    xh, a7, 8
1545         /* Shift back to the right, based on the exponent.  */
1546         addi    a4, a4, 1
1547         beqi    a4, 64, .Lfixunssfdi_bigexp
1548         ssl     a4              /* shift by 64 - a4 */
1549         bgei    a4, 32, .Lfixunssfdi_smallshift
1550         srl     xl, xh
1551         movi    xh, 0
1553 .Lfixunssfdi_shifted:
1554         /* Negate the result if sign != 0.  */
1555         bgez    a7, 1f
1556         neg     xl, xl
1557         neg     xh, xh
1558         beqz    xl, 1f
1559         addi    xh, xh, -1
1560 1:      leaf_return
1562 .Lfixunssfdi_smallshift:
1563         movi    xl, 0
1564         src     xl, xh, xl
1565         srl     xh, xh
1566         j       .Lfixunssfdi_shifted
1568 .Lfixunssfdi_nan_or_inf:
1569         /* Handle Infinity and NaN.  */
1570         slli    a4, a2, 9
1571         beqz    a4, .Lfixunssfdi_maxint
1573         /* Translate NaN to 0xffffffff.... */
1574 1:      movi    xh, -1
1575         movi    xl, -1
1576         leaf_return
1578 .Lfixunssfdi_maxint:
1579         bgez    a2, 1b
1580 2:      slli    xh, a6, 8       /* 0x80000000 */
1581         movi    xl, 0
1582         leaf_return
1584 .Lfixunssfdi_zero:
1585         movi    xh, 0
1586         movi    xl, 0
1587         leaf_return
1589 .Lfixunssfdi_bigexp:
1590         /* Handle unsigned maximum exponent case.  */
1591         bltz    a7, 2b
1592         movi    xl, 0
1593         leaf_return             /* no shift needed */
1595 #endif /* L_fixunssfdi */
1597 #ifdef L_floatsisf
1599         .align  4
1600         .global __floatunsisf
1601         .type   __floatunsisf, @function
1602 __floatunsisf:
1603         leaf_entry sp, 16
1604         beqz    a2, .Lfloatsisf_return
1606         /* Set the sign to zero and jump to the floatsisf code.  */
1607         movi    a7, 0
1608         j       .Lfloatsisf_normalize
1610         .align  4
1611         .global __floatsisf
1612         .type   __floatsisf, @function
1613 __floatsisf:
1614         leaf_entry sp, 16
1616         /* Check for zero.  */
1617         beqz    a2, .Lfloatsisf_return
1619         /* Save the sign.  */
1620         extui   a7, a2, 31, 1
1622         /* Get the absolute value.  */
1623 #if XCHAL_HAVE_ABS
1624         abs     a2, a2
1625 #else
1626         neg     a4, a2
1627         movltz  a2, a4, a2
1628 #endif
1630 .Lfloatsisf_normalize:
1631         /* Normalize with the first 1 bit in the msb.  */
1632         do_nsau a4, a2, a5, a6
1633         ssl     a4
1634         sll     a5, a2
1636         /* Shift the mantissa into position, with rounding bits in a6.  */
1637         srli    a2, a5, 8
1638         slli    a6, a5, (32 - 8)
1640         /* Set the exponent.  */
1641         movi    a5, 0x9d        /* 0x7e + 31 */
1642         sub     a5, a5, a4
1643         slli    a5, a5, 23
1644         add     a2, a2, a5
1646         /* Add the sign.  */
1647         slli    a7, a7, 31
1648         or      a2, a2, a7
1650         /* Round up if the leftover fraction is >= 1/2.  */
1651         bgez    a6, .Lfloatsisf_return
1652         addi    a2, a2, 1       /* Overflow to the exponent is OK.  */
1654         /* Check if the leftover fraction is exactly 1/2.  */
1655         slli    a6, a6, 1
1656         beqz    a6, .Lfloatsisf_exactlyhalf
1658 .Lfloatsisf_return:
1659         leaf_return
1661 .Lfloatsisf_exactlyhalf:
1662         /* Round down to the nearest even value.  */
1663         srli    a2, a2, 1
1664         slli    a2, a2, 1
1665         leaf_return
1667 #endif /* L_floatsisf */
1669 #ifdef L_floatdisf
1671         .align  4
1672         .global __floatundisf
1673         .type   __floatundisf, @function
1674 __floatundisf:
1675         leaf_entry sp, 16
1677         /* Check for zero.  */
1678         or      a4, xh, xl
1679         beqz    a4, 2f
1681         /* Set the sign to zero and jump to the floatdisf code.  */
1682         movi    a7, 0
1683         j       .Lfloatdisf_normalize
1685         .align  4
1686         .global __floatdisf
1687         .type   __floatdisf, @function
1688 __floatdisf:
1689         leaf_entry sp, 16
1691         /* Check for zero.  */
1692         or      a4, xh, xl
1693         beqz    a4, 2f
1695         /* Save the sign.  */
1696         extui   a7, xh, 31, 1
1698         /* Get the absolute value.  */
1699         bgez    xh, .Lfloatdisf_normalize
1700         neg     xl, xl
1701         neg     xh, xh
1702         beqz    xl, .Lfloatdisf_normalize
1703         addi    xh, xh, -1
1705 .Lfloatdisf_normalize:
1706         /* Normalize with the first 1 bit in the msb of xh.  */
1707         beqz    xh, .Lfloatdisf_bigshift
1708         do_nsau a4, xh, a5, a6
1709         ssl     a4
1710         src     xh, xh, xl
1711         sll     xl, xl
1713 .Lfloatdisf_shifted:
1714         /* Shift the mantissa into position, with rounding bits in a6.  */
1715         ssai    8
1716         sll     a5, xl
1717         src     a6, xh, xl
1718         srl     xh, xh
1719         beqz    a5, 1f
1720         movi    a5, 1
1721         or      a6, a6, a5
1723         /* Set the exponent.  */
1724         movi    a5, 0xbd        /* 0x7e + 63 */
1725         sub     a5, a5, a4
1726         slli    a5, a5, 23
1727         add     a2, xh, a5
1729         /* Add the sign.  */
1730         slli    a7, a7, 31
1731         or      a2, a2, a7
1733         /* Round up if the leftover fraction is >= 1/2.  */
1734         bgez    a6, 2f
1735         addi    a2, a2, 1       /* Overflow to the exponent is OK.  */
1737         /* Check if the leftover fraction is exactly 1/2.  */
1738         slli    a6, a6, 1
1739         beqz    a6, .Lfloatdisf_exactlyhalf
1740 2:      leaf_return
1742 .Lfloatdisf_bigshift:
1743         /* xh is zero.  Normalize with first 1 bit of xl in the msb of xh.  */
1744         do_nsau a4, xl, a5, a6
1745         ssl     a4
1746         sll     xh, xl
1747         movi    xl, 0
1748         addi    a4, a4, 32
1749         j       .Lfloatdisf_shifted
1751 .Lfloatdisf_exactlyhalf:
1752         /* Round down to the nearest even value.  */
1753         srli    a2, a2, 1
1754         slli    a2, a2, 1
1755         leaf_return
1757 #endif /* L_floatdisf */