1*0b57cec5SDimitry Andric//===----------------------Hexagon builtin routine ------------------------===// 2*0b57cec5SDimitry Andric// 3*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric// 7*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric/* ==================================================================== */ 9*0b57cec5SDimitry Andric/* FUNCTIONS Optimized double floating point operators */ 10*0b57cec5SDimitry Andric/* ==================================================================== */ 11*0b57cec5SDimitry Andric/* c = dadd_asm(a, b) */ 12*0b57cec5SDimitry Andric/* ==================================================================== * 13*0b57cec5SDimitry Andricfast2_QDOUBLE fast2_dadd(fast2_QDOUBLE a,fast2_QDOUBLE b) { 14*0b57cec5SDimitry Andric fast2_QDOUBLE c; 15*0b57cec5SDimitry Andric lint manta = a & MANTMASK; 16*0b57cec5SDimitry Andric int expa = Q6_R_sxth_R(a) ; 17*0b57cec5SDimitry Andric lint mantb = b & MANTMASK; 18*0b57cec5SDimitry Andric int expb = Q6_R_sxth_R(b) ; 19*0b57cec5SDimitry Andric int exp, expdiff, j, k, hi, lo, cn; 20*0b57cec5SDimitry Andric lint mant; 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 23*0b57cec5SDimitry Andric expdiff = Q6_R_sxth_R(expdiff) ; 24*0b57cec5SDimitry Andric if (expdiff > 63) { expdiff = 62;} 25*0b57cec5SDimitry Andric if (expa > expb) { 26*0b57cec5SDimitry Andric exp = expa + 1; 27*0b57cec5SDimitry Andric expa = 1; 28*0b57cec5SDimitry Andric expb = expdiff + 1; 29*0b57cec5SDimitry Andric } else { 30*0b57cec5SDimitry Andric exp = expb + 1; 31*0b57cec5SDimitry Andric expb = 1; 32*0b57cec5SDimitry Andric expa = expdiff + 1; 33*0b57cec5SDimitry Andric } 34*0b57cec5SDimitry Andric mant = (manta>>expa) + (mantb>>expb); 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric hi = (int) (mant>>32); 37*0b57cec5SDimitry Andric lo = (int) (mant); 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric k = Q6_R_normamt_R(hi); 40*0b57cec5SDimitry Andric if(hi == 0 || hi == -1) k = 31+Q6_R_normamt_R(lo); 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric mant = (mant << k); 43*0b57cec5SDimitry Andric cn = (mant == 0x8000000000000000LL); 44*0b57cec5SDimitry Andric exp = exp - k + cn; 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric if (mant == 0 || mant == -1) exp = 0x8001; 47*0b57cec5SDimitry Andric c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 48*0b57cec5SDimitry Andric return(c); 49*0b57cec5SDimitry Andric } 50*0b57cec5SDimitry Andric * ==================================================================== */ 51*0b57cec5SDimitry Andric .text 52*0b57cec5SDimitry Andric .global fast2_dadd_asm 53*0b57cec5SDimitry Andric .type fast2_dadd_asm, @function 54*0b57cec5SDimitry Andricfast2_dadd_asm: 55*0b57cec5SDimitry Andric#define manta R0 56*0b57cec5SDimitry Andric#define mantexpa R1:0 57*0b57cec5SDimitry Andric#define lmanta R1:0 58*0b57cec5SDimitry Andric#define mantb R2 59*0b57cec5SDimitry Andric#define mantexpb R3:2 60*0b57cec5SDimitry Andric#define lmantb R3:2 61*0b57cec5SDimitry Andric#define expa R4 62*0b57cec5SDimitry Andric#define expb R5 63*0b57cec5SDimitry Andric#define mantexpd R7:6 64*0b57cec5SDimitry Andric#define expd R6 65*0b57cec5SDimitry Andric#define exp R8 66*0b57cec5SDimitry Andric#define c63 R9 67*0b57cec5SDimitry Andric#define lmant R1:0 68*0b57cec5SDimitry Andric#define manth R1 69*0b57cec5SDimitry Andric#define mantl R0 70*0b57cec5SDimitry Andric#define minmin R11:10 // exactly 0x000000000000008001LL 71*0b57cec5SDimitry Andric#define minminl R10 72*0b57cec5SDimitry Andric#define k R4 73*0b57cec5SDimitry Andric#define ce P0 74*0b57cec5SDimitry Andric .falign 75*0b57cec5SDimitry Andric { 76*0b57cec5SDimitry Andric mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL 77*0b57cec5SDimitry Andric c63 = #62 78*0b57cec5SDimitry Andric expa = SXTH(manta) 79*0b57cec5SDimitry Andric expb = SXTH(mantb) 80*0b57cec5SDimitry Andric } { 81*0b57cec5SDimitry Andric expd = SXTH(expd) 82*0b57cec5SDimitry Andric ce = CMP.GT(expa, expb); 83*0b57cec5SDimitry Andric if ( ce.new) exp = add(expa, #1) 84*0b57cec5SDimitry Andric if (!ce.new) exp = add(expb, #1) 85*0b57cec5SDimitry Andric } { 86*0b57cec5SDimitry Andric if ( ce) expa = #1 87*0b57cec5SDimitry Andric if (!ce) expb = #1 88*0b57cec5SDimitry Andric manta.L = #0 89*0b57cec5SDimitry Andric expd = MIN(expd, c63) 90*0b57cec5SDimitry Andric } { 91*0b57cec5SDimitry Andric if (!ce) expa = add(expd, #1) 92*0b57cec5SDimitry Andric if ( ce) expb = add(expd, #1) 93*0b57cec5SDimitry Andric mantb.L = #0 94*0b57cec5SDimitry Andric minmin = #0 95*0b57cec5SDimitry Andric } { 96*0b57cec5SDimitry Andric lmanta = ASR(lmanta, expa) 97*0b57cec5SDimitry Andric lmantb = ASR(lmantb, expb) 98*0b57cec5SDimitry Andric } { 99*0b57cec5SDimitry Andric lmant = add(lmanta, lmantb) 100*0b57cec5SDimitry Andric minminl.L = #0x8001 101*0b57cec5SDimitry Andric } { 102*0b57cec5SDimitry Andric k = clb(lmant) 103*0b57cec5SDimitry Andric c63 = #58 104*0b57cec5SDimitry Andric } { 105*0b57cec5SDimitry Andric k = add(k, #-1) 106*0b57cec5SDimitry Andric p0 = cmp.gt(k, c63) 107*0b57cec5SDimitry Andric } { 108*0b57cec5SDimitry Andric mantexpa = ASL(lmant, k) 109*0b57cec5SDimitry Andric exp = SUB(exp, k) 110*0b57cec5SDimitry Andric if(p0) jump .Ldenorma 111*0b57cec5SDimitry Andric } { 112*0b57cec5SDimitry Andric manta = insert(exp, #16, #0) 113*0b57cec5SDimitry Andric jumpr r31 114*0b57cec5SDimitry Andric } 115*0b57cec5SDimitry Andric.Ldenorma: 116*0b57cec5SDimitry Andric { 117*0b57cec5SDimitry Andric mantexpa = minmin 118*0b57cec5SDimitry Andric jumpr r31 119*0b57cec5SDimitry Andric } 120*0b57cec5SDimitry Andric/* =================================================================== * 121*0b57cec5SDimitry Andric fast2_QDOUBLE fast2_dsub(fast2_QDOUBLE a,fast2_QDOUBLE b) { 122*0b57cec5SDimitry Andric fast2_QDOUBLE c; 123*0b57cec5SDimitry Andric lint manta = a & MANTMASK; 124*0b57cec5SDimitry Andric int expa = Q6_R_sxth_R(a) ; 125*0b57cec5SDimitry Andric lint mantb = b & MANTMASK; 126*0b57cec5SDimitry Andric int expb = Q6_R_sxth_R(b) ; 127*0b57cec5SDimitry Andric int exp, expdiff, j, k; 128*0b57cec5SDimitry Andric lint mant; 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric expdiff = (int) Q6_P_vabsdiffh_PP(a, b); 131*0b57cec5SDimitry Andric expdiff = Q6_R_sxth_R(expdiff) ; 132*0b57cec5SDimitry Andric if (expdiff > 63) { expdiff = 62;} 133*0b57cec5SDimitry Andric if (expa > expb) { 134*0b57cec5SDimitry Andric exp = expa + 1; 135*0b57cec5SDimitry Andric expa = 1; 136*0b57cec5SDimitry Andric expb = expdiff + 1; 137*0b57cec5SDimitry Andric } else { 138*0b57cec5SDimitry Andric exp = expb + 1; 139*0b57cec5SDimitry Andric expb = 1; 140*0b57cec5SDimitry Andric expa = expdiff + 1; 141*0b57cec5SDimitry Andric } 142*0b57cec5SDimitry Andric mant = (manta>>expa) - (mantb>>expb); 143*0b57cec5SDimitry Andric k = Q6_R_clb_P(mant)-1; 144*0b57cec5SDimitry Andric mant = (mant << k); 145*0b57cec5SDimitry Andric exp = exp - k; 146*0b57cec5SDimitry Andric if (mant == 0 || mant == -1) exp = 0x8001; 147*0b57cec5SDimitry Andric c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 148*0b57cec5SDimitry Andric return(c); 149*0b57cec5SDimitry Andric } 150*0b57cec5SDimitry Andric * ==================================================================== */ 151*0b57cec5SDimitry Andric .text 152*0b57cec5SDimitry Andric .global fast2_dsub_asm 153*0b57cec5SDimitry Andric .type fast2_dsub_asm, @function 154*0b57cec5SDimitry Andricfast2_dsub_asm: 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric#define manta R0 157*0b57cec5SDimitry Andric#define mantexpa R1:0 158*0b57cec5SDimitry Andric#define lmanta R1:0 159*0b57cec5SDimitry Andric#define mantb R2 160*0b57cec5SDimitry Andric#define mantexpb R3:2 161*0b57cec5SDimitry Andric#define lmantb R3:2 162*0b57cec5SDimitry Andric#define expa R4 163*0b57cec5SDimitry Andric#define expb R5 164*0b57cec5SDimitry Andric#define mantexpd R7:6 165*0b57cec5SDimitry Andric#define expd R6 166*0b57cec5SDimitry Andric#define exp R8 167*0b57cec5SDimitry Andric#define c63 R9 168*0b57cec5SDimitry Andric#define lmant R1:0 169*0b57cec5SDimitry Andric#define manth R1 170*0b57cec5SDimitry Andric#define mantl R0 171*0b57cec5SDimitry Andric#define minmin R11:10 // exactly 0x000000000000008001LL 172*0b57cec5SDimitry Andric#define minminl R10 173*0b57cec5SDimitry Andric#define k R4 174*0b57cec5SDimitry Andric#define ce P0 175*0b57cec5SDimitry Andric .falign 176*0b57cec5SDimitry Andric { 177*0b57cec5SDimitry Andric mantexpd = VABSDIFFH(mantexpa, mantexpb) //represented as 0x08001LL 178*0b57cec5SDimitry Andric c63 = #62 179*0b57cec5SDimitry Andric expa = SXTH(manta) 180*0b57cec5SDimitry Andric expb = SXTH(mantb) 181*0b57cec5SDimitry Andric } { 182*0b57cec5SDimitry Andric expd = SXTH(expd) 183*0b57cec5SDimitry Andric ce = CMP.GT(expa, expb); 184*0b57cec5SDimitry Andric if ( ce.new) exp = add(expa, #1) 185*0b57cec5SDimitry Andric if (!ce.new) exp = add(expb, #1) 186*0b57cec5SDimitry Andric } { 187*0b57cec5SDimitry Andric if ( ce) expa = #1 188*0b57cec5SDimitry Andric if (!ce) expb = #1 189*0b57cec5SDimitry Andric manta.L = #0 190*0b57cec5SDimitry Andric expd = MIN(expd, c63) 191*0b57cec5SDimitry Andric } { 192*0b57cec5SDimitry Andric if (!ce) expa = add(expd, #1) 193*0b57cec5SDimitry Andric if ( ce) expb = add(expd, #1) 194*0b57cec5SDimitry Andric mantb.L = #0 195*0b57cec5SDimitry Andric minmin = #0 196*0b57cec5SDimitry Andric } { 197*0b57cec5SDimitry Andric lmanta = ASR(lmanta, expa) 198*0b57cec5SDimitry Andric lmantb = ASR(lmantb, expb) 199*0b57cec5SDimitry Andric } { 200*0b57cec5SDimitry Andric lmant = sub(lmanta, lmantb) 201*0b57cec5SDimitry Andric minminl.L = #0x8001 202*0b57cec5SDimitry Andric } { 203*0b57cec5SDimitry Andric k = clb(lmant) 204*0b57cec5SDimitry Andric c63 = #58 205*0b57cec5SDimitry Andric } { 206*0b57cec5SDimitry Andric k = add(k, #-1) 207*0b57cec5SDimitry Andric p0 = cmp.gt(k, c63) 208*0b57cec5SDimitry Andric } { 209*0b57cec5SDimitry Andric mantexpa = ASL(lmant, k) 210*0b57cec5SDimitry Andric exp = SUB(exp, k) 211*0b57cec5SDimitry Andric if(p0) jump .Ldenorm 212*0b57cec5SDimitry Andric } { 213*0b57cec5SDimitry Andric manta = insert(exp, #16, #0) 214*0b57cec5SDimitry Andric jumpr r31 215*0b57cec5SDimitry Andric } 216*0b57cec5SDimitry Andric.Ldenorm: 217*0b57cec5SDimitry Andric { 218*0b57cec5SDimitry Andric mantexpa = minmin 219*0b57cec5SDimitry Andric jumpr r31 220*0b57cec5SDimitry Andric } 221*0b57cec5SDimitry Andric/* ==================================================================== * 222*0b57cec5SDimitry Andric fast2_QDOUBLE fast2_dmpy(fast2_QDOUBLE a,fast2_QDOUBLE b) { 223*0b57cec5SDimitry Andric fast2_QDOUBLE c; 224*0b57cec5SDimitry Andric lint manta = a & MANTMASK; 225*0b57cec5SDimitry Andric int expa = Q6_R_sxth_R(a) ; 226*0b57cec5SDimitry Andric lint mantb = b & MANTMASK; 227*0b57cec5SDimitry Andric int expb = Q6_R_sxth_R(b) ; 228*0b57cec5SDimitry Andric int exp, k; 229*0b57cec5SDimitry Andric lint mant; 230*0b57cec5SDimitry Andric int hia, hib, hi, lo; 231*0b57cec5SDimitry Andric unsigned int loa, lob; 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric hia = (int)(a >> 32); 234*0b57cec5SDimitry Andric loa = Q6_R_extractu_RII((int)manta, 31, 1); 235*0b57cec5SDimitry Andric hib = (int)(b >> 32); 236*0b57cec5SDimitry Andric lob = Q6_R_extractu_RII((int)mantb, 31, 1); 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric mant = Q6_P_mpy_RR(hia, lob); 239*0b57cec5SDimitry Andric mant = Q6_P_mpyacc_RR(mant,hib, loa); 240*0b57cec5SDimitry Andric mant = (mant >> 30) + (Q6_P_mpy_RR(hia, hib)<<1); 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric hi = (int) (mant>>32); 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric k = Q6_R_normamt_R(hi); 245*0b57cec5SDimitry Andric mant = mant << k; 246*0b57cec5SDimitry Andric exp = expa + expb - k; 247*0b57cec5SDimitry Andric if (mant == 0 || mant == -1) exp = 0x8001; 248*0b57cec5SDimitry Andric c = (mant & MANTMASK) | (((lint) exp) & EXP_MASK); 249*0b57cec5SDimitry Andric return(c); 250*0b57cec5SDimitry Andric } 251*0b57cec5SDimitry Andric * ==================================================================== */ 252*0b57cec5SDimitry Andric .text 253*0b57cec5SDimitry Andric .global fast2_dmpy_asm 254*0b57cec5SDimitry Andric .type fast2_dmpy_asm, @function 255*0b57cec5SDimitry Andricfast2_dmpy_asm: 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric#define mantal R0 258*0b57cec5SDimitry Andric#define mantah R1 259*0b57cec5SDimitry Andric#define mantexpa R1:0 260*0b57cec5SDimitry Andric#define mantbl R2 261*0b57cec5SDimitry Andric#define mantbh R3 262*0b57cec5SDimitry Andric#define mantexpb R3:2 263*0b57cec5SDimitry Andric#define expa R4 264*0b57cec5SDimitry Andric#define expb R5 265*0b57cec5SDimitry Andric#define c8001 R12 266*0b57cec5SDimitry Andric#define mantexpd R7:6 267*0b57cec5SDimitry Andric#define mantdh R7 268*0b57cec5SDimitry Andric#define exp R8 269*0b57cec5SDimitry Andric#define lmantc R11:10 270*0b57cec5SDimitry Andric#define kb R9 271*0b57cec5SDimitry Andric#define guard R11 272*0b57cec5SDimitry Andric#define mantal_ R12 273*0b57cec5SDimitry Andric#define mantbl_ R13 274*0b57cec5SDimitry Andric#define min R15:14 275*0b57cec5SDimitry Andric#define minh R15 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric .falign 278*0b57cec5SDimitry Andric { 279*0b57cec5SDimitry Andric mantbl_= lsr(mantbl, #16) 280*0b57cec5SDimitry Andric expb = sxth(mantbl) 281*0b57cec5SDimitry Andric expa = sxth(mantal) 282*0b57cec5SDimitry Andric mantal_= lsr(mantal, #16) 283*0b57cec5SDimitry Andric } 284*0b57cec5SDimitry Andric { 285*0b57cec5SDimitry Andric lmantc = mpy(mantah, mantbh) 286*0b57cec5SDimitry Andric mantexpd = mpy(mantah, mantbl_) 287*0b57cec5SDimitry Andric mantal.L = #0x0 288*0b57cec5SDimitry Andric min = #0 289*0b57cec5SDimitry Andric } 290*0b57cec5SDimitry Andric { 291*0b57cec5SDimitry Andric lmantc = add(lmantc, lmantc) 292*0b57cec5SDimitry Andric mantexpd+= mpy(mantbh, mantal_) 293*0b57cec5SDimitry Andric mantbl.L = #0x0 294*0b57cec5SDimitry Andric minh.H = #0x8000 295*0b57cec5SDimitry Andric } 296*0b57cec5SDimitry Andric { 297*0b57cec5SDimitry Andric mantexpd = asr(mantexpd, #15) 298*0b57cec5SDimitry Andric c8001.L = #0x8001 299*0b57cec5SDimitry Andric p1 = cmp.eq(mantexpa, mantexpb) 300*0b57cec5SDimitry Andric } 301*0b57cec5SDimitry Andric { 302*0b57cec5SDimitry Andric mantexpd = add(mantexpd, lmantc) 303*0b57cec5SDimitry Andric exp = add(expa, expb) 304*0b57cec5SDimitry Andric p2 = cmp.eq(mantexpa, min) 305*0b57cec5SDimitry Andric } 306*0b57cec5SDimitry Andric { 307*0b57cec5SDimitry Andric kb = clb(mantexpd) 308*0b57cec5SDimitry Andric mantexpb = abs(mantexpd) 309*0b57cec5SDimitry Andric guard = #58 310*0b57cec5SDimitry Andric } 311*0b57cec5SDimitry Andric { 312*0b57cec5SDimitry Andric p1 = and(p1, p2) 313*0b57cec5SDimitry Andric exp = sub(exp, kb) 314*0b57cec5SDimitry Andric kb = add(kb, #-1) 315*0b57cec5SDimitry Andric p0 = cmp.gt(kb, guard) 316*0b57cec5SDimitry Andric } 317*0b57cec5SDimitry Andric { 318*0b57cec5SDimitry Andric exp = add(exp, #1) 319*0b57cec5SDimitry Andric mantexpa = asl(mantexpd, kb) 320*0b57cec5SDimitry Andric if(p1) jump .Lsat //rarely happens 321*0b57cec5SDimitry Andric } 322*0b57cec5SDimitry Andric { 323*0b57cec5SDimitry Andric mantal = insert(exp,#16, #0) 324*0b57cec5SDimitry Andric if(!p0) jumpr r31 325*0b57cec5SDimitry Andric } 326*0b57cec5SDimitry Andric { 327*0b57cec5SDimitry Andric mantal = insert(c8001,#16, #0) 328*0b57cec5SDimitry Andric jumpr r31 329*0b57cec5SDimitry Andric } 330*0b57cec5SDimitry Andric.Lsat: 331*0b57cec5SDimitry Andric { 332*0b57cec5SDimitry Andric mantexpa = #-1 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric { 335*0b57cec5SDimitry Andric mantexpa = lsr(mantexpa, #1) 336*0b57cec5SDimitry Andric } 337*0b57cec5SDimitry Andric { 338*0b57cec5SDimitry Andric mantal = insert(exp,#16, #0) 339*0b57cec5SDimitry Andric jumpr r31 340*0b57cec5SDimitry Andric } 341*0b57cec5SDimitry Andric 342*0b57cec5SDimitry Andric/* ==================================================================== * 343*0b57cec5SDimitry Andric int fast2_qd2f(fast2_QDOUBLE a) { 344*0b57cec5SDimitry Andric int exp; 345*0b57cec5SDimitry Andric long long int manta; 346*0b57cec5SDimitry Andric int ic, rnd, mantb; 347*0b57cec5SDimitry Andric 348*0b57cec5SDimitry Andric manta = a>>32; 349*0b57cec5SDimitry Andric exp = Q6_R_sxth_R(a) ; 350*0b57cec5SDimitry Andric ic = 0x80000000 & manta; 351*0b57cec5SDimitry Andric manta = Q6_R_abs_R_sat(manta); 352*0b57cec5SDimitry Andric mantb = (manta + rnd)>>7; 353*0b57cec5SDimitry Andric rnd = 0x40 354*0b57cec5SDimitry Andric exp = (exp + 126); 355*0b57cec5SDimitry Andric if((manta & 0xff) == rnd) rnd = 0x00; 356*0b57cec5SDimitry Andric if((manta & 0x7fffffc0) == 0x7fffffc0) { 357*0b57cec5SDimitry Andric manta = 0x0; exp++; 358*0b57cec5SDimitry Andric } else { 359*0b57cec5SDimitry Andric manta= mantb & 0x007fffff; 360*0b57cec5SDimitry Andric } 361*0b57cec5SDimitry Andric exp = (exp << 23) & 0x7fffffc0; 362*0b57cec5SDimitry Andric ic = Q6_R_addacc_RR(ic, exp, manta); 363*0b57cec5SDimitry Andric return (ic); 364*0b57cec5SDimitry Andric } 365*0b57cec5SDimitry Andric * ==================================================================== */ 366*0b57cec5SDimitry Andric 367*0b57cec5SDimitry Andric .text 368*0b57cec5SDimitry Andric .global fast2_qd2f_asm 369*0b57cec5SDimitry Andric .type fast2_qd2f_asm, @function 370*0b57cec5SDimitry Andricfast2_qd2f_asm: 371*0b57cec5SDimitry Andric#define mantah R1 372*0b57cec5SDimitry Andric#define mantal R0 373*0b57cec5SDimitry Andric#define cff R0 374*0b57cec5SDimitry Andric#define mant R3 375*0b57cec5SDimitry Andric#define expo R4 376*0b57cec5SDimitry Andric#define rnd R5 377*0b57cec5SDimitry Andric#define mask R6 378*0b57cec5SDimitry Andric#define c07f R7 379*0b57cec5SDimitry Andric#define c80 R0 380*0b57cec5SDimitry Andric#define mantb R2 381*0b57cec5SDimitry Andric#define ic R0 382*0b57cec5SDimitry Andric 383*0b57cec5SDimitry Andric .falign 384*0b57cec5SDimitry Andric { 385*0b57cec5SDimitry Andric mant = abs(mantah):sat 386*0b57cec5SDimitry Andric expo = sxth(mantal) 387*0b57cec5SDimitry Andric rnd = #0x40 388*0b57cec5SDimitry Andric mask.L = #0xffc0 389*0b57cec5SDimitry Andric } 390*0b57cec5SDimitry Andric { 391*0b57cec5SDimitry Andric cff = extractu(mant, #8, #0) 392*0b57cec5SDimitry Andric p2 = cmp.gt(expo, #126) 393*0b57cec5SDimitry Andric p3 = cmp.ge(expo, #-126) 394*0b57cec5SDimitry Andric mask.H = #0x7fff 395*0b57cec5SDimitry Andric } 396*0b57cec5SDimitry Andric { 397*0b57cec5SDimitry Andric p1 = cmp.eq(cff,#0x40) 398*0b57cec5SDimitry Andric if(p1.new) rnd = #0 399*0b57cec5SDimitry Andric expo = add(expo, #126) 400*0b57cec5SDimitry Andric if(!p3) jump .Lmin 401*0b57cec5SDimitry Andric } 402*0b57cec5SDimitry Andric { 403*0b57cec5SDimitry Andric p0 = bitsset(mant, mask) 404*0b57cec5SDimitry Andric c80.L = #0x0000 405*0b57cec5SDimitry Andric mantb = add(mant, rnd) 406*0b57cec5SDimitry Andric c07f = lsr(mask, #8) 407*0b57cec5SDimitry Andric } 408*0b57cec5SDimitry Andric { 409*0b57cec5SDimitry Andric if(p0) expo = add(expo, #1) 410*0b57cec5SDimitry Andric if(p0) mant = #0 411*0b57cec5SDimitry Andric mantb = lsr(mantb, #7) 412*0b57cec5SDimitry Andric c80.H = #0x8000 413*0b57cec5SDimitry Andric } 414*0b57cec5SDimitry Andric { 415*0b57cec5SDimitry Andric ic = and(c80, mantah) 416*0b57cec5SDimitry Andric mask &= asl(expo, #23) 417*0b57cec5SDimitry Andric if(!p0) mant = and(mantb, c07f) 418*0b57cec5SDimitry Andric if(p2) jump .Lmax 419*0b57cec5SDimitry Andric } 420*0b57cec5SDimitry Andric { 421*0b57cec5SDimitry Andric ic += add(mask, mant) 422*0b57cec5SDimitry Andric jumpr r31 423*0b57cec5SDimitry Andric } 424*0b57cec5SDimitry Andric.Lmax: 425*0b57cec5SDimitry Andric { 426*0b57cec5SDimitry Andric ic.L = #0xffff; 427*0b57cec5SDimitry Andric } 428*0b57cec5SDimitry Andric { 429*0b57cec5SDimitry Andric ic.H = #0x7f7f; 430*0b57cec5SDimitry Andric jumpr r31 431*0b57cec5SDimitry Andric } 432*0b57cec5SDimitry Andric.Lmin: 433*0b57cec5SDimitry Andric { 434*0b57cec5SDimitry Andric ic = #0x0 435*0b57cec5SDimitry Andric jumpr r31 436*0b57cec5SDimitry Andric } 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric/* ==================================================================== * 439*0b57cec5SDimitry Andricfast2_QDOUBLE fast2_f2qd(int ia) { 440*0b57cec5SDimitry Andric lint exp; 441*0b57cec5SDimitry Andric lint mant; 442*0b57cec5SDimitry Andric fast2_QDOUBLE c; 443*0b57cec5SDimitry Andric 444*0b57cec5SDimitry Andric mant = ((ia << 7) | 0x40000000)&0x7fffff80 ; 445*0b57cec5SDimitry Andric if (ia & 0x80000000) mant = -mant; 446*0b57cec5SDimitry Andric exp = ((ia >> 23) & 0xFFLL) - 126; 447*0b57cec5SDimitry Andric c = (mant<<32) | Q6_R_zxth_R(exp);; 448*0b57cec5SDimitry Andric return(c); 449*0b57cec5SDimitry Andric} 450*0b57cec5SDimitry Andric * ==================================================================== */ 451*0b57cec5SDimitry Andric .text 452*0b57cec5SDimitry Andric .global fast2_f2qd_asm 453*0b57cec5SDimitry Andric .type fast2_f2qd_asm, @function 454*0b57cec5SDimitry Andricfast2_f2qd_asm: 455*0b57cec5SDimitry Andric#define ia R0 456*0b57cec5SDimitry Andric#define mag R3 457*0b57cec5SDimitry Andric#define mantr R1 458*0b57cec5SDimitry Andric#define expr R0 459*0b57cec5SDimitry Andric#define zero R2 460*0b57cec5SDimitry Andric#define maxneg R5:4 461*0b57cec5SDimitry Andric#define maxnegl R4 462*0b57cec5SDimitry Andric .falign 463*0b57cec5SDimitry Andric { 464*0b57cec5SDimitry Andric mantr = asl(ia, #7) 465*0b57cec5SDimitry Andric p0 = tstbit(ia, #31) 466*0b57cec5SDimitry Andric maxneg = #0 467*0b57cec5SDimitry Andric mag = add(ia,ia) 468*0b57cec5SDimitry Andric } 469*0b57cec5SDimitry Andric { 470*0b57cec5SDimitry Andric mantr = setbit(mantr, #30) 471*0b57cec5SDimitry Andric expr= extractu(ia,#8,#23) 472*0b57cec5SDimitry Andric maxnegl.L = #0x8001 473*0b57cec5SDimitry Andric p1 = cmp.eq(mag, #0) 474*0b57cec5SDimitry Andric } 475*0b57cec5SDimitry Andric { 476*0b57cec5SDimitry Andric mantr= extractu(mantr, #31, #0) 477*0b57cec5SDimitry Andric expr= add(expr, #-126) 478*0b57cec5SDimitry Andric zero = #0 479*0b57cec5SDimitry Andric if(p1) jump .Lminqd 480*0b57cec5SDimitry Andric } 481*0b57cec5SDimitry Andric { 482*0b57cec5SDimitry Andric expr = zxth(expr) 483*0b57cec5SDimitry Andric if(p0) mantr= sub(zero, mantr) 484*0b57cec5SDimitry Andric jumpr r31 485*0b57cec5SDimitry Andric } 486*0b57cec5SDimitry Andric.Lminqd: 487*0b57cec5SDimitry Andric { 488*0b57cec5SDimitry Andric R1:0 = maxneg 489*0b57cec5SDimitry Andric jumpr r31 490*0b57cec5SDimitry Andric } 491