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/* ==================================================================== 13 14QDOUBLE dadd(QDOUBLE a,QDOUBLE b) { 15 QDOUBLE c; 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; 21 lint mant; 22 23 expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b); 24 expdiff = HEXAGON_R_sxth_R(expdiff) ; 25 if (expdiff > 63) { expdiff = 62;} 26 if (expa > expb) { 27 exp = expa + 1; 28 expa = 1; 29 expb = expdiff + 1; 30 } else { 31 exp = expb + 1; 32 expb = 1; 33 expa = expdiff + 1; 34 } 35 mant = (manta>>expa) + (mantb>>expb); 36 37 hi = (int) (mant>>32); 38 lo = (int) (mant); 39 40 k = HEXAGON_R_normamt_R(hi); 41 if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo); 42 43 mant = (mant << k); 44 cn = (mant == 0x8000000000000000LL); 45 exp = exp - k + cn; 46 47 if (mant == 0 || mant == -1) exp = 0x8001; 48 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 49 return(c); 50 } 51 * ==================================================================== */ 52 .text 53 .global dadd_asm 54 .type dadd_asm, @function 55dadd_asm: 56 57#define manta R0 58#define mantexpa R1:0 59#define lmanta R1:0 60#define mantb R2 61#define mantexpb R3:2 62#define lmantb R3:2 63#define expa R4 64#define expb R5 65#define mantexpd R7:6 66#define expd R6 67#define exp R8 68#define c63 R9 69#define lmant R1:0 70#define manth R1 71#define mantl R0 72#define zero R7:6 73#define zerol R6 74#define minus R3:2 75#define minusl R2 76#define maxneg R9 77#define minmin R11:10 // exactly 0x800000000000000000LL 78#define minminh R11 79#define k R4 80#define kl R5 81#define ce P0 82 .falign 83 { 84 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL 85 c63 = #62 86 expa = SXTH(manta) 87 expb = SXTH(mantb) 88 } { 89 expd = SXTH(expd) 90 ce = CMP.GT(expa, expb); 91 if ( ce.new) exp = add(expa, #1) 92 if (!ce.new) exp = add(expb, #1) 93 } { 94 if ( ce) expa = #1 95 if (!ce) expb = #1 96 manta.L = #0 97 expd = MIN(expd, c63) 98 } { 99 if (!ce) expa = add(expd, #1) 100 if ( ce) expb = add(expd, #1) 101 mantb.L = #0 102 zero = #0 103 } { 104 lmanta = ASR(lmanta, expa) 105 lmantb = ASR(lmantb, expb) 106 minmin = #0 107 } { 108 lmant = add(lmanta, lmantb) 109 minus = #-1 110 minminh.H = #0x8000 111 } { 112 k = NORMAMT(manth) 113 kl = NORMAMT(mantl) 114 p0 = cmp.eq(manth, zerol) 115 p1 = cmp.eq(manth, minusl) 116 } { 117 p0 = OR(p0, p1) 118 if(p0.new) k = add(kl, #31) 119 maxneg.H = #0 120 } { 121 mantexpa = ASL(lmant, k) 122 exp = SUB(exp, k) 123 maxneg.L = #0x8001 124 } { 125 p0 = cmp.eq(mantexpa, zero) 126 p1 = cmp.eq(mantexpa, minus) 127 manta.L = #0 128 exp = ZXTH(exp) 129 } { 130 p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0 131 if(p2.new) exp = add(exp, #1) 132 } 133#if (__HEXAGON_ARCH__ == 60) 134 { 135 p0 = OR(p0, p1) 136 if( p0.new) manta = OR(manta,maxneg) 137 if(!p0.new) manta = OR(manta,exp) 138 } 139 jumpr r31 140#else 141 { 142 p0 = OR(p0, p1) 143 if( p0.new) manta = OR(manta,maxneg) 144 if(!p0.new) manta = OR(manta,exp) 145 jumpr r31 146 } 147#endif 148/* =================================================================== * 149 QDOUBLE dsub(QDOUBLE a,QDOUBLE b) { 150 QDOUBLE c; 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; 156 lint mant; 157 158 expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b); 159 expdiff = HEXAGON_R_sxth_R(expdiff) ; 160 if (expdiff > 63) { expdiff = 62;} 161 if (expa > expb) { 162 exp = expa + 1; 163 expa = 1; 164 expb = expdiff + 1; 165 } else { 166 exp = expb + 1; 167 expb = 1; 168 expa = expdiff + 1; 169 } 170 mant = (manta>>expa) - (mantb>>expb); 171 172 hi = (int) (mant>>32); 173 lo = (int) (mant); 174 175 k = HEXAGON_R_normamt_R(hi); 176 if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo); 177 178 mant = (mant << k); 179 cn = (mant == 0x8000000000000000LL); 180 exp = exp - k + cn; 181 182 if (mant == 0 || mant == -1) exp = 0x8001; 183 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 184 return(c); 185 } 186 * ==================================================================== */ 187 .text 188 .global dsub_asm 189 .type dsub_asm, @function 190dsub_asm: 191 192#define manta R0 193#define mantexpa R1:0 194#define lmanta R1:0 195#define mantb R2 196#define mantexpb R3:2 197#define lmantb R3:2 198#define expa R4 199#define expb R5 200#define mantexpd R7:6 201#define expd R6 202#define exp R8 203#define c63 R9 204#define lmant R1:0 205#define manth R1 206#define mantl R0 207#define zero R7:6 208#define zerol R6 209#define minus R3:2 210#define minusl R2 211#define maxneg R9 212#define minmin R11:10 // exactly 0x800000000000000000LL 213#define minminh R11 214#define k R4 215#define kl R5 216#define ce P0 217 .falign 218 { 219 mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL 220 c63 = #62 221 expa = SXTH(manta) 222 expb = SXTH(mantb) 223 } { 224 expd = SXTH(expd) 225 ce = CMP.GT(expa, expb); 226 if ( ce.new) exp = add(expa, #1) 227 if (!ce.new) exp = add(expb, #1) 228 } { 229 if ( ce) expa = #1 230 if (!ce) expb = #1 231 manta.L = #0 232 expd = MIN(expd, c63) 233 } { 234 if (!ce) expa = add(expd, #1) 235 if ( ce) expb = add(expd, #1) 236 mantb.L = #0 237 zero = #0 238 } { 239 lmanta = ASR(lmanta, expa) 240 lmantb = ASR(lmantb, expb) 241 minmin = #0 242 } { 243 lmant = sub(lmanta, lmantb) 244 minus = #-1 245 minminh.H = #0x8000 246 } { 247 k = NORMAMT(manth) 248 kl = NORMAMT(mantl) 249 p0 = cmp.eq(manth, zerol) 250 p1 = cmp.eq(manth, minusl) 251 } { 252 p0 = OR(p0, p1) 253 if(p0.new) k = add(kl, #31) 254 maxneg.H = #0 255 } { 256 mantexpa = ASL(lmant, k) 257 exp = SUB(exp, k) 258 maxneg.L = #0x8001 259 } { 260 p0 = cmp.eq(mantexpa, zero) 261 p1 = cmp.eq(mantexpa, minus) 262 manta.L = #0 263 exp = ZXTH(exp) 264 } { 265 p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0 266 if(p2.new) exp = add(exp, #1) 267 } 268#if (__HEXAGON_ARCH__ == 60) 269 { 270 p0 = OR(p0, p1) 271 if( p0.new) manta = OR(manta,maxneg) 272 if(!p0.new) manta = OR(manta,exp) 273 } 274 jumpr r31 275#else 276 { 277 p0 = OR(p0, p1) 278 if( p0.new) manta = OR(manta,maxneg) 279 if(!p0.new) manta = OR(manta,exp) 280 jumpr r31 281 } 282#endif 283/* ==================================================================== * 284 QDOUBLE dmpy(QDOUBLE a,QDOUBLE b) { 285 QDOUBLE c; 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) ; 290 int exp, k; 291 lint mant; 292 int hia, hib, hi, lo; 293 unsigned int loa, lob; 294 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); 299 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); 303 304 hi = (int) (mant>>32); 305 lo = (int) (mant); 306 307 k = HEXAGON_R_normamt_R(hi); 308 if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo); 309 mant = mant << k; 310 exp = expa + expb - k; 311 if (mant == 0 || mant == -1) exp = 0x8001; 312 c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 313 return(c); 314 } 315 * ==================================================================== */ 316 .text 317 .global dmpy_asm 318 .type dmpy_asm, @function 319dmpy_asm: 320 321#define mantal R0 322#define mantah R1 323#define mantexpa R1:0 324#define mantbl R2 325#define mantbh R3 326#define mantexpb R3:2 327#define expa R4 328#define expb R5 329#define mantexpd R7:6 330#define exp R8 331#define lmantc R11:10 332#define mantch R11 333#define mantcl R10 334#define zero0 R7:6 335#define zero0l R6 336#define minus1 R3:2 337#define minus1l R2 338#define maxneg R9 339#define k R4 340#define kl R5 341 342 .falign 343 { 344 mantbl = lsr(mantbl, #16) 345 mantal = lsr(mantal, #16) 346 expa = sxth(mantal) 347 expb = sxth(mantbl) 348 } 349 { 350 lmantc = mpy(mantah, mantbh) 351 mantexpd = mpy(mantah, mantbl) 352 } 353 { 354 lmantc = add(lmantc, lmantc) //<<1 355 mantexpd+= mpy(mantbh, mantal) 356 } 357 { 358 lmantc += asr(mantexpd, #15) 359 exp = add(expa, expb) 360 zero0 = #0 361 minus1 = #-1 362 } 363 { 364 k = normamt(mantch) 365 kl = normamt(mantcl) 366 p0 = cmp.eq(mantch, zero0l) 367 p1 = cmp.eq(mantch, minus1l) 368 } 369 { 370 p0 = or(p0, p1) 371 if(p0.new) k = add(kl, #31) 372 maxneg.H = #0 373 } 374 { 375 mantexpa = asl(lmantc, k) 376 exp = sub(exp, k) 377 maxneg.L = #0x8001 378 } 379 { 380 p0 = cmp.eq(mantexpa, zero0) 381 p1 = cmp.eq(mantexpa, minus1) 382 mantal.L = #0 383 exp = zxth(exp) 384 } 385#if (__HEXAGON_ARCH__ == 60) 386 { 387 p0 = or(p0, p1) 388 if( p0.new) mantal = or(mantal,maxneg) 389 if(!p0.new) mantal = or(mantal,exp) 390 } 391 jumpr r31 392#else 393 { 394 p0 = or(p0, p1) 395 if( p0.new) mantal = or(mantal,maxneg) 396 if(!p0.new) mantal = or(mantal,exp) 397 jumpr r31 398 } 399#endif 400