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
 |