1336817Sdim//===----------------------Hexagon builtin routine ------------------------===// 2336817Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6336817Sdim// 7336817Sdim//===----------------------------------------------------------------------===// 8336817Sdim/* ==================================================================== * 9336817Sdim 10336817Sdimfast2_QLDOUBLE fast2_ldadd(fast2_QLDOUBLE a,fast2_QLDOUBLE b) { 11336817Sdim fast2_QLDOUBLE c; 12336817Sdim lint manta = a & MANTMASK; 13336817Sdim int expa = Q6_R_sxth_R(a) ; 14336817Sdim lint mantb = b & MANTMASK; 15336817Sdim int expb = Q6_R_sxth_R(b) ; 16336817Sdim int exp, expdiff, j, k, hi, lo, cn; 17336817Sdim lint mant; 18336817Sdim 19336817Sdim expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 20336817Sdim expdiff = Q6_R_sxth_R(expdiff) ; 21336817Sdim if (expdiff > 63) { expdiff = 62;} 22336817Sdim if (expa > expb) { 23336817Sdim exp = expa + 1; 24336817Sdim expa = 1; 25336817Sdim expb = expdiff + 1; 26336817Sdim } else { 27336817Sdim exp = expb + 1; 28336817Sdim expb = 1; 29336817Sdim expa = expdiff + 1; 30336817Sdim } 31336817Sdim mant = (manta>>expa) + (mantb>>expb); 32336817Sdim 33336817Sdim hi = (int) (mant>>32); 34336817Sdim lo = (int) (mant); 35336817Sdim 36336817Sdim k = Q6_R_normamt_R(hi); 37336817Sdim if(hi == 0 || hi == -1) k = 31+Q6_R_normamt_R(lo); 38336817Sdim 39336817Sdim mant = (mant << k); 40336817Sdim cn = (mant == 0x8000000000000000LL); 41336817Sdim exp = exp - k + cn; 42336817Sdim 43336817Sdim if (mant == 0 || mant == -1) exp = 0x8001; 44336817Sdim c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 45336817Sdim return(c); 46336817Sdim } 47336817Sdim * ==================================================================== */ 48336817Sdim .text 49336817Sdim .global fast2_ldadd_asm 50336817Sdim .type fast2_ldadd_asm, @function 51336817Sdimfast2_ldadd_asm: 52336817Sdim#define manta R1:0 53336817Sdim#define lmanta R1:0 54336817Sdim#define mantb R3:2 55336817Sdim#define lmantb R3:2 56336817Sdim#define expa R4 57336817Sdim#define expb R5 58336817Sdim#define expd R6 59336817Sdim#define exp R8 60336817Sdim#define c63 R9 61336817Sdim#define lmant R1:0 62336817Sdim#define k R4 63336817Sdim#define ce P0 64336817Sdim#define zero R3:2 65336817Sdim .falign 66336817Sdim { 67336817Sdim expa = memw(r29+#8) 68336817Sdim expb = memw(r29+#24) 69336817Sdim r7 = r0 70336817Sdim } 71336817Sdim { 72336817Sdim expd = sub(expa, expb):sat 73336817Sdim ce = CMP.GT(expa, expb); 74336817Sdim if ( ce.new) exp = add(expa, #1) 75336817Sdim if (!ce.new) exp = add(expb, #1) 76336817Sdim } { 77336817Sdim expd = abs(expd):sat 78336817Sdim if ( ce) expa = #1 79336817Sdim if (!ce) expb = #1 80336817Sdim c63 = #62 81336817Sdim } { 82336817Sdim expd = MIN(expd, c63) 83336817Sdim manta = memd(r29+#0) 84336817Sdim mantb = memd(r29+#16) 85336817Sdim } { 86336817Sdim if (!ce) expa = add(expd, #1) 87336817Sdim if ( ce) expb = add(expd, #1) 88336817Sdim } { 89336817Sdim lmanta = ASR(lmanta, expa) 90336817Sdim lmantb = ASR(lmantb, expb) 91336817Sdim } { 92336817Sdim lmant = add(lmanta, lmantb) 93336817Sdim zero = #0 94336817Sdim } { 95336817Sdim k = clb(lmant) 96336817Sdim c63.L =#0x0001 97336817Sdim } { 98336817Sdim exp -= add(k, #-1) //exp = exp - (k-1) 99336817Sdim k = add(k, #-1) 100336817Sdim p0 = cmp.gt(k, #58) 101336817Sdim c63.H =#0x8000 102336817Sdim } { 103336817Sdim if(!p0)memw(r7+#8) = exp 104336817Sdim lmant = ASL(lmant, k) 105336817Sdim if(p0) jump .Ldenorma 106336817Sdim } { 107336817Sdim memd(r7+#0) = lmant 108336817Sdim jumpr r31 109336817Sdim } 110336817Sdim.Ldenorma: 111336817Sdim memd(r7+#0) = zero 112336817Sdim { 113336817Sdim memw(r7+#8) = c63 114336817Sdim jumpr r31 115336817Sdim } 116336817Sdim/* =================================================================== * 117336817Sdim fast2_QLDOUBLE fast2_ldsub(fast2_QLDOUBLE a,fast2_QLDOUBLE b) { 118336817Sdim fast2_QLDOUBLE c; 119336817Sdim lint manta = a & MANTMASK; 120336817Sdim int expa = Q6_R_sxth_R(a) ; 121336817Sdim lint mantb = b & MANTMASK; 122336817Sdim int expb = Q6_R_sxth_R(b) ; 123336817Sdim int exp, expdiff, j, k; 124336817Sdim lint mant; 125336817Sdim 126336817Sdim expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 127336817Sdim expdiff = Q6_R_sxth_R(expdiff) ; 128336817Sdim if (expdiff > 63) { expdiff = 62;} 129336817Sdim if (expa > expb) { 130336817Sdim exp = expa + 1; 131336817Sdim expa = 1; 132336817Sdim expb = expdiff + 1; 133336817Sdim } else { 134336817Sdim exp = expb + 1; 135336817Sdim expb = 1; 136336817Sdim expa = expdiff + 1; 137336817Sdim } 138336817Sdim mant = (manta>>expa) - (mantb>>expb); 139336817Sdim k = Q6_R_clb_P(mant)-1; 140336817Sdim mant = (mant << k); 141336817Sdim exp = exp - k; 142336817Sdim if (mant == 0 || mant == -1) exp = 0x8001; 143336817Sdim c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 144336817Sdim return(c); 145336817Sdim } 146336817Sdim * ==================================================================== */ 147336817Sdim .text 148336817Sdim .global fast2_ldsub_asm 149336817Sdim .type fast2_ldsub_asm, @function 150336817Sdimfast2_ldsub_asm: 151336817Sdim#define manta R1:0 152336817Sdim#define lmanta R1:0 153336817Sdim#define mantb R3:2 154336817Sdim#define lmantb R3:2 155336817Sdim#define expa R4 156336817Sdim#define expb R5 157336817Sdim#define expd R6 158336817Sdim#define exp R8 159336817Sdim#define c63 R9 160336817Sdim#define lmant R1:0 161336817Sdim#define k R4 162336817Sdim#define ce P0 163336817Sdim#define zero R3:2 164336817Sdim .falign 165336817Sdim { 166336817Sdim expa = memw(r29+#8) 167336817Sdim expb = memw(r29+#24) 168336817Sdim r7 = r0 169336817Sdim } 170336817Sdim { 171336817Sdim expd = sub(expa, expb):sat 172336817Sdim ce = CMP.GT(expa, expb); 173336817Sdim if ( ce.new) exp = add(expa, #1) 174336817Sdim if (!ce.new) exp = add(expb, #1) 175336817Sdim } { 176336817Sdim expd = abs(expd):sat 177336817Sdim if ( ce) expa = #1 178336817Sdim if (!ce) expb = #1 179336817Sdim c63 = #62 180336817Sdim } { 181336817Sdim expd = min(expd, c63) 182336817Sdim manta = memd(r29+#0) 183336817Sdim mantb = memd(r29+#16) 184336817Sdim } { 185336817Sdim if (!ce) expa = add(expd, #1) 186336817Sdim if ( ce) expb = add(expd, #1) 187336817Sdim } { 188336817Sdim lmanta = ASR(lmanta, expa) 189336817Sdim lmantb = ASR(lmantb, expb) 190336817Sdim } { 191336817Sdim lmant = sub(lmanta, lmantb) 192336817Sdim zero = #0 193336817Sdim } { 194336817Sdim k = clb(lmant) 195336817Sdim c63.L =#0x0001 196336817Sdim } { 197336817Sdim exp -= add(k, #-1) //exp = exp - (k+1) 198336817Sdim k = add(k, #-1) 199336817Sdim p0 = cmp.gt(k, #58) 200336817Sdim c63.H =#0x8000 201336817Sdim } { 202336817Sdim if(!p0)memw(r7+#8) = exp 203336817Sdim lmant = asl(lmant, k) 204336817Sdim if(p0) jump .Ldenorma_s 205336817Sdim } { 206336817Sdim memd(r7+#0) = lmant 207336817Sdim jumpr r31 208336817Sdim } 209336817Sdim.Ldenorma_s: 210336817Sdim memd(r7+#0) = zero 211336817Sdim { 212336817Sdim memw(r7+#8) = c63 213336817Sdim jumpr r31 214336817Sdim } 215336817Sdim 216336817Sdim/* ==================================================================== * 217336817Sdim fast2_QLDOUBLE fast2_ldmpy(fast2_QLDOUBLE a,fast2_QLDOUBLE b) { 218336817Sdim fast2_QLDOUBLE c; 219336817Sdim lint manta = a & MANTMASK; 220336817Sdim int expa = Q6_R_sxth_R(a) ; 221336817Sdim lint mantb = b & MANTMASK; 222336817Sdim int expb = Q6_R_sxth_R(b) ; 223336817Sdim int exp, k; 224336817Sdim lint mant; 225336817Sdim int hia, hib, hi, lo; 226336817Sdim unsigned int loa, lob; 227336817Sdim 228336817Sdim hia = (int)(a >> 32); 229336817Sdim loa = Q6_R_extractu_RII((int)manta, 31, 1); 230336817Sdim hib = (int)(b >> 32); 231336817Sdim lob = Q6_R_extractu_RII((int)mantb, 31, 1); 232336817Sdim 233336817Sdim mant = Q6_P_mpy_RR(hia, lob); 234336817Sdim mant = Q6_P_mpyacc_RR(mant,hib, loa); 235336817Sdim mant = (mant >> 30) + (Q6_P_mpy_RR(hia, hib)<<1); 236336817Sdim 237336817Sdim hi = (int) (mant>>32); 238336817Sdim 239336817Sdim k = Q6_R_normamt_R(hi); 240336817Sdim mant = mant << k; 241336817Sdim exp = expa + expb - k; 242336817Sdim if (mant == 0 || mant == -1) exp = 0x8001; 243336817Sdim c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 244336817Sdim return(c); 245336817Sdim } 246336817Sdim * ==================================================================== */ 247336817Sdim .text 248336817Sdim .global fast2_ldmpy_asm 249336817Sdim .type fast2_ldmpy_asm, @function 250336817Sdimfast2_ldmpy_asm: 251336817Sdim 252336817Sdim#define mantxl_ R9 253336817Sdim#define mantxl R14 254336817Sdim#define mantxh R15 255336817Sdim#define mantx R15:14 256336817Sdim#define mantbl R2 257336817Sdim#define mantbl_ R8 258336817Sdim#define mantbh R3 259336817Sdim#define mantb R3:2 260336817Sdim#define expa R4 261336817Sdim#define expb R5 262336817Sdim#define c8001 R8 263336817Sdim#define mantd R7:6 264336817Sdim#define lmantc R11:10 265336817Sdim#define kp R9 266336817Sdim#define min R13:12 267336817Sdim#define minh R13 268336817Sdim#define max R13:12 269336817Sdim#define maxh R13 270336817Sdim#define ret R0 271336817Sdim 272336817Sdim .falign 273336817Sdim { 274336817Sdim mantx = memd(r29+#0) 275336817Sdim mantb = memd(r29+#16) 276336817Sdim min = #0 277336817Sdim } 278336817Sdim { 279336817Sdim mantbl_= extractu(mantbl, #31, #1) 280336817Sdim mantxl_= extractu(mantxl, #31, #1) 281336817Sdim minh.H = #0x8000 282336817Sdim } 283336817Sdim { 284336817Sdim lmantc = mpy(mantxh, mantbh) 285336817Sdim mantd = mpy(mantxh, mantbl_) 286336817Sdim expa = memw(r29+#8) 287336817Sdim expb = memw(r29+#24) 288336817Sdim } 289336817Sdim { 290336817Sdim lmantc = add(lmantc, lmantc) 291336817Sdim mantd += mpy(mantbh, mantxl_) 292336817Sdim } 293336817Sdim { 294336817Sdim mantd = asr(mantd, #30) 295336817Sdim c8001.L = #0x0001 296336817Sdim p1 = cmp.eq(mantx, mantb) 297336817Sdim } 298336817Sdim { 299336817Sdim mantd = add(mantd, lmantc) 300336817Sdim expa= add(expa, expb) 301336817Sdim p2 = cmp.eq(mantb, min) 302336817Sdim } 303336817Sdim { 304336817Sdim kp = clb(mantd) 305336817Sdim c8001.H = #0x8000 306336817Sdim p1 = and(p1, p2) 307336817Sdim } 308336817Sdim { 309336817Sdim expa-= add(kp, #-1) 310336817Sdim kp = add(kp, #-1) 311336817Sdim if(p1) jump .Lsat 312336817Sdim } 313336817Sdim { 314336817Sdim mantd = asl(mantd, kp) 315336817Sdim memw(ret+#8) = expa 316336817Sdim p0 = cmp.gt(kp, #58) 317336817Sdim if(p0.new) jump:NT .Ldenorm //rarely happens 318336817Sdim } 319336817Sdim { 320336817Sdim memd(ret+#0) = mantd 321336817Sdim jumpr r31 322336817Sdim } 323336817Sdim.Lsat: 324336817Sdim { 325336817Sdim max = #0 326336817Sdim expa+= add(kp, #1) 327336817Sdim } 328336817Sdim { 329336817Sdim maxh.H = #0x4000 330336817Sdim memw(ret+#8) = expa 331336817Sdim } 332336817Sdim { 333336817Sdim memd(ret+#0) = max 334336817Sdim jumpr r31 335336817Sdim } 336336817Sdim.Ldenorm: 337336817Sdim { 338336817Sdim memw(ret+#8) = c8001 339336817Sdim mantx = #0 340336817Sdim } 341336817Sdim { 342336817Sdim memd(ret+#0) = mantx 343336817Sdim jumpr r31 344336817Sdim } 345