| //===----------------------Hexagon builtin routine ------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /* ==================================================================== */ |
| /* FUNCTIONS Optimized double floating point operators */ |
| /* ==================================================================== */ |
| /* c = dadd_asm(a, b) */ |
| /* ==================================================================== |
| |
| QDOUBLE dadd(QDOUBLE a,QDOUBLE b) { |
| QDOUBLE c; |
| lint manta = a & MANTMASK; |
| int expa = HEXAGON_R_sxth_R(a) ; |
| lint mantb = b & MANTMASK; |
| int expb = HEXAGON_R_sxth_R(b) ; |
| int exp, expdiff, j, k, hi, lo, cn; |
| lint mant; |
| |
| expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b); |
| expdiff = HEXAGON_R_sxth_R(expdiff) ; |
| if (expdiff > 63) { expdiff = 62;} |
| if (expa > expb) { |
| exp = expa + 1; |
| expa = 1; |
| expb = expdiff + 1; |
| } else { |
| exp = expb + 1; |
| expb = 1; |
| expa = expdiff + 1; |
| } |
| mant = (manta>>expa) + (mantb>>expb); |
| |
| hi = (int) (mant>>32); |
| lo = (int) (mant); |
| |
| k = HEXAGON_R_normamt_R(hi); |
| if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo); |
| |
| mant = (mant << k); |
| cn = (mant == 0x8000000000000000LL); |
| exp = exp - k + cn; |
| |
| if (mant == 0 || mant == -1) exp = 0x8001; |
| c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); |
| return(c); |
| } |
| * ==================================================================== */ |
| .text |
| .global dadd_asm |
| .type dadd_asm, @function |
| dadd_asm: |
| |
| #define manta R0 |
| #define mantexpa R1:0 |
| #define lmanta R1:0 |
| #define mantb R2 |
| #define mantexpb R3:2 |
| #define lmantb R3:2 |
| #define expa R4 |
| #define expb R5 |
| #define mantexpd R7:6 |
| #define expd R6 |
| #define exp R8 |
| #define c63 R9 |
| #define lmant R1:0 |
| #define manth R1 |
| #define mantl R0 |
| #define zero R7:6 |
| #define zerol R6 |
| #define minus R3:2 |
| #define minusl R2 |
| #define maxneg R9 |
| #define minmin R11:10 // exactly 0x800000000000000000LL |
| #define minminh R11 |
| #define k R4 |
| #define kl R5 |
| #define ce P0 |
| .falign |
| { |
| mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL |
| c63 = #62 |
| expa = SXTH(manta) |
| expb = SXTH(mantb) |
| } { |
| expd = SXTH(expd) |
| ce = CMP.GT(expa, expb); |
| if ( ce.new) exp = add(expa, #1) |
| if (!ce.new) exp = add(expb, #1) |
| } { |
| if ( ce) expa = #1 |
| if (!ce) expb = #1 |
| manta.L = #0 |
| expd = MIN(expd, c63) |
| } { |
| if (!ce) expa = add(expd, #1) |
| if ( ce) expb = add(expd, #1) |
| mantb.L = #0 |
| zero = #0 |
| } { |
| lmanta = ASR(lmanta, expa) |
| lmantb = ASR(lmantb, expb) |
| minmin = #0 |
| } { |
| lmant = add(lmanta, lmantb) |
| minus = #-1 |
| minminh.H = #0x8000 |
| } { |
| k = NORMAMT(manth) |
| kl = NORMAMT(mantl) |
| p0 = cmp.eq(manth, zerol) |
| p1 = cmp.eq(manth, minusl) |
| } { |
| p0 = OR(p0, p1) |
| if(p0.new) k = add(kl, #31) |
| maxneg.H = #0 |
| } { |
| mantexpa = ASL(lmant, k) |
| exp = SUB(exp, k) |
| maxneg.L = #0x8001 |
| } { |
| p0 = cmp.eq(mantexpa, zero) |
| p1 = cmp.eq(mantexpa, minus) |
| manta.L = #0 |
| exp = ZXTH(exp) |
| } { |
| p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0 |
| if(p2.new) exp = add(exp, #1) |
| } |
| #if (__HEXAGON_ARCH__ == 60) |
| { |
| p0 = OR(p0, p1) |
| if( p0.new) manta = OR(manta,maxneg) |
| if(!p0.new) manta = OR(manta,exp) |
| } |
| jumpr r31 |
| #else |
| { |
| p0 = OR(p0, p1) |
| if( p0.new) manta = OR(manta,maxneg) |
| if(!p0.new) manta = OR(manta,exp) |
| jumpr r31 |
| } |
| #endif |
| /* =================================================================== * |
| QDOUBLE dsub(QDOUBLE a,QDOUBLE b) { |
| QDOUBLE c; |
| lint manta = a & MANTMASK; |
| int expa = HEXAGON_R_sxth_R(a) ; |
| lint mantb = b & MANTMASK; |
| int expb = HEXAGON_R_sxth_R(b) ; |
| int exp, expdiff, j, k, hi, lo, cn; |
| lint mant; |
| |
| expdiff = (int) HEXAGON_P_vabsdiffh_PP(a, b); |
| expdiff = HEXAGON_R_sxth_R(expdiff) ; |
| if (expdiff > 63) { expdiff = 62;} |
| if (expa > expb) { |
| exp = expa + 1; |
| expa = 1; |
| expb = expdiff + 1; |
| } else { |
| exp = expb + 1; |
| expb = 1; |
| expa = expdiff + 1; |
| } |
| mant = (manta>>expa) - (mantb>>expb); |
| |
| hi = (int) (mant>>32); |
| lo = (int) (mant); |
| |
| k = HEXAGON_R_normamt_R(hi); |
| if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo); |
| |
| mant = (mant << k); |
| cn = (mant == 0x8000000000000000LL); |
| exp = exp - k + cn; |
| |
| if (mant == 0 || mant == -1) exp = 0x8001; |
| c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); |
| return(c); |
| } |
| * ==================================================================== */ |
| .text |
| .global dsub_asm |
| .type dsub_asm, @function |
| dsub_asm: |
| |
| #define manta R0 |
| #define mantexpa R1:0 |
| #define lmanta R1:0 |
| #define mantb R2 |
| #define mantexpb R3:2 |
| #define lmantb R3:2 |
| #define expa R4 |
| #define expb R5 |
| #define mantexpd R7:6 |
| #define expd R6 |
| #define exp R8 |
| #define c63 R9 |
| #define lmant R1:0 |
| #define manth R1 |
| #define mantl R0 |
| #define zero R7:6 |
| #define zerol R6 |
| #define minus R3:2 |
| #define minusl R2 |
| #define maxneg R9 |
| #define minmin R11:10 // exactly 0x800000000000000000LL |
| #define minminh R11 |
| #define k R4 |
| #define kl R5 |
| #define ce P0 |
| .falign |
| { |
| mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL |
| c63 = #62 |
| expa = SXTH(manta) |
| expb = SXTH(mantb) |
| } { |
| expd = SXTH(expd) |
| ce = CMP.GT(expa, expb); |
| if ( ce.new) exp = add(expa, #1) |
| if (!ce.new) exp = add(expb, #1) |
| } { |
| if ( ce) expa = #1 |
| if (!ce) expb = #1 |
| manta.L = #0 |
| expd = MIN(expd, c63) |
| } { |
| if (!ce) expa = add(expd, #1) |
| if ( ce) expb = add(expd, #1) |
| mantb.L = #0 |
| zero = #0 |
| } { |
| lmanta = ASR(lmanta, expa) |
| lmantb = ASR(lmantb, expb) |
| minmin = #0 |
| } { |
| lmant = sub(lmanta, lmantb) |
| minus = #-1 |
| minminh.H = #0x8000 |
| } { |
| k = NORMAMT(manth) |
| kl = NORMAMT(mantl) |
| p0 = cmp.eq(manth, zerol) |
| p1 = cmp.eq(manth, minusl) |
| } { |
| p0 = OR(p0, p1) |
| if(p0.new) k = add(kl, #31) |
| maxneg.H = #0 |
| } { |
| mantexpa = ASL(lmant, k) |
| exp = SUB(exp, k) |
| maxneg.L = #0x8001 |
| } { |
| p0 = cmp.eq(mantexpa, zero) |
| p1 = cmp.eq(mantexpa, minus) |
| manta.L = #0 |
| exp = ZXTH(exp) |
| } { |
| p2 = cmp.eq(mantexpa, minmin) //is result 0x80....0 |
| if(p2.new) exp = add(exp, #1) |
| } |
| #if (__HEXAGON_ARCH__ == 60) |
| { |
| p0 = OR(p0, p1) |
| if( p0.new) manta = OR(manta,maxneg) |
| if(!p0.new) manta = OR(manta,exp) |
| } |
| jumpr r31 |
| #else |
| { |
| p0 = OR(p0, p1) |
| if( p0.new) manta = OR(manta,maxneg) |
| if(!p0.new) manta = OR(manta,exp) |
| jumpr r31 |
| } |
| #endif |
| /* ==================================================================== * |
| QDOUBLE dmpy(QDOUBLE a,QDOUBLE b) { |
| QDOUBLE c; |
| lint manta = a & MANTMASK; |
| int expa = HEXAGON_R_sxth_R(a) ; |
| lint mantb = b & MANTMASK; |
| int expb = HEXAGON_R_sxth_R(b) ; |
| int exp, k; |
| lint mant; |
| int hia, hib, hi, lo; |
| unsigned int loa, lob; |
| |
| hia = (int)(a >> 32); |
| loa = HEXAGON_R_extractu_RII((int)manta, 31, 1); |
| hib = (int)(b >> 32); |
| lob = HEXAGON_R_extractu_RII((int)mantb, 31, 1); |
| |
| mant = HEXAGON_P_mpy_RR(hia, lob); |
| mant = HEXAGON_P_mpyacc_RR(mant,hib, loa); |
| mant = (mant >> 30) + (HEXAGON_P_mpy_RR(hia, hib)<<1); |
| |
| hi = (int) (mant>>32); |
| lo = (int) (mant); |
| |
| k = HEXAGON_R_normamt_R(hi); |
| if(hi == 0 || hi == -1) k = 31+HEXAGON_R_normamt_R(lo); |
| mant = mant << k; |
| exp = expa + expb - k; |
| if (mant == 0 || mant == -1) exp = 0x8001; |
| c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); |
| return(c); |
| } |
| * ==================================================================== */ |
| .text |
| .global dmpy_asm |
| .type dmpy_asm, @function |
| dmpy_asm: |
| |
| #define mantal R0 |
| #define mantah R1 |
| #define mantexpa R1:0 |
| #define mantbl R2 |
| #define mantbh R3 |
| #define mantexpb R3:2 |
| #define expa R4 |
| #define expb R5 |
| #define mantexpd R7:6 |
| #define exp R8 |
| #define lmantc R11:10 |
| #define mantch R11 |
| #define mantcl R10 |
| #define zero0 R7:6 |
| #define zero0l R6 |
| #define minus1 R3:2 |
| #define minus1l R2 |
| #define maxneg R9 |
| #define k R4 |
| #define kl R5 |
| |
| .falign |
| { |
| mantbl = lsr(mantbl, #16) |
| mantal = lsr(mantal, #16) |
| expa = sxth(mantal) |
| expb = sxth(mantbl) |
| } |
| { |
| lmantc = mpy(mantah, mantbh) |
| mantexpd = mpy(mantah, mantbl) |
| } |
| { |
| lmantc = add(lmantc, lmantc) //<<1 |
| mantexpd+= mpy(mantbh, mantal) |
| } |
| { |
| lmantc += asr(mantexpd, #15) |
| exp = add(expa, expb) |
| zero0 = #0 |
| minus1 = #-1 |
| } |
| { |
| k = normamt(mantch) |
| kl = normamt(mantcl) |
| p0 = cmp.eq(mantch, zero0l) |
| p1 = cmp.eq(mantch, minus1l) |
| } |
| { |
| p0 = or(p0, p1) |
| if(p0.new) k = add(kl, #31) |
| maxneg.H = #0 |
| } |
| { |
| mantexpa = asl(lmantc, k) |
| exp = sub(exp, k) |
| maxneg.L = #0x8001 |
| } |
| { |
| p0 = cmp.eq(mantexpa, zero0) |
| p1 = cmp.eq(mantexpa, minus1) |
| mantal.L = #0 |
| exp = zxth(exp) |
| } |
| #if (__HEXAGON_ARCH__ == 60) |
| { |
| p0 = or(p0, p1) |
| if( p0.new) mantal = or(mantal,maxneg) |
| if(!p0.new) mantal = or(mantal,exp) |
| } |
| jumpr r31 |
| #else |
| { |
| p0 = or(p0, p1) |
| if( p0.new) mantal = or(mantal,maxneg) |
| if(!p0.new) mantal = or(mantal,exp) |
| jumpr r31 |
| } |
| #endif |