1 /* IEEE-754 double-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)
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
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. */
52 .type __negdf2, @function
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.) */
71 /* If y is neither Infinity nor NaN, return x. */
73 /* If x is a NaN, return it. Otherwise, return y. */
76 beqz a7, .Ladd_ynan_or_inf
86 /* Operand signs differ. Do a subtraction. */
93 .type __adddf3, @function
98 /* Check if the two operands have the same sign. */
100 bltz a7, .Ladd_opposite_signs
103 /* Check if either exponent == 0x7ff (i.e., NaN or Infinity). */
104 ball xh, a6, .Ladd_xnan_or_inf
105 ball yh, a6, .Ladd_ynan_or_inf
107 /* Compare the exponents. The smaller operand will be shifted
108 right by the exponent difference and added to the larger
112 bltu a7, a8, .Ladd_shiftx
115 /* Check if the smaller (or equal) exponent is zero. */
116 bnone yh, a6, .Ladd_yexpzero
118 /* Replace yh sign/exponent with 0x001. */
124 /* Compute the exponent difference. Optimize for difference < 32. */
126 bgeui a10, 32, .Ladd_bigshifty
128 /* Shift yh/yl right by the exponent difference. Any bits that are
129 shifted out of yl are saved in a9 for rounding the result. */
137 /* Do the 64-bit addition. */
143 /* Check if the add overflowed into the exponent. */
144 extui a10, xh, 20, 12
145 beq a10, a7, .Ladd_round
150 /* y is a subnormal value. Replace its sign/exponent with zero,
151 i.e., no implicit "1.0", and increment the apparent exponent
152 because subnormals behave as if they had the minimum (nonzero)
153 exponent. Test for the case when both exponents are zero. */
156 bnone xh, a6, .Ladd_bothexpzero
161 /* Both exponents are zero. Handle this as a special case. There
162 is no need to shift or round, and the normal code for handling
163 a carry into the exponent field will not work because it
164 assumes there is an implicit "1.0" that needs to be added. */
172 /* Exponent difference > 64 -- just return the bigger value. */
175 /* Shift yh/yl right by the exponent difference. Any bits that are
176 shifted out are saved in a9 for rounding the result. */
178 sll a11, yl /* lost bits shifted out of yl */
183 or a9, a9, a10 /* any positive, nonzero value will work */
187 /* Same as "yexpzero" except skip handling the case when both
188 exponents are zero. */
195 /* Same thing as the "shifty" code, but with x and y swapped. Also,
196 because the exponent difference is always nonzero in this version,
197 the shift sequence can use SLL and skip loading a constant zero. */
198 bnone xh, a6, .Ladd_xexpzero
206 bgeui a10, 32, .Ladd_bigshiftx
219 /* Check if the add overflowed into the exponent. */
220 extui a10, xh, 20, 12
221 bne a10, a8, .Ladd_carry
224 /* Round up if the leftover fraction is >= 1/2. */
227 beqz xl, .Ladd_roundcarry
229 /* Check if the leftover fraction is exactly 1/2. */
231 beqz a9, .Ladd_exactlyhalf
235 /* Mostly the same thing as "bigshifty".... */
236 bgeui a10, 64, .Ladd_returny
253 /* The addition has overflowed into the exponent field, so the
254 value needs to be renormalized. The mantissa of the result
255 can be recovered by subtracting the original exponent and
256 adding 0x100000 (which is the explicit "1.0" for the
257 mantissa of the non-shifted operand -- the "1.0" for the
258 shifted operand was already added). The mantissa can then
259 be shifted right by one bit. The explicit "1.0" of the
260 shifted mantissa then needs to be replaced by the exponent,
261 incremented by one to account for the normalizing shift.
262 It is faster to combine these operations: do the shift first
263 and combine the additions and subtractions. If x is the
264 original exponent, the result is:
265 shifted mantissa - (x << 19) + (1 << 19) + (x << 20)
267 shifted mantissa + ((x + 1) << 19)
268 Note that the exponent is incremented here by leaving the
269 explicit "1.0" of the mantissa in the exponent field. */
271 /* Shift xh/xl right by one bit. Save the lsb of xl. */
277 /* See explanation above. The original exponent is in a8. */
282 /* Return an Infinity if the exponent overflowed. */
283 ball xh, a6, .Ladd_infinity
285 /* Same thing as the "round" code except the msb of the leftover
286 fraction is bit 0 of a10, with the rest of the fraction in a9. */
289 beqz xl, .Ladd_roundcarry
290 beqz a9, .Ladd_exactlyhalf
294 /* Clear the mantissa. */
299 /* The sign bit may have been lost in a carry-out. Put it back. */
305 /* Round down to the nearest even value. */
311 /* xl is always zero when the rounding increment overflows, so
312 there's no need to round it to an even value. */
314 /* Overflow to the exponent is OK. */
321 /* Handle NaNs and Infinities. (This code is placed before the
322 start of the function just to keep it in range of the limited
323 branch displacements.) */
326 /* If y is neither Infinity nor NaN, return x. */
328 /* Both x and y are either NaN or Inf, so the result is NaN. */
329 movi a4, 0x80000 /* make it a quiet NaN */
334 /* Negate y and return it. */
340 .Lsub_opposite_signs:
341 /* Operand signs differ. Do an addition. */
348 .type __subdf3, @function
353 /* Check if the two operands have the same sign. */
355 bltz a7, .Lsub_opposite_signs
358 /* Check if either exponent == 0x7ff (i.e., NaN or Infinity). */
359 ball xh, a6, .Lsub_xnan_or_inf
360 ball yh, a6, .Lsub_ynan_or_inf
362 /* Compare the operands. In contrast to addition, the entire
363 value matters here. */
366 bltu xh, yh, .Lsub_xsmaller
367 beq xh, yh, .Lsub_compare_low
370 /* Check if the smaller (or equal) exponent is zero. */
371 bnone yh, a6, .Lsub_yexpzero
373 /* Replace yh sign/exponent with 0x001. */
379 /* Compute the exponent difference. Optimize for difference < 32. */
381 bgeui a10, 32, .Lsub_bigshifty
383 /* Shift yh/yl right by the exponent difference. Any bits that are
384 shifted out of yl are saved in a9 for rounding the result. */
392 /* Do the 64-bit subtraction. */
398 /* Subtract the leftover bits in a9 from zero and propagate any
399 borrow from xh/xl. */
406 /* Check if the subtract underflowed into the exponent. */
407 extui a10, xh, 20, 11
408 beq a10, a7, .Lsub_round
412 /* The high words are equal. Compare the low words. */
413 bltu xl, yl, .Lsub_xsmaller
414 bltu yl, xl, .Lsub_ysmaller
415 /* The operands are equal. Return 0.0. */
421 /* y is a subnormal value. Replace its sign/exponent with zero,
422 i.e., no implicit "1.0". Unless x is also a subnormal, increment
423 y's apparent exponent because subnormals behave as if they had
424 the minimum (nonzero) exponent. */
427 bnone xh, a6, .Lsub_yexpdiff
432 /* Exponent difference > 64 -- just return the bigger value. */
435 /* Shift yh/yl right by the exponent difference. Any bits that are
436 shifted out are saved in a9 for rounding the result. */
438 sll a11, yl /* lost bits shifted out of yl */
443 or a9, a9, a10 /* any positive, nonzero value will work */
447 /* Same thing as the "ysmaller" code, but with x and y swapped and
449 bnone xh, a6, .Lsub_xexpzero
457 bgeui a10, 32, .Lsub_bigshiftx
475 /* Subtract the leftover bits in a9 from zero and propagate any
476 borrow from xh/xl. */
483 /* Check if the subtract underflowed into the exponent. */
484 extui a10, xh, 20, 11
485 bne a10, a8, .Lsub_borrow
488 /* Round up if the leftover fraction is >= 1/2. */
491 beqz xl, .Lsub_roundcarry
493 /* Check if the leftover fraction is exactly 1/2. */
495 beqz a9, .Lsub_exactlyhalf
499 /* Same as "yexpzero". */
502 bnone yh, a6, .Lsub_xexpdiff
507 /* Mostly the same thing as "bigshifty", but with the sign bit of the
508 shifted value set so that the subsequent subtraction flips the
510 bgeui a10, 64, .Lsub_returny
516 slli xh, a6, 11 /* set sign bit of xh */
522 /* Negate and return y. */
529 /* The subtraction has underflowed into the exponent field, so the
530 value needs to be renormalized. Shift the mantissa left as
531 needed to remove any leading zeros and adjust the exponent
532 accordingly. If the exponent is not large enough to remove
533 all the leading zeros, the result will be a subnormal value. */
536 beqz a8, .Lsub_xhzero
537 do_nsau a6, a8, a7, a11
539 bge a6, a10, .Lsub_subnormal
543 /* Shift the mantissa (a8/xl/a9) left by a6. */
549 /* Combine the shifted mantissa with the sign and exponent,
550 decrementing the exponent by a6. (The exponent has already
551 been decremented by one due to the borrow from the subtraction,
552 but adding the mantissa will increment the exponent by one.) */
560 /* Round down to the nearest even value. */
566 /* xl is always zero when the rounding increment overflows, so
567 there's no need to round it to an even value. */
569 /* Overflow to the exponent is OK. */
573 /* When normalizing the result, all the mantissa bits in the high
574 word are zero. Shift by "20 + (leading zero count of xl) + 1". */
575 do_nsau a6, xl, a7, a11
577 blt a10, a6, .Lsub_subnormal
579 .Lsub_normalize_shift:
580 bltui a6, 32, .Lsub_shift_lt32
594 /* The exponent is too small to shift away all the leading zeros.
595 Set a6 to the current exponent (which has already been
596 decremented by the borrow) so that the exponent of the result
597 will be zero. Do not add 1 to a6 in this case, because: (1)
598 adding the mantissa will not increment the exponent, so there is
599 no need to subtract anything extra from the exponent to
600 compensate, and (2) the effective exponent of a subnormal is 1
601 not 0 so the shift amount must be 1 smaller than normal. */
603 j .Lsub_normalize_shift
605 #endif /* L_addsubdf3 */
612 /* Handle unusual cases (zeros, subnormals, NaNs and Infinities).
613 (This code is placed before the start of the function just to
614 keep it in range of the limited branch displacements.) */
617 /* Clear the sign bit of x. */
621 /* If x is zero, return zero. */
623 beqz a10, .Lmul_return_zero
625 /* Normalize x. Adjust the exponent in a8. */
626 beqz xh, .Lmul_xh_zero
627 do_nsau a10, xh, a11, a12
636 do_nsau a10, xl, a11, a12
641 bltz a10, .Lmul_xl_srl
651 /* Clear the sign bit of y. */
655 /* If y is zero, return zero. */
657 beqz a10, .Lmul_return_zero
659 /* Normalize y. Adjust the exponent in a9. */
660 beqz yh, .Lmul_yh_zero
661 do_nsau a10, yh, a11, a12
670 do_nsau a10, yl, a11, a12
675 bltz a10, .Lmul_yl_srl
685 /* Return zero with the appropriate sign bit. */
692 /* If y is zero, return NaN. */
696 movi a4, 0x80000 /* make it a quiet NaN */
700 /* If y is NaN, return y. */
701 bnall yh, a6, .Lmul_returnx
704 beqz a8, .Lmul_returnx
711 /* Set the sign bit and return. */
719 /* If x is zero, return NaN. */
720 bnez xl, .Lmul_returny
722 bnez a8, .Lmul_returny
723 movi a7, 0x80000 /* make it a quiet NaN */
729 .type __muldf3, @function
732 #if __XTENSA_CALL0_ABI__
741 /* Get the sign of the result. */
744 /* Check for NaN and infinity. */
745 ball xh, a6, .Lmul_xnan_or_inf
746 ball yh, a6, .Lmul_ynan_or_inf
748 /* Extract the exponents. */
752 beqz a8, .Lmul_xexpzero
754 beqz a9, .Lmul_yexpzero
757 /* Add the exponents. */
760 /* Replace sign/exponent fields with explicit "1.0". */
767 /* Multiply 64x64 to 128 bits. The result ends up in xh/xl/a6.
768 The least-significant word of the result is thrown away except
769 that if it is nonzero, the lsb of a6 is set to 1. */
770 #if XCHAL_HAVE_MUL32_HIGH
772 /* Compute a6 with any carry-outs in a10. */
785 /* If the low word of the result is nonzero, set the lsb of a6. */
791 /* Compute xl with any carry-outs in a9. */
814 /* Break the inputs into 16-bit chunks and compute 16 32-bit partial
815 products. These partial products are:
840 where the input chunks are (hh, hl, lh, ll). If using the Mul16
841 or Mul32 multiplier options, these input chunks must be stored in
842 separate registers. For Mac16, the UMUL.AA.* opcodes can specify
843 that the inputs come from either half of the registers, so there
844 is no need to shift them out ahead of time. If there is no
845 multiply hardware, the 16-bit chunks can be extracted when setting
846 up the arguments to the separate multiply function. */
848 /* Save a7 since it is needed to hold a temporary value. */
850 #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
851 /* Calling a separate multiply function will clobber a0 and requires
852 use of a8 as a temporary, so save those values now. (The function
853 uses a custom ABI so nothing else needs to be saved.) */
858 #if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32
865 /* Get the high halves of the inputs into registers. */
876 #if XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MUL16
877 /* Clear the high halves of the inputs. This does not matter
878 for MUL16 because the high bits are ignored. */
884 #endif /* MUL16 || MUL32 */
889 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
890 mul16u dst, xreg ## xhalf, yreg ## yhalf
892 #elif XCHAL_HAVE_MUL32
894 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
895 mull dst, xreg ## xhalf, yreg ## yhalf
897 #elif XCHAL_HAVE_MAC16
899 /* The preprocessor insists on inserting a space when concatenating after
900 a period in the definition of do_mul below. These macros are a workaround
901 using underscores instead of periods when doing the concatenation. */
902 #define umul_aa_ll umul.aa.ll
903 #define umul_aa_lh umul.aa.lh
904 #define umul_aa_hl umul.aa.hl
905 #define umul_aa_hh umul.aa.hh
907 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
908 umul_aa_ ## xhalf ## yhalf xreg, yreg; \
911 #else /* no multiply hardware */
913 #define set_arg_l(dst, src) \
914 extui dst, src, 0, 16
915 #define set_arg_h(dst, src) \
918 #define do_mul(dst, xreg, xhalf, yreg, yhalf) \
919 set_arg_ ## xhalf (a13, xreg); \
920 set_arg_ ## yhalf (a14, yreg); \
921 call0 .Lmul_mulsi3; \
925 /* Add pp1 and pp2 into a10 with carry-out in a9. */
926 do_mul(a10, xl, l, yl, h) /* pp 1 */
927 do_mul(a11, xl, h, yl, l) /* pp 2 */
933 /* Initialize a6 with a9/a10 shifted into position. Note that
934 this value can be safely incremented without any carry-outs. */
938 /* Compute the low word into a10. */
939 do_mul(a11, xl, l, yl, l) /* pp 0 */
945 /* Compute the contributions of pp0-5 to a6, with carry-outs in a9.
946 This is good enough to determine the low half of a6, so that any
947 nonzero bits from the low word of the result can be collapsed
948 into a6, freeing up a register. */
950 do_mul(a11, xl, l, yh, l) /* pp 3 */
955 do_mul(a11, xl, h, yl, h) /* pp 4 */
960 do_mul(a11, xh, l, yl, l) /* pp 5 */
965 /* Collapse any nonzero bits from the low word into a6. */
970 /* Add pp6-9 into a11 with carry-outs in a10. */
971 do_mul(a7, xl, l, yh, h) /* pp 6 */
972 do_mul(a11, xh, h, yl, l) /* pp 9 */
978 do_mul(a7, xl, h, yh, l) /* pp 7 */
983 do_mul(a7, xh, l, yl, h) /* pp 8 */
988 /* Shift a10/a11 into position, and add low half of a11 to a6. */
996 /* Add pp10-12 into xl with carry-outs in a9. */
998 do_mul(xl, xl, h, yh, h) /* pp 10 */
1003 do_mul(a10, xh, l, yh, l) /* pp 11 */
1008 do_mul(a10, xh, h, yl, h) /* pp 12 */
1013 /* Add pp13-14 into a11 with carry-outs in a10. */
1014 do_mul(a11, xh, l, yh, h) /* pp 13 */
1015 do_mul(a7, xh, h, yh, l) /* pp 14 */
1021 /* Shift a10/a11 into position, and add low half of a11 to a6. */
1030 do_mul(xh, xh, h, yh, h) /* pp 15 */
1033 /* Restore values saved on the stack during the multiplication. */
1035 #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
1041 /* Shift left by 12 bits, unless there was a carry-out from the
1042 multiply, in which case, shift by 11 bits and increment the
1043 exponent. Note: It is convenient to use the constant 0x3ff
1044 instead of 0x400 when removing the extra exponent bias (so that
1045 it is easy to construct 0x7fe for the overflow check). Reverse
1046 the logic here to decrement the exponent sum by one unless there
1049 srli a5, xh, 21 - 12
1058 /* Subtract the extra bias from the exponent sum (plus one to account
1059 for the explicit "1.0" of the mantissa that will be added to the
1060 exponent in the final result). */
1064 /* Check for over/underflow. The value in a8 is one less than the
1065 final exponent, so values in the range 0..7fd are OK here. */
1066 slli a4, a4, 1 /* 0x7fe */
1067 bgeu a8, a4, .Lmul_overflow
1071 bgez a6, .Lmul_rounded
1073 beqz xl, .Lmul_roundcarry
1075 beqz a6, .Lmul_exactlyhalf
1078 /* Add the exponent to the mantissa. */
1083 /* Add the sign bit. */
1089 #if __XTENSA_CALL0_ABI__
1099 /* Round down to the nearest even value. */
1105 /* xl is always zero when the rounding increment overflows, so
1106 there's no need to round it to an even value. */
1108 /* Overflow is OK -- it will be added to the exponent. */
1112 bltz a8, .Lmul_underflow
1113 /* Return +/- Infinity. */
1114 addi a8, a4, 1 /* 0x7ff */
1120 /* Create a subnormal value, where the exponent field contains zero,
1121 but the effective exponent is 1. The value of a8 is one less than
1122 the actual exponent, so just negate it to get the shift amount. */
1126 bgeui a8, 32, .Lmul_bigshift
1128 /* Shift xh/xl right. Any bits that are shifted out of xl are saved
1129 in a6 (combined with the shifted-out bits currently in a6) for
1130 rounding the result. */
1137 bgeui a8, 64, .Lmul_flush_to_zero
1138 sll a10, xl /* lost bits shifted out of xl */
1144 /* Set the exponent to zero. */
1147 /* Pack any nonzero bits shifted out into a6. */
1148 beqz a9, .Lmul_round
1153 .Lmul_flush_to_zero:
1154 /* Return zero with the appropriate sign bit. */
1160 #if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
1162 /* For Xtensa processors with no multiply hardware, this simplified
1163 version of _mulsi3 is used for multiplying 16-bit chunks of
1164 the floating-point mantissas. It uses a custom ABI: the inputs
1165 are passed in a13 and a14, the result is returned in a12, and
1166 a8 and a15 are clobbered. */
1175 do_addx2 a15, a14, a12, a15
1179 do_addx4 a15, a14, a12, a15
1183 do_addx8 a15, a14, a12, a15
1189 bnez a13, .Lmul_mult_loop
1191 #endif /* !MUL16 && !MUL32 && !MAC16 */
1192 #endif /* L_muldf3 */
1199 /* Handle unusual cases (zeros, subnormals, NaNs and Infinities).
1200 (This code is placed before the start of the function just to
1201 keep it in range of the limited branch displacements.) */
1204 /* Clear the sign bit of y. */
1208 /* Check for division by zero. */
1210 beqz a10, .Ldiv_yzero
1212 /* Normalize y. Adjust the exponent in a9. */
1213 beqz yh, .Ldiv_yh_zero
1214 do_nsau a10, yh, a11, a9
1223 do_nsau a10, yl, a11, a9
1228 bltz a10, .Ldiv_yl_srl
1238 /* y is zero. Return NaN if x is also zero; otherwise, infinity. */
1246 movi a4, 0x80000 /* make it a quiet NaN */
1252 /* Clear the sign bit of x. */
1256 /* If x is zero, return zero. */
1258 beqz a10, .Ldiv_return_zero
1260 /* Normalize x. Adjust the exponent in a8. */
1261 beqz xh, .Ldiv_xh_zero
1262 do_nsau a10, xh, a11, a8
1271 do_nsau a10, xl, a11, a8
1276 bltz a10, .Ldiv_xl_srl
1286 /* Return zero with the appropriate sign bit. */
1293 /* Set the sign bit of the result. */
1297 /* If y is NaN or Inf, return NaN. */
1299 movi a4, 0x80000 /* make it a quiet NaN */
1304 /* If y is Infinity, return zero. */
1307 beqz a8, .Ldiv_return_zero
1308 /* y is NaN; return it. */
1319 .type __divdf3, @function
1324 /* Get the sign of the result. */
1327 /* Check for NaN and infinity. */
1328 ball xh, a6, .Ldiv_xnan_or_inf
1329 ball yh, a6, .Ldiv_ynan_or_inf
1331 /* Extract the exponents. */
1332 extui a8, xh, 20, 11
1333 extui a9, yh, 20, 11
1335 beqz a9, .Ldiv_yexpzero
1337 beqz a8, .Ldiv_xexpzero
1340 /* Subtract the exponents. */
1343 /* Replace sign/exponent fields with explicit "1.0". */
1350 /* Set SAR for left shift by one. */
1353 /* The first digit of the mantissa division must be a one.
1354 Shift x (and adjust the exponent) as needed to make this true. */
1356 beq yh, xh, .Ldiv_highequal1
1361 /* Do the first subtraction and shift. */
1369 /* Put the quotient into a10/a11. */
1373 /* Divide one bit at a time for 52 bits. */
1375 #if XCHAL_HAVE_LOOPS
1376 loop a9, .Ldiv_loopend
1379 /* Shift the quotient << 1. */
1383 /* Is this digit a 0 or 1? */
1385 beq xh, yh, .Ldiv_highequal2
1387 /* Output a 1 and subtract. */
1394 /* Shift the dividend << 1. */
1398 #if !XCHAL_HAVE_LOOPS
1404 /* Add the exponent bias (less one to account for the explicit "1.0"
1405 of the mantissa that will be added to the exponent in the final
1410 /* Check for over/underflow. The value in a8 is one less than the
1411 final exponent, so values in the range 0..7fd are OK here. */
1412 addmi a9, a9, 0x400 /* 0x7fe */
1413 bgeu a8, a9, .Ldiv_overflow
1416 /* Round. The remainder (<< 1) is in xh/xl. */
1417 bltu xh, yh, .Ldiv_rounded
1418 beq xh, yh, .Ldiv_highequal3
1421 beqz a11, .Ldiv_roundcarry
1425 /* Add the exponent to the mantissa. */
1430 /* Add the sign bit. */
1441 bltu xl, yl, .Ldiv_rounded
1442 bne xl, yl, .Ldiv_roundup
1444 /* Remainder is exactly half the divisor. Round even. */
1446 beqz a11, .Ldiv_roundcarry
1452 bltz a8, .Ldiv_underflow
1453 /* Return +/- Infinity. */
1454 addi a8, a9, 1 /* 0x7ff */
1460 /* Create a subnormal value, where the exponent field contains zero,
1461 but the effective exponent is 1. The value of a8 is one less than
1462 the actual exponent, so just negate it to get the shift amount. */
1465 bgeui a8, 32, .Ldiv_bigshift
1467 /* Shift a10/a11 right. Any bits that are shifted out of a11 are
1468 saved in a6 for rounding the result. */
1475 bgeui a8, 64, .Ldiv_flush_to_zero
1476 sll a9, a11 /* lost bits shifted out of a11 */
1482 /* Set the exponent to zero. */
1485 /* Pack any nonzero remainder (in xh/xl) into a6. */
1491 /* Round a10/a11 based on the bits shifted out into a6. */
1492 1: bgez a6, .Ldiv_rounded
1494 beqz a11, .Ldiv_roundcarry
1496 bnez a6, .Ldiv_rounded
1502 /* a11 is always zero when the rounding increment overflows, so
1503 there's no need to round it to an even value. */
1505 /* Overflow to the exponent field is OK. */
1508 .Ldiv_flush_to_zero:
1509 /* Return zero with the appropriate sign bit. */
1515 #endif /* L_divdf3 */
1519 /* Equal and Not Equal */
1524 .set __nedf2, __eqdf2
1525 .type __eqdf2, @function
1531 /* The values are equal but NaN != NaN. Check the exponent. */
1543 /* Check if the mantissas are nonzero. */
1548 /* Check if x and y are zero with different signs. */
1551 or a7, a7, xl /* xl == yl here */
1553 /* Equal if a7 == 0, where a7 is either abs(x | y) or the mantissa
1554 or x when exponent(x) = 0x7ff and x == y. */
1565 .type __gtdf2, @function
1570 1: bnall yh, a6, .Lle_cmp
1572 /* Check if y is a NaN. */
1579 /* Check if x is a NaN. */
1587 /* Less Than or Equal */
1591 .type __ledf2, @function
1596 1: bnall yh, a6, .Lle_cmp
1598 /* Check if y is a NaN. */
1605 /* Check if x is a NaN. */
1613 /* Check if x and y have different signs. */
1615 bltz a7, .Lle_diff_signs
1617 /* Check if x is negative. */
1620 /* Check if x <= y. */
1628 /* Check if y <= x. */
1638 /* Check if both x and y are zero. */
1649 /* Greater Than or Equal */
1653 .type __gedf2, @function
1658 1: bnall yh, a6, .Llt_cmp
1660 /* Check if y is a NaN. */
1667 /* Check if x is a NaN. */
1679 .type __ltdf2, @function
1684 1: bnall yh, a6, .Llt_cmp
1686 /* Check if y is a NaN. */
1693 /* Check if x is a NaN. */
1701 /* Check if x and y have different signs. */
1703 bltz a7, .Llt_diff_signs
1705 /* Check if x is negative. */
1708 /* Check if x < y. */
1716 /* Check if y < x. */
1726 /* Check if both x and y are nonzero. */
1741 .type __unorddf2, @function
1762 #endif /* L_cmpdf2 */
1768 .type __fixdfsi, @function
1772 /* Check for NaN and Infinity. */
1774 ball xh, a6, .Lfixdfsi_nan_or_inf
1776 /* Extract the exponent and check if 0 < (exp - 0x3fe) < 32. */
1777 extui a4, xh, 20, 11
1778 extui a5, a6, 19, 10 /* 0x3fe */
1780 bgei a4, 32, .Lfixdfsi_maxint
1781 blti a4, 1, .Lfixdfsi_zero
1783 /* Add explicit "1.0" and shift << 11. */
1788 /* Shift back to the right, based on the exponent. */
1789 ssl a4 /* shift by 32 - a4 */
1792 /* Negate the result if sign != 0. */
1797 .Lfixdfsi_nan_or_inf:
1798 /* Handle Infinity and NaN. */
1801 beqz a4, .Lfixdfsi_maxint
1803 /* Translate NaN to +maxint. */
1807 slli a4, a6, 11 /* 0x80000000 */
1808 addi a5, a4, -1 /* 0x7fffffff */
1817 #endif /* L_fixdfsi */
1823 .type __fixdfdi, @function
1827 /* Check for NaN and Infinity. */
1829 ball xh, a6, .Lfixdfdi_nan_or_inf
1831 /* Extract the exponent and check if 0 < (exp - 0x3fe) < 64. */
1832 extui a4, xh, 20, 11
1833 extui a5, a6, 19, 10 /* 0x3fe */
1835 bgei a4, 64, .Lfixdfdi_maxint
1836 blti a4, 1, .Lfixdfdi_zero
1838 /* Add explicit "1.0" and shift << 11. */
1844 /* Shift back to the right, based on the exponent. */
1845 ssl a4 /* shift by 64 - a4 */
1846 bgei a4, 32, .Lfixdfdi_smallshift
1851 /* Negate the result if sign != 0. */
1859 .Lfixdfdi_smallshift:
1864 .Lfixdfdi_nan_or_inf:
1865 /* Handle Infinity and NaN. */
1868 beqz a4, .Lfixdfdi_maxint
1870 /* Translate NaN to +maxint. */
1874 slli a7, a6, 11 /* 0x80000000 */
1880 1: addi xh, a7, -1 /* 0x7fffffff */
1889 #endif /* L_fixdfdi */
1894 .global __fixunsdfsi
1895 .type __fixunsdfsi, @function
1899 /* Check for NaN and Infinity. */
1901 ball xh, a6, .Lfixunsdfsi_nan_or_inf
1903 /* Extract the exponent and check if 0 <= (exp - 0x3ff) < 32. */
1904 extui a4, xh, 20, 11
1905 extui a5, a6, 20, 10 /* 0x3ff */
1907 bgei a4, 32, .Lfixunsdfsi_maxint
1908 bltz a4, .Lfixunsdfsi_zero
1910 /* Add explicit "1.0" and shift << 11. */
1915 /* Shift back to the right, based on the exponent. */
1917 beqi a4, 32, .Lfixunsdfsi_bigexp
1918 ssl a4 /* shift by 32 - a4 */
1921 /* Negate the result if sign != 0. */
1926 .Lfixunsdfsi_nan_or_inf:
1927 /* Handle Infinity and NaN. */
1930 beqz a4, .Lfixunsdfsi_maxint
1932 /* Translate NaN to 0xffffffff. */
1936 .Lfixunsdfsi_maxint:
1937 slli a4, a6, 11 /* 0x80000000 */
1938 movi a5, -1 /* 0xffffffff */
1947 .Lfixunsdfsi_bigexp:
1948 /* Handle unsigned maximum exponent case. */
1950 mov a2, a5 /* no shift needed */
1953 /* Return 0x80000000 if negative. */
1957 #endif /* L_fixunsdfsi */
1962 .global __fixunsdfdi
1963 .type __fixunsdfdi, @function
1967 /* Check for NaN and Infinity. */
1969 ball xh, a6, .Lfixunsdfdi_nan_or_inf
1971 /* Extract the exponent and check if 0 <= (exp - 0x3ff) < 64. */
1972 extui a4, xh, 20, 11
1973 extui a5, a6, 20, 10 /* 0x3ff */
1975 bgei a4, 64, .Lfixunsdfdi_maxint
1976 bltz a4, .Lfixunsdfdi_zero
1978 /* Add explicit "1.0" and shift << 11. */
1984 /* Shift back to the right, based on the exponent. */
1986 beqi a4, 64, .Lfixunsdfdi_bigexp
1987 ssl a4 /* shift by 64 - a4 */
1988 bgei a4, 32, .Lfixunsdfdi_smallshift
1992 .Lfixunsdfdi_shifted:
1993 /* Negate the result if sign != 0. */
2001 .Lfixunsdfdi_smallshift:
2004 j .Lfixunsdfdi_shifted
2006 .Lfixunsdfdi_nan_or_inf:
2007 /* Handle Infinity and NaN. */
2010 beqz a4, .Lfixunsdfdi_maxint
2012 /* Translate NaN to 0xffffffff.... */
2017 .Lfixunsdfdi_maxint:
2019 2: slli xh, a6, 11 /* 0x80000000 */
2028 .Lfixunsdfdi_bigexp:
2029 /* Handle unsigned maximum exponent case. */
2031 leaf_return /* no shift needed */
2033 #endif /* L_fixunsdfdi */
2038 .global __floatunsidf
2039 .type __floatunsidf, @function
2042 beqz a2, .Lfloatsidf_return_zero
2044 /* Set the sign to zero and jump to the floatsidf code. */
2046 j .Lfloatsidf_normalize
2050 .type __floatsidf, @function
2054 /* Check for zero. */
2055 beqz a2, .Lfloatsidf_return_zero
2057 /* Save the sign. */
2060 /* Get the absolute value. */
2068 .Lfloatsidf_normalize:
2069 /* Normalize with the first 1 bit in the msb. */
2070 do_nsau a4, a2, a5, a6
2074 /* Shift the mantissa into position. */
2076 slli xl, a5, (32 - 11)
2078 /* Set the exponent. */
2079 movi a5, 0x41d /* 0x3fe + 31 */
2084 /* Add the sign and return. */
2089 .Lfloatsidf_return_zero:
2093 #endif /* L_floatsidf */
2098 .global __floatundidf
2099 .type __floatundidf, @function
2103 /* Check for zero. */
2107 /* Set the sign to zero and jump to the floatdidf code. */
2109 j .Lfloatdidf_normalize
2113 .type __floatdidf, @function
2117 /* Check for zero. */
2121 /* Save the sign. */
2124 /* Get the absolute value. */
2125 bgez xh, .Lfloatdidf_normalize
2128 beqz xl, .Lfloatdidf_normalize
2131 .Lfloatdidf_normalize:
2132 /* Normalize with the first 1 bit in the msb of xh. */
2133 beqz xh, .Lfloatdidf_bigshift
2134 do_nsau a4, xh, a5, a6
2139 .Lfloatdidf_shifted:
2140 /* Shift the mantissa into position, with rounding bits in a6. */
2146 /* Set the exponent. */
2147 movi a5, 0x43d /* 0x3fe + 63 */
2156 /* Round up if the leftover fraction is >= 1/2. */
2159 beqz xl, .Lfloatdidf_roundcarry
2161 /* Check if the leftover fraction is exactly 1/2. */
2163 beqz a6, .Lfloatdidf_exactlyhalf
2166 .Lfloatdidf_bigshift:
2167 /* xh is zero. Normalize with first 1 bit of xl in the msb of xh. */
2168 do_nsau a4, xl, a5, a6
2173 j .Lfloatdidf_shifted
2175 .Lfloatdidf_exactlyhalf:
2176 /* Round down to the nearest even value. */
2181 .Lfloatdidf_roundcarry:
2182 /* xl is always zero when the rounding increment overflows, so
2183 there's no need to round it to an even value. */
2185 /* Overflow to the exponent is OK. */
2188 #endif /* L_floatdidf */
2193 .global __truncdfsf2
2194 .type __truncdfsf2, @function
2198 /* Adjust the exponent bias. */
2199 movi a4, (0x3ff - 0x7f) << 20
2202 /* Check for underflow. */
2204 bltz a6, .Ltrunc_underflow
2205 extui a6, a5, 20, 11
2206 beqz a6, .Ltrunc_underflow
2208 /* Check for overflow. */
2210 bge a6, a4, .Ltrunc_overflow
2212 /* Shift a5/xl << 3 into a5/a4. */
2218 /* Add the sign bit. */
2223 /* Round up if the leftover fraction is >= 1/2. */
2226 /* Overflow to the exponent is OK. The answer will be correct. */
2228 /* Check if the leftover fraction is exactly 1/2. */
2230 beqz a4, .Ltrunc_exactlyhalf
2233 .Ltrunc_exactlyhalf:
2234 /* Round down to the nearest even value. */
2240 /* Check if exponent == 0x7ff. */
2244 /* Check if mantissa is nonzero. */
2249 /* Shift a4 to set a bit in the mantissa, making a quiet NaN. */
2252 1: slli a4, a4, 4 /* 0xff000000 or 0xff800000 */
2253 /* Add the sign bit. */
2260 /* Find shift count for a subnormal. Flush to zero if >= 32. */
2261 extui a6, xh, 20, 11
2262 movi a5, 0x3ff - 0x7f
2267 /* Replace the exponent with an explicit "1.0". */
2268 slli a5, a5, 13 /* 0x700000 */
2273 /* Shift the mantissa left by 3 bits (into a5/a4). */
2278 /* Shift right by a6. */
2283 beqz a7, .Ltrunc_addsign
2284 or a4, a4, a6 /* any positive, nonzero value will work */
2287 /* Return +/- zero. */
2288 1: extui a2, xh, 31, 1
2292 #endif /* L_truncdfsf2 */
2294 #ifdef L_extendsfdf2
2297 .global __extendsfdf2
2298 .type __extendsfdf2, @function
2302 /* Save the sign bit and then shift it off. */
2307 /* Extract and check the exponent. */
2309 beqz a6, .Lextend_expzero
2311 beqi a6, 256, .Lextend_nan_or_inf
2313 /* Shift >> 3 into a4/xl. */
2315 slli xl, a2, (32 - 3)
2317 /* Adjust the exponent bias. */
2318 movi a6, (0x3ff - 0x7f) << 20
2321 /* Add the sign bit. */
2325 .Lextend_nan_or_inf:
2328 /* Check for NaN. */
2332 slli a6, a6, 11 /* 0x80000 */
2335 /* Add the sign and return. */
2343 /* Normalize it to have 8 zero bits before the first 1 bit. */
2344 do_nsau a7, a4, a2, a3
2349 /* Shift >> 3 into a4/xl. */
2350 slli xl, a4, (32 - 3)
2353 /* Set the exponent. */
2354 movi a6, 0x3fe - 0x7f
2359 /* Add the sign and return. */
2363 #endif /* L_extendsfdf2 */