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 //===----------------------------------------------------------------------===//
8 /* ==================================================================== */
9 /* FUNCTIONS Optimized double floating point operators */
10 /* ==================================================================== */
11 /* c = dadd_asm(a, b) */
12 /* ====================================================================
14 QDOUBLE dadd(QDOUBLE a,QDOUBLE b) {
16 lint manta = a & MANTMASK;
17 int expa = HEXAGON_R_sxth_R(a) ;
18 lint mantb = b & MANTMASK;
19 int expb = HEXAGON_R_sxth_R(b) ;
20 int exp, expdiff, j, k, hi, lo, cn;
23 expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b);
24 expdiff = HEXAGON_R_sxth_R(expdiff) ;
25 if (expdiff > 63) { expdiff = 62;}
35 mant = (manta>>expa) + (mantb>>expb);
37 hi = (int) (mant>>32);
40 k = HEXAGON_R_normamt_R(hi);
41 if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo);
44 cn = (mant == 0x8000000000000000LL);
47 if (mant == 0 || mant == -1) exp = 0x8001;
48 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
51 * ==================================================================== */
54 .type dadd_asm, @function
77 #define minmin R11:10 // exactly 0x800000000000000000LL
84 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL
90 ce = CMP.GT(expa, expb);
91 if ( ce.new) exp = add(expa, #1)
92 if (!ce.new) exp = add(expb, #1)
99 if (!ce) expa = add(expd, #1)
100 if ( ce) expb = add(expd, #1)
104 lmanta = ASR(lmanta, expa)
105 lmantb = ASR(lmantb, expb)
108 lmant = add(lmanta, lmantb)
114 p0 = cmp.eq(manth, zerol)
115 p1 = cmp.eq(manth, minusl)
118 if(p0.new) k = add(kl, #31)
121 mantexpa = ASL(lmant, k)
125 p0 = cmp.eq(mantexpa, zero)
126 p1 = cmp.eq(mantexpa, minus)
130 p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0
131 if(p2.new) exp = add(exp, #1)
133 #if (__HEXAGON_ARCH__ == 60)
136 if( p0.new) manta = OR(manta,maxneg)
137 if(!p0.new) manta = OR(manta,exp)
143 if( p0.new) manta = OR(manta,maxneg)
144 if(!p0.new) manta = OR(manta,exp)
148 /* =================================================================== *
149 QDOUBLE dsub(QDOUBLE a,QDOUBLE b) {
151 lint manta = a & MANTMASK;
152 int expa = HEXAGON_R_sxth_R(a) ;
153 lint mantb = b & MANTMASK;
154 int expb = HEXAGON_R_sxth_R(b) ;
155 int exp, expdiff, j, k, hi, lo, cn;
158 expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b);
159 expdiff = HEXAGON_R_sxth_R(expdiff) ;
160 if (expdiff > 63) { expdiff = 62;}
170 mant = (manta>>expa) - (mantb>>expb);
172 hi = (int) (mant>>32);
175 k = HEXAGON_R_normamt_R(hi);
176 if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo);
179 cn = (mant == 0x8000000000000000LL);
182 if (mant == 0 || mant == -1) exp = 0x8001;
183 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
186 * ==================================================================== */
189 .type dsub_asm, @function
193 #define mantexpa R1:0
196 #define mantexpb R3:2
200 #define mantexpd R7:6
212 #define minmin R11:10 // exactly 0x800000000000000000LL
219 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL
225 ce = CMP.GT(expa, expb);
226 if ( ce.new) exp = add(expa, #1)
227 if (!ce.new) exp = add(expb, #1)
232 expd = MIN(expd, c63)
234 if (!ce) expa = add(expd, #1)
235 if ( ce) expb = add(expd, #1)
239 lmanta = ASR(lmanta, expa)
240 lmantb = ASR(lmantb, expb)
243 lmant = sub(lmanta, lmantb)
249 p0 = cmp.eq(manth, zerol)
250 p1 = cmp.eq(manth, minusl)
253 if(p0.new) k = add(kl, #31)
256 mantexpa = ASL(lmant, k)
260 p0 = cmp.eq(mantexpa, zero)
261 p1 = cmp.eq(mantexpa, minus)
265 p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0
266 if(p2.new) exp = add(exp, #1)
268 #if (__HEXAGON_ARCH__ == 60)
271 if( p0.new) manta = OR(manta,maxneg)
272 if(!p0.new) manta = OR(manta,exp)
278 if( p0.new) manta = OR(manta,maxneg)
279 if(!p0.new) manta = OR(manta,exp)
283 /* ==================================================================== *
284 QDOUBLE dmpy(QDOUBLE a,QDOUBLE b) {
286 lint manta = a & MANTMASK;
287 int expa = HEXAGON_R_sxth_R(a) ;
288 lint mantb = b & MANTMASK;
289 int expb = HEXAGON_R_sxth_R(b) ;
292 int hia, hib, hi, lo;
293 unsigned int loa, lob;
295 hia = (int)(a >> 32);
296 loa = HEXAGON_R_extractu_RII((int)manta, 31, 1);
297 hib = (int)(b >> 32);
298 lob = HEXAGON_R_extractu_RII((int)mantb, 31, 1);
300 mant = HEXAGON_P_mpy_RR(hia, lob);
301 mant = HEXAGON_P_mpyacc_RR(mant,hib, loa);
302 mant = (mant >> 30) + (HEXAGON_P_mpy_RR(hia, hib)<<1);
304 hi = (int) (mant>>32);
307 k = HEXAGON_R_normamt_R(hi);
308 if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo);
310 exp = expa + expb - k;
311 if (mant == 0 || mant == -1) exp = 0x8001;
312 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
315 * ==================================================================== */
318 .type dmpy_asm, @function
323 #define mantexpa R1:0
326 #define mantexpb R3:2
329 #define mantexpd R7:6
331 #define lmantc R11:10
344 mantbl = lsr(mantbl, #16)
345 mantal = lsr(mantal, #16)
350 lmantc = mpy(mantah, mantbh)
351 mantexpd = mpy(mantah, mantbl)
354 lmantc = add(lmantc, lmantc) //<<1
355 mantexpd+= mpy(mantbh, mantal)
358 lmantc += asr(mantexpd, #15)
359 exp = add(expa, expb)
366 p0 = cmp.eq(mantch, zero0l)
367 p1 = cmp.eq(mantch, minus1l)
371 if(p0.new) k = add(kl, #31)
375 mantexpa = asl(lmantc, k)
380 p0 = cmp.eq(mantexpa, zero0)
381 p1 = cmp.eq(mantexpa, minus1)
385 #if (__HEXAGON_ARCH__ == 60)
388 if( p0.new) mantal = or(mantal,maxneg)
389 if(!p0.new) mantal = or(mantal,exp)
395 if( p0.new) mantal = or(mantal,maxneg)
396 if(!p0.new) mantal = or(mantal,exp)