diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-10-16 12:11:24 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-10-16 12:11:24 +0000 |
commit | 40811e93f3fdf9342a9295369994012420fac548 (patch) | |
tree | a8d85e094a9c21e10aa250f537c101fc2016a049 /contrib/libs/cxxsupp/builtins/hexagon/fastmath_dlib_asm.S | |
parent | 30ebe5357bb143648c6be4d151ecd4944af81ada (diff) | |
parent | 28a0c4a9f297064538a018c512cd9bbd00a1a35d (diff) | |
download | ydb-40811e93f3fdf9342a9295369994012420fac548.tar.gz |
Merge branch 'rightlib' into mergelibs-241016-1210
Diffstat (limited to 'contrib/libs/cxxsupp/builtins/hexagon/fastmath_dlib_asm.S')
-rw-r--r-- | contrib/libs/cxxsupp/builtins/hexagon/fastmath_dlib_asm.S | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/contrib/libs/cxxsupp/builtins/hexagon/fastmath_dlib_asm.S b/contrib/libs/cxxsupp/builtins/hexagon/fastmath_dlib_asm.S new file mode 100644 index 0000000000..3e59526c1e --- /dev/null +++ b/contrib/libs/cxxsupp/builtins/hexagon/fastmath_dlib_asm.S @@ -0,0 +1,399 @@ +//===----------------------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 |