1 /*===-- addsf3.S - Adds two single precision floating pointer numbers-----===//
3 * The LLVM Compiler Infrastructure
5 * This file is dual licensed under the MIT and the University of Illinois Open
6 * Source Licenses. See LICENSE.TXT for details.
8 *===----------------------------------------------------------------------===//
10 * This file implements the __addsf3 (single precision floating pointer number
11 * addition with the IEEE-754 default rounding (to nearest, ties to even)
12 * function for the ARM Thumb1 ISA.
14 *===----------------------------------------------------------------------===*/
16 #include "../assembly.h"
17 #define significandBits 23
25 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fadd, __addsf3)
27 DEFINE_COMPILERRT_THUMB_FUNCTION(__addsf3)
28 push {r4, r5, r6, r7, lr}
29 // Get the absolute value of a and b.
32 lsrs r2, r2, #1 /* aAbs */
33 beq LOCAL_LABEL(a_zero_nan_inf)
34 lsrs r3, r3, #1 /* bAbs */
35 beq LOCAL_LABEL(zero_nan_inf)
37 // Detect if a or b is infinity or Nan.
38 lsrs r6, r2, #(significandBits)
39 lsrs r7, r3, #(significandBits)
41 beq LOCAL_LABEL(zero_nan_inf)
43 beq LOCAL_LABEL(zero_nan_inf)
45 // Swap Rep and Abs so that a and aAbs has the larger absolute value.
47 bhs LOCAL_LABEL(no_swap)
56 // Get the significands and shift them to give us round, guard and sticky.
57 lsls r4, r0, #(typeWidth - significandBits)
58 lsrs r4, r4, #(typeWidth - significandBits - 3) /* aSignificand << 3 */
59 lsls r5, r1, #(typeWidth - significandBits)
60 lsrs r5, r5, #(typeWidth - significandBits - 3) /* bSignificand << 3 */
62 // Get the implicitBit.
64 lsls r6, r6, #(significandBits + 3)
66 // Get aExponent and set implicit bit if necessary.
67 lsrs r2, r2, #(significandBits)
68 beq LOCAL_LABEL(a_done_implicit_bit)
70 LOCAL_LABEL(a_done_implicit_bit):
72 // Get bExponent and set implicit bit if necessary.
73 lsrs r3, r3, #(significandBits)
74 beq LOCAL_LABEL(b_done_implicit_bit)
76 LOCAL_LABEL(b_done_implicit_bit):
78 // Get the difference in exponents.
80 beq LOCAL_LABEL(done_align)
82 // If b is denormal, then a must be normal as align > 0, and we only need to
83 // right shift bSignificand by (align - 1) bits.
89 // No longer needs bExponent. r3 is dead here.
90 // Set sticky bits of b: sticky = bSignificand << (typeWidth - align).
99 // bSignificand = bSignificand >> align | sticky;
102 bne LOCAL_LABEL(done_align)
103 movs r5, #1 // sticky; b is known to be non-zero.
105 LOCAL_LABEL(done_align):
106 // isSubtraction = (aRep ^ bRep) >> 31;
110 bne LOCAL_LABEL(do_substraction)
112 // Same sign, do Addition.
114 // aSignificand += bSignificand;
119 lsls r6, r6, #(significandBits + 3 + 1)
122 beq LOCAL_LABEL(form_result)
123 // If the addition carried up, we need to right-shift the result and
124 // adjust the exponent.
127 ands r7, r6 // sticky = aSignificand & 1;
129 orrs r4, r7 // result Significand
130 adds r2, #1 // result Exponent
131 // If we have overflowed the type, return +/- infinity.
133 beq LOCAL_LABEL(ret_inf)
135 LOCAL_LABEL(form_result):
136 // Shift the sign, exponent and significand into place.
137 lsrs r0, #(typeWidth - 1)
138 lsls r0, #(typeWidth - 1) // Get Sign.
139 lsls r2, #(significandBits)
142 lsls r4, #(typeWidth - significandBits - 3)
143 lsrs r4, #(typeWidth - significandBits)
146 // Final rounding. The result may overflow to infinity, but that is the
147 // correct result in that case.
148 // roundGuardSticky = aSignificand & 0x7;
151 // if (roundGuardSticky > 0x4) result++;
154 blt LOCAL_LABEL(done_round)
157 pop {r4, r5, r6, r7, pc}
160 // if (roundGuardSticky == 0x4) result += result & 1;
163 bcc LOCAL_LABEL(done_round)
165 LOCAL_LABEL(done_round):
166 pop {r4, r5, r6, r7, pc}
168 LOCAL_LABEL(do_substraction):
169 subs r4, r4, r5 // aSignificand -= bSignificand;
170 beq LOCAL_LABEL(ret_zero)
173 beq LOCAL_LABEL(form_result) // if a's exp is 0, no need to normalize.
174 // If partial cancellation occured, we need to left-shift the result
175 // and adjust the exponent:
176 lsrs r6, r6, #(significandBits + 3)
177 bne LOCAL_LABEL(form_result)
179 push {r0, r1, r2, r3}
181 bl SYMBOL_NAME(__clzsi2)
184 // shift = rep_clz(aSignificand) - rep_clz(implicitBit << 3);
185 subs r5, r5, #(typeWidth - significandBits - 3 - 1)
186 // aSignificand <<= shift; aExponent -= shift;
189 bgt LOCAL_LABEL(form_result)
191 // Do normalization if aExponent <= 0.
193 subs r6, r6, r2 // 1 - aExponent;
194 movs r2, #0 // aExponent = 0;
195 movs r3, #(typeWidth) // bExponent is dead.
198 lsls r7, r3 // stickyBit = (bool)(aSignificant << (typeWidth - align))
202 lsrs r4, r6 /* aSignificand >> shift */
204 b LOCAL_LABEL(form_result)
206 LOCAL_LABEL(ret_zero):
208 pop {r4, r5, r6, r7, pc}
211 LOCAL_LABEL(a_zero_nan_inf):
214 LOCAL_LABEL(zero_nan_inf):
215 // Here r2 has aAbs, r3 has bAbs
217 lsls r4, r4, #(significandBits) // Make +inf.
220 bhi LOCAL_LABEL(a_is_nan)
222 bhi LOCAL_LABEL(b_is_nan)
225 bne LOCAL_LABEL(a_is_rational)
227 eors r1, r0 // aRep ^ bRep.
229 lsls r6, r6, #(typeWidth - 1) // get sign mask.
230 cmp r1, r6 // if they only differ on sign bit, it's -INF + INF
231 beq LOCAL_LABEL(a_is_nan)
232 pop {r4, r5, r6, r7, pc}
234 LOCAL_LABEL(a_is_rational):
236 bne LOCAL_LABEL(b_is_rational)
238 pop {r4, r5, r6, r7, pc}
240 LOCAL_LABEL(b_is_rational):
241 // either a or b or both are zero.
243 beq LOCAL_LABEL(both_zero)
244 cmp r2, #0 // is absA 0 ?
245 beq LOCAL_LABEL(ret_b)
246 pop {r4, r5, r6, r7, pc}
248 LOCAL_LABEL(both_zero):
249 ands r0, r1 // +0 + -0 = +0
250 pop {r4, r5, r6, r7, pc}
256 pop {r4, r5, r6, r7, pc}
258 LOCAL_LABEL(b_is_nan):
260 LOCAL_LABEL(a_is_nan):
262 lsls r1, r1, #(significandBits -1) // r1 is quiet bit.
264 pop {r4, r5, r6, r7, pc}
266 LOCAL_LABEL(ret_inf):
268 lsls r4, r4, #(significandBits)
270 lsrs r0, r0, #(significandBits)
271 lsls r0, r0, #(significandBits)
272 pop {r4, r5, r6, r7, pc}
275 END_COMPILERRT_FUNCTION(__addsf3)
277 NO_EXEC_STACK_DIRECTIVE