Files
llvm-project/compiler-rt/lib/builtins/hexagon/fastmath_dlib_asm.S
Chandler Carruth 57b08b0944 Update more file headers across all of the LLVM projects in the monorepo
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
2019-01-19 10:56:40 +00:00

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