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/* FUNCTIONS Optimized double floating point operators */ 10/* ==================================================================== */ 11/* c = dadd_asm(a, b) */ 12/* ==================================================================== * 13fast2_QDOUBLE fast2_dadd(fast2_QDOUBLE a,fast2_QDOUBLE b) { 14 fast2_QDOUBLE c; 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; 20 lint mant; 21 22 expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 23 expdiff = Q6_R_sxth_R(expdiff) ; 24 if (expdiff > 63) { expdiff = 62;} 25 if (expa > expb) { 26 exp = expa + 1; 27 expa = 1; 28 expb = expdiff + 1; 29 } else { 30 exp = expb + 1; 31 expb = 1; 32 expa = expdiff + 1; 33 } 34 mant = (manta>>expa) + (mantb>>expb); 35 36 hi = (int) (mant>>32); 37 lo = (int) (mant); 38 39 k = Q6_R_normamt_R(hi); 40 if(hi == 0 || hi == -1) k = 31+Q6_R_normamt_R(lo); 41 42 mant = (mant << k); 43 cn = (mant == 0x8000000000000000LL); 44 exp = exp - k + cn; 45 46 if (mant == 0 || mant == -1) exp = 0x8001; 47 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 48 return(c); 49 } 50 * ==================================================================== */ 51 .text 52 .global fast2_dadd_asm 53 .type fast2_dadd_asm, @function 54fast2_dadd_asm: 55#define manta R0 56#define mantexpa R1:0 57#define lmanta R1:0 58#define mantb R2 59#define mantexpb R3:2 60#define lmantb R3:2 61#define expa R4 62#define expb R5 63#define mantexpd R7:6 64#define expd R6 65#define exp R8 66#define c63 R9 67#define lmant R1:0 68#define manth R1 69#define mantl R0 70#define minmin R11:10 // exactly 0x000000000000008001LL 71#define minminl R10 72#define k R4 73#define ce P0 74 .falign 75 { 76 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL 77 c63 = #62 78 expa = SXTH(manta) 79 expb = SXTH(mantb) 80 } { 81 expd = SXTH(expd) 82 ce = CMP.GT(expa, expb); 83 if ( ce.new) exp = add(expa, #1) 84 if (!ce.new) exp = add(expb, #1) 85 } { 86 if ( ce) expa = #1 87 if (!ce) expb = #1 88 manta.L = #0 89 expd = MIN(expd, c63) 90 } { 91 if (!ce) expa = add(expd, #1) 92 if ( ce) expb = add(expd, #1) 93 mantb.L = #0 94 minmin = #0 95 } { 96 lmanta = ASR(lmanta, expa) 97 lmantb = ASR(lmantb, expb) 98 } { 99 lmant = add(lmanta, lmantb) 100 minminl.L = #0x8001 101 } { 102 k = clb(lmant) 103 c63 = #58 104 } { 105 k = add(k, #-1) 106 p0 = cmp.gt(k, c63) 107 } { 108 mantexpa = ASL(lmant, k) 109 exp = SUB(exp, k) 110 if(p0) jump .Ldenorma 111 } { 112 manta = insert(exp, #16, #0) 113 jumpr r31 114 } 115.Ldenorma: 116 { 117 mantexpa = minmin 118 jumpr r31 119 } 120/* =================================================================== * 121 fast2_QDOUBLE fast2_dsub(fast2_QDOUBLE a,fast2_QDOUBLE b) { 122 fast2_QDOUBLE c; 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; 128 lint mant; 129 130 expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 131 expdiff = Q6_R_sxth_R(expdiff) ; 132 if (expdiff > 63) { expdiff = 62;} 133 if (expa > expb) { 134 exp = expa + 1; 135 expa = 1; 136 expb = expdiff + 1; 137 } else { 138 exp = expb + 1; 139 expb = 1; 140 expa = expdiff + 1; 141 } 142 mant = (manta>>expa) - (mantb>>expb); 143 k = Q6_R_clb_P(mant)-1; 144 mant = (mant << k); 145 exp = exp - k; 146 if (mant == 0 || mant == -1) exp = 0x8001; 147 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 148 return(c); 149 } 150 * ==================================================================== */ 151 .text 152 .global fast2_dsub_asm 153 .type fast2_dsub_asm, @function 154fast2_dsub_asm: 155 156#define manta R0 157#define mantexpa R1:0 158#define lmanta R1:0 159#define mantb R2 160#define mantexpb R3:2 161#define lmantb R3:2 162#define expa R4 163#define expb R5 164#define mantexpd R7:6 165#define expd R6 166#define exp R8 167#define c63 R9 168#define lmant R1:0 169#define manth R1 170#define mantl R0 171#define minmin R11:10 // exactly 0x000000000000008001LL 172#define minminl R10 173#define k R4 174#define ce P0 175 .falign 176 { 177 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL 178 c63 = #62 179 expa = SXTH(manta) 180 expb = SXTH(mantb) 181 } { 182 expd = SXTH(expd) 183 ce = CMP.GT(expa, expb); 184 if ( ce.new) exp = add(expa, #1) 185 if (!ce.new) exp = add(expb, #1) 186 } { 187 if ( ce) expa = #1 188 if (!ce) expb = #1 189 manta.L = #0 190 expd = MIN(expd, c63) 191 } { 192 if (!ce) expa = add(expd, #1) 193 if ( ce) expb = add(expd, #1) 194 mantb.L = #0 195 minmin = #0 196 } { 197 lmanta = ASR(lmanta, expa) 198 lmantb = ASR(lmantb, expb) 199 } { 200 lmant = sub(lmanta, lmantb) 201 minminl.L = #0x8001 202 } { 203 k = clb(lmant) 204 c63 = #58 205 } { 206 k = add(k, #-1) 207 p0 = cmp.gt(k, c63) 208 } { 209 mantexpa = ASL(lmant, k) 210 exp = SUB(exp, k) 211 if(p0) jump .Ldenorm 212 } { 213 manta = insert(exp, #16, #0) 214 jumpr r31 215 } 216.Ldenorm: 217 { 218 mantexpa = minmin 219 jumpr r31 220 } 221/* ==================================================================== * 222 fast2_QDOUBLE fast2_dmpy(fast2_QDOUBLE a,fast2_QDOUBLE b) { 223 fast2_QDOUBLE c; 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) ; 228 int exp, k; 229 lint mant; 230 int hia, hib, hi, lo; 231 unsigned int loa, lob; 232 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); 237 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); 241 242 hi = (int) (mant>>32); 243 244 k = Q6_R_normamt_R(hi); 245 mant = mant << k; 246 exp = expa + expb - k; 247 if (mant == 0 || mant == -1) exp = 0x8001; 248 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 249 return(c); 250 } 251 * ==================================================================== */ 252 .text 253 .global fast2_dmpy_asm 254 .type fast2_dmpy_asm, @function 255fast2_dmpy_asm: 256 257#define mantal R0 258#define mantah R1 259#define mantexpa R1:0 260#define mantbl R2 261#define mantbh R3 262#define mantexpb R3:2 263#define expa R4 264#define expb R5 265#define c8001 R12 266#define mantexpd R7:6 267#define mantdh R7 268#define exp R8 269#define lmantc R11:10 270#define kb R9 271#define guard R11 272#define mantal_ R12 273#define mantbl_ R13 274#define min R15:14 275#define minh R15 276 277 .falign 278 { 279 mantbl_= lsr(mantbl, #16) 280 expb = sxth(mantbl) 281 expa = sxth(mantal) 282 mantal_= lsr(mantal, #16) 283 } 284 { 285 lmantc = mpy(mantah, mantbh) 286 mantexpd = mpy(mantah, mantbl_) 287 mantal.L = #0x0 288 min = #0 289 } 290 { 291 lmantc = add(lmantc, lmantc) 292 mantexpd+= mpy(mantbh, mantal_) 293 mantbl.L = #0x0 294 minh.H = #0x8000 295 } 296 { 297 mantexpd = asr(mantexpd, #15) 298 c8001.L = #0x8001 299 p1 = cmp.eq(mantexpa, mantexpb) 300 } 301 { 302 mantexpd = add(mantexpd, lmantc) 303 exp = add(expa, expb) 304 p2 = cmp.eq(mantexpa, min) 305 } 306 { 307 kb = clb(mantexpd) 308 mantexpb = abs(mantexpd) 309 guard = #58 310 } 311 { 312 p1 = and(p1, p2) 313 exp = sub(exp, kb) 314 kb = add(kb, #-1) 315 p0 = cmp.gt(kb, guard) 316 } 317 { 318 exp = add(exp, #1) 319 mantexpa = asl(mantexpd, kb) 320 if(p1) jump .Lsat //rarely happens 321 } 322 { 323 mantal = insert(exp,#16, #0) 324 if(!p0) jumpr r31 325 } 326 { 327 mantal = insert(c8001,#16, #0) 328 jumpr r31 329 } 330.Lsat: 331 { 332 mantexpa = #-1 333 } 334 { 335 mantexpa = lsr(mantexpa, #1) 336 } 337 { 338 mantal = insert(exp,#16, #0) 339 jumpr r31 340 } 341 342/* ==================================================================== * 343 int fast2_qd2f(fast2_QDOUBLE a) { 344 int exp; 345 long long int manta; 346 int ic, rnd, mantb; 347 348 manta = a>>32; 349 exp = Q6_R_sxth_R(a) ; 350 ic = 0x80000000 & manta; 351 manta = Q6_R_abs_R_sat(manta); 352 mantb = (manta + rnd)>>7; 353 rnd = 0x40 354 exp = (exp + 126); 355 if((manta & 0xff) == rnd) rnd = 0x00; 356 if((manta & 0x7fffffc0) == 0x7fffffc0) { 357 manta = 0x0; exp++; 358 } else { 359 manta= mantb & 0x007fffff; 360 } 361 exp = (exp << 23) & 0x7fffffc0; 362 ic = Q6_R_addacc_RR(ic, exp, manta); 363 return (ic); 364 } 365 * ==================================================================== */ 366 367 .text 368 .global fast2_qd2f_asm 369 .type fast2_qd2f_asm, @function 370fast2_qd2f_asm: 371#define mantah R1 372#define mantal R0 373#define cff R0 374#define mant R3 375#define expo R4 376#define rnd R5 377#define mask R6 378#define c07f R7 379#define c80 R0 380#define mantb R2 381#define ic R0 382 383 .falign 384 { 385 mant = abs(mantah):sat 386 expo = sxth(mantal) 387 rnd = #0x40 388 mask.L = #0xffc0 389 } 390 { 391 cff = extractu(mant, #8, #0) 392 p2 = cmp.gt(expo, #126) 393 p3 = cmp.ge(expo, #-126) 394 mask.H = #0x7fff 395 } 396 { 397 p1 = cmp.eq(cff,#0x40) 398 if(p1.new) rnd = #0 399 expo = add(expo, #126) 400 if(!p3) jump .Lmin 401 } 402 { 403 p0 = bitsset(mant, mask) 404 c80.L = #0x0000 405 mantb = add(mant, rnd) 406 c07f = lsr(mask, #8) 407 } 408 { 409 if(p0) expo = add(expo, #1) 410 if(p0) mant = #0 411 mantb = lsr(mantb, #7) 412 c80.H = #0x8000 413 } 414 { 415 ic = and(c80, mantah) 416 mask &= asl(expo, #23) 417 if(!p0) mant = and(mantb, c07f) 418 if(p2) jump .Lmax 419 } 420 { 421 ic += add(mask, mant) 422 jumpr r31 423 } 424.Lmax: 425 { 426 ic.L = #0xffff; 427 } 428 { 429 ic.H = #0x7f7f; 430 jumpr r31 431 } 432.Lmin: 433 { 434 ic = #0x0 435 jumpr r31 436 } 437 438/* ==================================================================== * 439fast2_QDOUBLE fast2_f2qd(int ia) { 440 lint exp; 441 lint mant; 442 fast2_QDOUBLE c; 443 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);; 448 return(c); 449} 450 * ==================================================================== */ 451 .text 452 .global fast2_f2qd_asm 453 .type fast2_f2qd_asm, @function 454fast2_f2qd_asm: 455#define ia R0 456#define mag R3 457#define mantr R1 458#define expr R0 459#define zero R2 460#define maxneg R5:4 461#define maxnegl R4 462 .falign 463 { 464 mantr = asl(ia, #7) 465 p0 = tstbit(ia, #31) 466 maxneg = #0 467 mag = add(ia,ia) 468 } 469 { 470 mantr = setbit(mantr, #30) 471 expr= extractu(ia,#8,#23) 472 maxnegl.L = #0x8001 473 p1 = cmp.eq(mag, #0) 474 } 475 { 476 mantr= extractu(mantr, #31, #0) 477 expr= add(expr, #-126) 478 zero = #0 479 if(p1) jump .Lminqd 480 } 481 { 482 expr = zxth(expr) 483 if(p0) mantr= sub(zero, mantr) 484 jumpr r31 485 } 486.Lminqd: 487 { 488 R1:0 = maxneg 489 jumpr r31 490 } 491