to reflect the new license. These used slightly different spellings that defeated my regular expressions. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351648
400 lines
10 KiB
ArmAsm
400 lines
10 KiB
ArmAsm
//===----------------------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
|