1//===----------------------Hexagon builtin routine ------------------------===// 2// 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 6// 7//===----------------------------------------------------------------------===// 8/* ==================================================================== * 9 10fast2_QLDOUBLE fast2_ldadd(fast2_QLDOUBLE a,fast2_QLDOUBLE b) { 11 fast2_QLDOUBLE c; 12 lint manta = a & MANTMASK; 13 int expa = Q6_R_sxth_R(a) ; 14 lint mantb = b & MANTMASK; 15 int expb = Q6_R_sxth_R(b) ; 16 int exp, expdiff, j, k, hi, lo, cn; 17 lint mant; 18 19 expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 20 expdiff = Q6_R_sxth_R(expdiff) ; 21 if (expdiff > 63) { expdiff = 62;} 22 if (expa > expb) { 23 exp = expa + 1; 24 expa = 1; 25 expb = expdiff + 1; 26 } else { 27 exp = expb + 1; 28 expb = 1; 29 expa = expdiff + 1; 30 } 31 mant = (manta>>expa) + (mantb>>expb); 32 33 hi = (int) (mant>>32); 34 lo = (int) (mant); 35 36 k = Q6_R_normamt_R(hi); 37 if(hi == 0 || hi == -1) k = 31+Q6_R_normamt_R(lo); 38 39 mant = (mant << k); 40 cn = (mant == 0x8000000000000000LL); 41 exp = exp - k + cn; 42 43 if (mant == 0 || mant == -1) exp = 0x8001; 44 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 45 return(c); 46 } 47 * ==================================================================== */ 48 .text 49 .global fast2_ldadd_asm 50 .type fast2_ldadd_asm, @function 51fast2_ldadd_asm: 52#define manta R1:0 53#define lmanta R1:0 54#define mantb R3:2 55#define lmantb R3:2 56#define expa R4 57#define expb R5 58#define expd R6 59#define exp R8 60#define c63 R9 61#define lmant R1:0 62#define k R4 63#define ce P0 64#define zero R3:2 65 .falign 66 { 67 expa = memw(r29+#8) 68 expb = memw(r29+#24) 69 r7 = r0 70 } 71 { 72 expd = sub(expa, expb):sat 73 ce = CMP.GT(expa, expb); 74 if ( ce.new) exp = add(expa, #1) 75 if (!ce.new) exp = add(expb, #1) 76 } { 77 expd = abs(expd):sat 78 if ( ce) expa = #1 79 if (!ce) expb = #1 80 c63 = #62 81 } { 82 expd = MIN(expd, c63) 83 manta = memd(r29+#0) 84 mantb = memd(r29+#16) 85 } { 86 if (!ce) expa = add(expd, #1) 87 if ( ce) expb = add(expd, #1) 88 } { 89 lmanta = ASR(lmanta, expa) 90 lmantb = ASR(lmantb, expb) 91 } { 92 lmant = add(lmanta, lmantb) 93 zero = #0 94 } { 95 k = clb(lmant) 96 c63.L =#0x0001 97 } { 98 exp -= add(k, #-1) //exp = exp - (k-1) 99 k = add(k, #-1) 100 p0 = cmp.gt(k, #58) 101 c63.H =#0x8000 102 } { 103 if(!p0)memw(r7+#8) = exp 104 lmant = ASL(lmant, k) 105 if(p0) jump .Ldenorma 106 } { 107 memd(r7+#0) = lmant 108 jumpr r31 109 } 110.Ldenorma: 111 memd(r7+#0) = zero 112 { 113 memw(r7+#8) = c63 114 jumpr r31 115 } 116/* =================================================================== * 117 fast2_QLDOUBLE fast2_ldsub(fast2_QLDOUBLE a,fast2_QLDOUBLE b) { 118 fast2_QLDOUBLE c; 119 lint manta = a & MANTMASK; 120 int expa = Q6_R_sxth_R(a) ; 121 lint mantb = b & MANTMASK; 122 int expb = Q6_R_sxth_R(b) ; 123 int exp, expdiff, j, k; 124 lint mant; 125 126 expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 127 expdiff = Q6_R_sxth_R(expdiff) ; 128 if (expdiff > 63) { expdiff = 62;} 129 if (expa > expb) { 130 exp = expa + 1; 131 expa = 1; 132 expb = expdiff + 1; 133 } else { 134 exp = expb + 1; 135 expb = 1; 136 expa = expdiff + 1; 137 } 138 mant = (manta>>expa) - (mantb>>expb); 139 k = Q6_R_clb_P(mant)-1; 140 mant = (mant << k); 141 exp = exp - k; 142 if (mant == 0 || mant == -1) exp = 0x8001; 143 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 144 return(c); 145 } 146 * ==================================================================== */ 147 .text 148 .global fast2_ldsub_asm 149 .type fast2_ldsub_asm, @function 150fast2_ldsub_asm: 151#define manta R1:0 152#define lmanta R1:0 153#define mantb R3:2 154#define lmantb R3:2 155#define expa R4 156#define expb R5 157#define expd R6 158#define exp R8 159#define c63 R9 160#define lmant R1:0 161#define k R4 162#define ce P0 163#define zero R3:2 164 .falign 165 { 166 expa = memw(r29+#8) 167 expb = memw(r29+#24) 168 r7 = r0 169 } 170 { 171 expd = sub(expa, expb):sat 172 ce = CMP.GT(expa, expb); 173 if ( ce.new) exp = add(expa, #1) 174 if (!ce.new) exp = add(expb, #1) 175 } { 176 expd = abs(expd):sat 177 if ( ce) expa = #1 178 if (!ce) expb = #1 179 c63 = #62 180 } { 181 expd = min(expd, c63) 182 manta = memd(r29+#0) 183 mantb = memd(r29+#16) 184 } { 185 if (!ce) expa = add(expd, #1) 186 if ( ce) expb = add(expd, #1) 187 } { 188 lmanta = ASR(lmanta, expa) 189 lmantb = ASR(lmantb, expb) 190 } { 191 lmant = sub(lmanta, lmantb) 192 zero = #0 193 } { 194 k = clb(lmant) 195 c63.L =#0x0001 196 } { 197 exp -= add(k, #-1) //exp = exp - (k+1) 198 k = add(k, #-1) 199 p0 = cmp.gt(k, #58) 200 c63.H =#0x8000 201 } { 202 if(!p0)memw(r7+#8) = exp 203 lmant = asl(lmant, k) 204 if(p0) jump .Ldenorma_s 205 } { 206 memd(r7+#0) = lmant 207 jumpr r31 208 } 209.Ldenorma_s: 210 memd(r7+#0) = zero 211 { 212 memw(r7+#8) = c63 213 jumpr r31 214 } 215 216/* ==================================================================== * 217 fast2_QLDOUBLE fast2_ldmpy(fast2_QLDOUBLE a,fast2_QLDOUBLE b) { 218 fast2_QLDOUBLE c; 219 lint manta = a & MANTMASK; 220 int expa = Q6_R_sxth_R(a) ; 221 lint mantb = b & MANTMASK; 222 int expb = Q6_R_sxth_R(b) ; 223 int exp, k; 224 lint mant; 225 int hia, hib, hi, lo; 226 unsigned int loa, lob; 227 228 hia = (int)(a >> 32); 229 loa = Q6_R_extractu_RII((int)manta, 31, 1); 230 hib = (int)(b >> 32); 231 lob = Q6_R_extractu_RII((int)mantb, 31, 1); 232 233 mant = Q6_P_mpy_RR(hia, lob); 234 mant = Q6_P_mpyacc_RR(mant,hib, loa); 235 mant = (mant >> 30) + (Q6_P_mpy_RR(hia, hib)<<1); 236 237 hi = (int) (mant>>32); 238 239 k = Q6_R_normamt_R(hi); 240 mant = mant << k; 241 exp = expa + expb - k; 242 if (mant == 0 || mant == -1) exp = 0x8001; 243 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 244 return(c); 245 } 246 * ==================================================================== */ 247 .text 248 .global fast2_ldmpy_asm 249 .type fast2_ldmpy_asm, @function 250fast2_ldmpy_asm: 251 252#define mantxl_ R9 253#define mantxl R14 254#define mantxh R15 255#define mantx R15:14 256#define mantbl R2 257#define mantbl_ R8 258#define mantbh R3 259#define mantb R3:2 260#define expa R4 261#define expb R5 262#define c8001 R8 263#define mantd R7:6 264#define lmantc R11:10 265#define kp R9 266#define min R13:12 267#define minh R13 268#define max R13:12 269#define maxh R13 270#define ret R0 271 272 .falign 273 { 274 mantx = memd(r29+#0) 275 mantb = memd(r29+#16) 276 min = #0 277 } 278 { 279 mantbl_= extractu(mantbl, #31, #1) 280 mantxl_= extractu(mantxl, #31, #1) 281 minh.H = #0x8000 282 } 283 { 284 lmantc = mpy(mantxh, mantbh) 285 mantd = mpy(mantxh, mantbl_) 286 expa = memw(r29+#8) 287 expb = memw(r29+#24) 288 } 289 { 290 lmantc = add(lmantc, lmantc) 291 mantd += mpy(mantbh, mantxl_) 292 } 293 { 294 mantd = asr(mantd, #30) 295 c8001.L = #0x0001 296 p1 = cmp.eq(mantx, mantb) 297 } 298 { 299 mantd = add(mantd, lmantc) 300 expa= add(expa, expb) 301 p2 = cmp.eq(mantb, min) 302 } 303 { 304 kp = clb(mantd) 305 c8001.H = #0x8000 306 p1 = and(p1, p2) 307 } 308 { 309 expa-= add(kp, #-1) 310 kp = add(kp, #-1) 311 if(p1) jump .Lsat 312 } 313 { 314 mantd = asl(mantd, kp) 315 memw(ret+#8) = expa 316 p0 = cmp.gt(kp, #58) 317 if(p0.new) jump:NT .Ldenorm //rarely happens 318 } 319 { 320 memd(ret+#0) = mantd 321 jumpr r31 322 } 323.Lsat: 324 { 325 max = #0 326 expa+= add(kp, #1) 327 } 328 { 329 maxh.H = #0x4000 330 memw(ret+#8) = expa 331 } 332 { 333 memd(ret+#0) = max 334 jumpr r31 335 } 336.Ldenorm: 337 { 338 memw(ret+#8) = c8001 339 mantx = #0 340 } 341 { 342 memd(ret+#0) = mantx 343 jumpr r31 344 } 345