1 //===----------------------Hexagon builtin routine ------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Double Precision Multiply
39 #define EXTRACTOFF r14
40 #define EXTRACTAMT r15:14
45 #define HI_MANTBITS 20
48 #define MANTISSA_TO_INT_BIAS 52
49 #define SR_BIT_INEXACT 5
52 #define SR_ROUND_OFF 22
58 #define Q6_ALIAS(TAG) .global __qdsp_##TAG ; .set __qdsp_##TAG, __hexagon_##TAG
59 #define FAST_ALIAS(TAG) .global __hexagon_fast_##TAG ; .set __hexagon_fast_##TAG, __hexagon_##TAG
60 #define FAST2_ALIAS(TAG) .global __hexagon_fast2_##TAG ; .set __hexagon_fast2_##TAG, __hexagon_##TAG
61 #define END(TAG) .size TAG,.-TAG
64 .global __hexagon_adddf3
65 .global __hexagon_subdf3
66 .type __hexagon_adddf3, @function
67 .type __hexagon_subdf3, @function
79 EXPA = extractu(AH,#EXPBITS,#HI_MANTBITS)
80 EXPB = extractu(BH,#EXPBITS,#HI_MANTBITS)
81 ATMP = combine(##0x20000000,#0)
84 NORMAL = dfclass(A,#2)
85 NORMAL = dfclass(B,#2)
87 BIGB = cmp.gtu(EXPB,EXPA) // Is B substantially greater than A?
90 if (!NORMAL) jump .Ladd_abnormal // If abnormal, go to special code
91 if (BIGB) A = B // if B >> A, swap A and B
92 if (BIGB) B = A // If B >> A, swap A and B
93 if (BIGB) EXPB_A = combine(EXPA,EXPB) // swap exponents
96 ATMP = insert(A,#MANTBITS,#EXPBITS-2) // Q1.62
97 BTMP = insert(B,#MANTBITS,#EXPBITS-2) // Q1.62
98 EXPDIFF = sub(EXPA,EXPB)
99 ZTMP = combine(#62,#1)
105 #define NO_STICKIES p1
108 EXPDIFF = min(EXPDIFF,ZTMPH) // If exponent difference >= ~60,
109 // will collapse to sticky bit
111 A_POS = cmp.gt(AH,#-1)
115 if (!A_POS) ATMP = ATMP2
116 ATMP2 = extractu(BTMP,EXTRACTAMT)
117 BTMP = ASR(BTMP,EXPDIFF)
125 NO_STICKIES = cmp.eq(ATMP2,ZERO)
126 if (!NO_STICKIES.new) BTMPL = or(BTMPL,ZTMPL)
127 EXPB = add(EXPA,#-BIAS-60)
128 B_POS = cmp.gt(BH,#-1)
131 ATMP = add(ATMP,BTMP) // ADD!!!
132 ATMP2 = sub(ATMP,BTMP) // Negate and ADD --> SUB!!!
133 ZTMP = combine(#54,##2045)
136 p0 = cmp.gtu(EXPA,ZTMPH) // must be pretty high in case of large cancellation
137 p0 = !cmp.gtu(EXPA,ZTMPL)
138 if (!p0.new) jump:nt .Ladd_ovf_unf
139 if (!B_POS) ATMP = ATMP2 // if B neg, pick difference
142 A = convert_d2df(ATMP) // Convert to Double Precision, taking care of flags, etc. So nice!
143 p0 = cmp.eq(ATMPH,#0)
144 p0 = cmp.eq(ATMPL,#0)
145 if (p0.new) jump:nt .Ladd_zero // or maybe conversion handles zero case correctly?
148 AH += asl(EXPB,#HI_MANTBITS)
154 BH = togglebit(BH,#31)
161 // True zero, full cancellation
162 // +0 unless round towards negative infinity
169 TMP = extractu(TMP,#2,#22)
174 if (p0.new) AH = xor(AH,BH)
179 // Overflow or Denormal is possible
180 // Good news: Underflow flag is not possible!
182 // ATMP has 2's complement value
184 // EXPA has A's exponent, EXPB has EXPA-BIAS-60
186 // Convert, extract exponent, add adjustment.
187 // If > 2046, overflow
190 // Note that we've not done our zero check yet, so do that too
193 A = convert_d2df(ATMP)
194 p0 = cmp.eq(ATMPH,#0)
195 p0 = cmp.eq(ATMPL,#0)
196 if (p0.new) jump:nt .Ladd_zero
199 TMP = extractu(AH,#EXPBITS,#HI_MANTBITS)
200 AH += asl(EXPB,#HI_MANTBITS)
204 B = combine(##0x00100000,#0)
207 p0 = cmp.gt(EXPB,##BIAS+BIAS-2)
208 if (p0.new) jump:nt .Ladd_ovf
212 if (p0.new) jumpr:t r31
216 B = insert(A,#MANTBITS,#0)
228 // We get either max finite value or infinity. Either way, overflow+inexact
230 A = ATMP // 2's complement value
232 ATMP = combine(##0x7fefffff,#-1) // positive max finite
235 EXPB = extractu(TMP,#2,#SR_ROUND_OFF) // rounding bits
236 TMP = or(TMP,#0x28) // inexact + overflow
237 BTMP = combine(##0x7ff00000,#0) // positive infinity
241 EXPB ^= lsr(AH,#31) // Does sign match rounding?
242 TMP = EXPB // unmodified rounding mode
245 p0 = !cmp.eq(TMP,#1) // If not round-to-zero and
246 p0 = !cmp.eq(EXPB,#2) // Not rounding the other way,
247 if (p0.new) ATMP = BTMP // we should get infinity
250 A = insert(ATMP,#63,#0) // insert inf/maxfinite, leave sign
259 ATMP = extractu(A,#63,#0) // strip off sign
260 BTMP = extractu(B,#63,#0) // strip off sign
263 p3 = cmp.gtu(ATMP,BTMP)
264 if (!p3.new) A = B // sort values
265 if (!p3.new) B = A // sort values
268 // Any NaN --> NaN, possibly raise invalid if sNaN
269 p0 = dfclass(A,#0x0f) // A not NaN?
270 if (!p0.new) jump:nt .Linvalid_nan_add
275 // Infinity + non-infinity number is infinity
276 // Infinity + infinity --> inf or nan
277 p1 = dfclass(A,#0x08) // A is infinity
278 if (p1.new) jump:nt .Linf_add
281 p2 = dfclass(B,#0x01) // B is zero
282 if (p2.new) jump:nt .LB_zero // so return A or special 0+0
285 // We are left with adding one or more subnormals
288 if (p0.new) jump:nt .Ladd_two_subnormal
289 ATMP = combine(##0x20000000,#0)
292 EXPA = extractu(AH,#EXPBITS,#HI_MANTBITS)
294 // BTMP already ABS(B)
295 BTMP = asl(BTMP,#EXPBITS-2)
298 #define EXTRACTOFF r14
301 ATMP = insert(A,#MANTBITS,#EXPBITS-2)
302 EXPDIFF = sub(EXPA,EXPB)
303 ZTMP = combine(#62,#1)
309 ATMP = extractu(A,#63,#0)
310 BTMP = extractu(B,#63,#0)
323 ATMP = add(ATMP,BTMP)
327 p0 = cmp.gt(ATMPH,#-1)
336 if (!p0) AH = or(AH,BH)
338 if (p0.new) jump:nt .Lzero_plus_zero
346 TMP = convert_df2sf(A) // will generate invalid if sNaN
347 p0 = dfclass(B,#0x0f) // if B is not NaN
348 if (p0.new) B = A // make it whatever A is
351 BL = convert_df2sf(B) // will generate invalid if sNaN
358 p0 = dfcmp.eq(ATMP,A) // is A also zero?
359 if (!p0.new) jumpr:t r31 // If not, just return A
362 // if equal integral values, they have the same sign, which is fine for all rounding
364 // If unequal in sign, we get +0 for all rounding modes except round down
368 if (p0.new) jumpr:t r31
374 TMP = extractu(TMP,#2,#SR_ROUND_OFF)
379 if (p0.new) AH = ##0x80000000
383 // adding infinities is only OK if they are equal
385 p0 = !cmp.eq(AH,BH) // Do they have different signs
386 p0 = dfclass(B,#8) // And is B also infinite?
387 if (!p0.new) jumpr:t r31 // If not, just a normal inf
390 BL = ##0x7f800001 // sNAN
393 A = convert_sf2df(BL) // trigger invalid, set NaN
396 END(__hexagon_adddf3)