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 /* ==================================================================== *
13 fast2_QDOUBLE fast2_dadd(fast2_QDOUBLE a,fast2_QDOUBLE b) {
15 lint manta = a & MANTMASK;
16 int expa = Q6_R_sxth_R(a) ;
17 lint mantb = b & MANTMASK;
18 int expb = Q6_R_sxth_R(b) ;
19 int exp, expdiff, j, k, hi, lo, cn;
22 expdiff = (int) Q6_P_vabsdiffh_PP(a, b);
23 expdiff = Q6_R_sxth_R(expdiff) ;
24 if (expdiff > 63) { expdiff = 62;}
34 mant = (manta>>expa) + (mantb>>expb);
36 hi = (int) (mant>>32);
39 k = Q6_R_normamt_R(hi);
40 if(hi == 0 || hi == -1) k = 31+Q6_R_normamt_R(lo);
43 cn = (mant == 0x8000000000000000LL);
46 if (mant == 0 || mant == -1) exp = 0x8001;
47 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
50 * ==================================================================== */
52 .global fast2_dadd_asm
53 .type fast2_dadd_asm, @function
70 #define minmin R11:10 // exactly 0x000000000000008001LL
76 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL
82 ce = CMP.GT(expa, expb);
83 if ( ce.new) exp = add(expa, #1)
84 if (!ce.new) exp = add(expb, #1)
91 if (!ce) expa = add(expd, #1)
92 if ( ce) expb = add(expd, #1)
96 lmanta = ASR(lmanta, expa)
97 lmantb = ASR(lmantb, expb)
99 lmant = add(lmanta, lmantb)
108 mantexpa = ASL(lmant, k)
110 if(p0) jump .Ldenorma
112 manta = insert(exp, #16, #0)
120 /* =================================================================== *
121 fast2_QDOUBLE fast2_dsub(fast2_QDOUBLE a,fast2_QDOUBLE b) {
123 lint manta = a & MANTMASK;
124 int expa = Q6_R_sxth_R(a) ;
125 lint mantb = b & MANTMASK;
126 int expb = Q6_R_sxth_R(b) ;
127 int exp, expdiff, j, k;
130 expdiff = (int) Q6_P_vabsdiffh_PP(a, b);
131 expdiff = Q6_R_sxth_R(expdiff) ;
132 if (expdiff > 63) { expdiff = 62;}
142 mant = (manta>>expa) - (mantb>>expb);
143 k = Q6_R_clb_P(mant)-1;
146 if (mant == 0 || mant == -1) exp = 0x8001;
147 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
150 * ==================================================================== */
152 .global fast2_dsub_asm
153 .type fast2_dsub_asm, @function
157 #define mantexpa R1:0
160 #define mantexpb R3:2
164 #define mantexpd R7:6
171 #define minmin R11:10 // exactly 0x000000000000008001LL
177 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL
183 ce = CMP.GT(expa, expb);
184 if ( ce.new) exp = add(expa, #1)
185 if (!ce.new) exp = add(expb, #1)
190 expd = MIN(expd, c63)
192 if (!ce) expa = add(expd, #1)
193 if ( ce) expb = add(expd, #1)
197 lmanta = ASR(lmanta, expa)
198 lmantb = ASR(lmantb, expb)
200 lmant = sub(lmanta, lmantb)
209 mantexpa = ASL(lmant, k)
213 manta = insert(exp, #16, #0)
221 /* ==================================================================== *
222 fast2_QDOUBLE fast2_dmpy(fast2_QDOUBLE a,fast2_QDOUBLE b) {
224 lint manta = a & MANTMASK;
225 int expa = Q6_R_sxth_R(a) ;
226 lint mantb = b & MANTMASK;
227 int expb = Q6_R_sxth_R(b) ;
230 int hia, hib, hi, lo;
231 unsigned int loa, lob;
233 hia = (int)(a >> 32);
234 loa = Q6_R_extractu_RII((int)manta, 31, 1);
235 hib = (int)(b >> 32);
236 lob = Q6_R_extractu_RII((int)mantb, 31, 1);
238 mant = Q6_P_mpy_RR(hia, lob);
239 mant = Q6_P_mpyacc_RR(mant,hib, loa);
240 mant = (mant >> 30) + (Q6_P_mpy_RR(hia, hib)<<1);
242 hi = (int) (mant>>32);
244 k = Q6_R_normamt_R(hi);
246 exp = expa + expb - k;
247 if (mant == 0 || mant == -1) exp = 0x8001;
248 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK);
251 * ==================================================================== */
253 .global fast2_dmpy_asm
254 .type fast2_dmpy_asm, @function
259 #define mantexpa R1:0
262 #define mantexpb R3:2
266 #define mantexpd R7:6
269 #define lmantc R11:10
279 mantbl_= lsr(mantbl, #16)
282 mantal_= lsr(mantal, #16)
285 lmantc = mpy(mantah, mantbh)
286 mantexpd = mpy(mantah, mantbl_)
291 lmantc = add(lmantc, lmantc)
292 mantexpd+= mpy(mantbh, mantal_)
297 mantexpd = asr(mantexpd, #15)
299 p1 = cmp.eq(mantexpa, mantexpb)
302 mantexpd = add(mantexpd, lmantc)
303 exp = add(expa, expb)
304 p2 = cmp.eq(mantexpa, min)
308 mantexpb = abs(mantexpd)
315 p0 = cmp.gt(kb, guard)
319 mantexpa = asl(mantexpd, kb)
320 if(p1) jump .Lsat //rarely happens
323 mantal = insert(exp,#16, #0)
327 mantal = insert(c8001,#16, #0)
335 mantexpa = lsr(mantexpa, #1)
338 mantal = insert(exp,#16, #0)
342 /* ==================================================================== *
343 int fast2_qd2f(fast2_QDOUBLE a) {
349 exp = Q6_R_sxth_R(a) ;
350 ic = 0x80000000 & manta;
351 manta = Q6_R_abs_R_sat(manta);
352 mantb = (manta + rnd)>>7;
355 if((manta & 0xff) == rnd) rnd = 0x00;
356 if((manta & 0x7fffffc0) == 0x7fffffc0) {
359 manta= mantb & 0x007fffff;
361 exp = (exp << 23) & 0x7fffffc0;
362 ic = Q6_R_addacc_RR(ic, exp, manta);
365 * ==================================================================== */
368 .global fast2_qd2f_asm
369 .type fast2_qd2f_asm, @function
385 mant = abs(mantah):sat
391 cff = extractu(mant, #8, #0)
392 p2 = cmp.gt(expo, #126)
393 p3 = cmp.ge(expo, #-126)
397 p1 = cmp.eq(cff,#0x40)
399 expo = add(expo, #126)
403 p0 = bitsset(mant, mask)
405 mantb = add(mant, rnd)
409 if(p0) expo = add(expo, #1)
411 mantb = lsr(mantb, #7)
415 ic = and(c80, mantah)
416 mask &= asl(expo, #23)
417 if(!p0) mant = and(mantb, c07f)
421 ic += add(mask, mant)
438 /* ==================================================================== *
439 fast2_QDOUBLE fast2_f2qd(int ia) {
444 mant = ((ia << 7) | 0x40000000)&0x7fffff80 ;
445 if (ia & 0x80000000) mant = -mant;
446 exp = ((ia >> 23) & 0xFFLL) - 126;
447 c = (mant<<32) | Q6_R_zxth_R(exp);;
450 * ==================================================================== */
452 .global fast2_f2qd_asm
453 .type fast2_f2qd_asm, @function
470 mantr = setbit(mantr, #30)
471 expr= extractu(ia,#8,#23)
476 mantr= extractu(mantr, #31, #0)
477 expr= add(expr, #-126)
483 if(p0) mantr= sub(zero, mantr)