1*25c28e83SPiotr Jasiukajtis /* 2*25c28e83SPiotr Jasiukajtis * CDDL HEADER START 3*25c28e83SPiotr Jasiukajtis * 4*25c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 5*25c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 6*25c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 7*25c28e83SPiotr Jasiukajtis * 8*25c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*25c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 10*25c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 11*25c28e83SPiotr Jasiukajtis * and limitations under the License. 12*25c28e83SPiotr Jasiukajtis * 13*25c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 14*25c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*25c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 16*25c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 17*25c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 18*25c28e83SPiotr Jasiukajtis * 19*25c28e83SPiotr Jasiukajtis * CDDL HEADER END 20*25c28e83SPiotr Jasiukajtis */ 21*25c28e83SPiotr Jasiukajtis 22*25c28e83SPiotr Jasiukajtis /* 23*25c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*25c28e83SPiotr Jasiukajtis * Use is subject to license terms. 25*25c28e83SPiotr Jasiukajtis */ 26*25c28e83SPiotr Jasiukajtis 27*25c28e83SPiotr Jasiukajtis /* 28*25c28e83SPiotr Jasiukajtis * Copyright 2011, Richard Lowe. 29*25c28e83SPiotr Jasiukajtis */ 30*25c28e83SPiotr Jasiukajtis 31*25c28e83SPiotr Jasiukajtis /* Functions in this file are duplicated in locallibm.il. Keep them in sync */ 32*25c28e83SPiotr Jasiukajtis 33*25c28e83SPiotr Jasiukajtis #ifndef _LIBM_INLINES_H 34*25c28e83SPiotr Jasiukajtis #define _LIBM_INLINES_H 35*25c28e83SPiotr Jasiukajtis 36*25c28e83SPiotr Jasiukajtis #ifdef __GNUC__ 37*25c28e83SPiotr Jasiukajtis 38*25c28e83SPiotr Jasiukajtis #include <sys/types.h> 39*25c28e83SPiotr Jasiukajtis #include <sys/ieeefp.h> 40*25c28e83SPiotr Jasiukajtis 41*25c28e83SPiotr Jasiukajtis #ifdef __cplusplus 42*25c28e83SPiotr Jasiukajtis extern "C" { 43*25c28e83SPiotr Jasiukajtis #endif 44*25c28e83SPiotr Jasiukajtis 45*25c28e83SPiotr Jasiukajtis extern __inline__ double 46*25c28e83SPiotr Jasiukajtis __inline_sqrt(double d) 47*25c28e83SPiotr Jasiukajtis { 48*25c28e83SPiotr Jasiukajtis double ret; 49*25c28e83SPiotr Jasiukajtis 50*25c28e83SPiotr Jasiukajtis __asm__ __volatile__("fsqrtd %1,%0\n\t" : "=e" (ret) : "e" (d)); 51*25c28e83SPiotr Jasiukajtis return (ret); 52*25c28e83SPiotr Jasiukajtis } 53*25c28e83SPiotr Jasiukajtis 54*25c28e83SPiotr Jasiukajtis extern __inline__ float 55*25c28e83SPiotr Jasiukajtis __inline_sqrtf(float f) 56*25c28e83SPiotr Jasiukajtis { 57*25c28e83SPiotr Jasiukajtis float ret; 58*25c28e83SPiotr Jasiukajtis 59*25c28e83SPiotr Jasiukajtis __asm__ __volatile__("fsqrts %1,%0\n\t" : "=f" (ret) : "f" (f)); 60*25c28e83SPiotr Jasiukajtis return (ret); 61*25c28e83SPiotr Jasiukajtis } 62*25c28e83SPiotr Jasiukajtis 63*25c28e83SPiotr Jasiukajtis extern __inline__ enum fp_class_type 64*25c28e83SPiotr Jasiukajtis fp_classf(float f) 65*25c28e83SPiotr Jasiukajtis { 66*25c28e83SPiotr Jasiukajtis enum fp_class_type ret; 67*25c28e83SPiotr Jasiukajtis uint32_t tmp; 68*25c28e83SPiotr Jasiukajtis 69*25c28e83SPiotr Jasiukajtis /* XXX: Separate input and output */ 70*25c28e83SPiotr Jasiukajtis __asm__ __volatile__( 71*25c28e83SPiotr Jasiukajtis "sethi %%hi(0x80000000),%1\n\t" 72*25c28e83SPiotr Jasiukajtis "andncc %2,%1,%0\n\t" 73*25c28e83SPiotr Jasiukajtis "bne 1f\n\t" 74*25c28e83SPiotr Jasiukajtis "nop\n\t" 75*25c28e83SPiotr Jasiukajtis "mov 0,%0\n\t" 76*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is 0 */ 77*25c28e83SPiotr Jasiukajtis "nop\n\t" 78*25c28e83SPiotr Jasiukajtis "1:\n\t" 79*25c28e83SPiotr Jasiukajtis "sethi %%hi(0x7f800000),%1\n\t" 80*25c28e83SPiotr Jasiukajtis "andcc %0,%1,%%g0\n\t" 81*25c28e83SPiotr Jasiukajtis "bne 1f\n\t" 82*25c28e83SPiotr Jasiukajtis "nop\n\t" 83*25c28e83SPiotr Jasiukajtis "mov 1,%0\n\t" 84*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is subnormal */ 85*25c28e83SPiotr Jasiukajtis "nop\n\t" 86*25c28e83SPiotr Jasiukajtis "1:\n\t" 87*25c28e83SPiotr Jasiukajtis "cmp %0,%1\n\t" 88*25c28e83SPiotr Jasiukajtis "bge 1f\n\t" 89*25c28e83SPiotr Jasiukajtis "nop\n\t" 90*25c28e83SPiotr Jasiukajtis "mov 2,%0\n\t" 91*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is normal */ 92*25c28e83SPiotr Jasiukajtis "nop\n\t" 93*25c28e83SPiotr Jasiukajtis "1:\n\t" 94*25c28e83SPiotr Jasiukajtis "bg 1f\n\t" 95*25c28e83SPiotr Jasiukajtis "nop\n\t" 96*25c28e83SPiotr Jasiukajtis "mov 3,%0\n\t" 97*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is __infinity */ 98*25c28e83SPiotr Jasiukajtis "nop\n\t" 99*25c28e83SPiotr Jasiukajtis "1:\n\t" 100*25c28e83SPiotr Jasiukajtis "sethi %%hi(0x00400000),%1\n\t" 101*25c28e83SPiotr Jasiukajtis "andcc %0,%1,%%g0\n\t" 102*25c28e83SPiotr Jasiukajtis "mov 4,%0\n\t" /* x is quiet NaN */ 103*25c28e83SPiotr Jasiukajtis "bne 2f\n\t" 104*25c28e83SPiotr Jasiukajtis "nop\n\t" 105*25c28e83SPiotr Jasiukajtis "mov 5,%0\n\t" /* x is signaling NaN */ 106*25c28e83SPiotr Jasiukajtis "2:\n\t" 107*25c28e83SPiotr Jasiukajtis : "=r" (ret), "=&r" (tmp) 108*25c28e83SPiotr Jasiukajtis : "r" (f) 109*25c28e83SPiotr Jasiukajtis : "cc"); 110*25c28e83SPiotr Jasiukajtis return (ret); 111*25c28e83SPiotr Jasiukajtis } 112*25c28e83SPiotr Jasiukajtis 113*25c28e83SPiotr Jasiukajtis #define _HI_WORD(x) ((uint32_t *)&x)[0] 114*25c28e83SPiotr Jasiukajtis #define _LO_WORD(x) ((uint32_t *)&x)[1] 115*25c28e83SPiotr Jasiukajtis 116*25c28e83SPiotr Jasiukajtis extern __inline__ enum fp_class_type 117*25c28e83SPiotr Jasiukajtis fp_class(double d) 118*25c28e83SPiotr Jasiukajtis { 119*25c28e83SPiotr Jasiukajtis enum fp_class_type ret; 120*25c28e83SPiotr Jasiukajtis uint32_t tmp; 121*25c28e83SPiotr Jasiukajtis 122*25c28e83SPiotr Jasiukajtis __asm__ __volatile__( 123*25c28e83SPiotr Jasiukajtis "sethi %%hi(0x80000000),%1\n\t" /* %1 gets 80000000 */ 124*25c28e83SPiotr Jasiukajtis "andn %2,%1,%0\n\t" /* %2-%0 gets abs(x) */ 125*25c28e83SPiotr Jasiukajtis "orcc %0,%3,%%g0\n\t" /* set cc as x is zero/nonzero */ 126*25c28e83SPiotr Jasiukajtis "bne 1f\n\t" /* branch if x is nonzero */ 127*25c28e83SPiotr Jasiukajtis "nop\n\t" 128*25c28e83SPiotr Jasiukajtis "mov 0,%0\n\t" 129*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is 0 */ 130*25c28e83SPiotr Jasiukajtis "nop\n\t" 131*25c28e83SPiotr Jasiukajtis "1:\n\t" 132*25c28e83SPiotr Jasiukajtis "sethi %%hi(0x7ff00000),%1\n\t" /* %1 gets 7ff00000 */ 133*25c28e83SPiotr Jasiukajtis "andcc %0,%1,%%g0\n\t" /* cc set by __exp field of x */ 134*25c28e83SPiotr Jasiukajtis "bne 1f\n\t" /* branch if normal or max __exp */ 135*25c28e83SPiotr Jasiukajtis "nop\n\t" 136*25c28e83SPiotr Jasiukajtis "mov 1,%0\n\t" 137*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is subnormal */ 138*25c28e83SPiotr Jasiukajtis "nop\n\t" 139*25c28e83SPiotr Jasiukajtis "1:\n\t" 140*25c28e83SPiotr Jasiukajtis "cmp %0,%1\n\t" 141*25c28e83SPiotr Jasiukajtis "bge 1f\n\t" /* branch if x is max __exp */ 142*25c28e83SPiotr Jasiukajtis "nop\n\t" 143*25c28e83SPiotr Jasiukajtis "mov 2,%0\n\t" 144*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is normal */ 145*25c28e83SPiotr Jasiukajtis "nop\n\t" 146*25c28e83SPiotr Jasiukajtis "1:\n\t" 147*25c28e83SPiotr Jasiukajtis "andn %0,%1,%0\n\t" /* o0 gets msw __significand field */ 148*25c28e83SPiotr Jasiukajtis "orcc %0,%3,%%g0\n\t" /* set cc by OR __significand */ 149*25c28e83SPiotr Jasiukajtis "bne 1f\n\t" /* Branch if __nan */ 150*25c28e83SPiotr Jasiukajtis "nop\n\t" 151*25c28e83SPiotr Jasiukajtis "mov 3,%0\n\t" 152*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" /* x is __infinity */ 153*25c28e83SPiotr Jasiukajtis "nop\n\t" 154*25c28e83SPiotr Jasiukajtis "1:\n\t" 155*25c28e83SPiotr Jasiukajtis "sethi %%hi(0x00080000),%1\n\t" 156*25c28e83SPiotr Jasiukajtis "andcc %0,%1,%%g0\n\t" /* set cc by quiet/sig bit */ 157*25c28e83SPiotr Jasiukajtis "be 1f\n\t" /* Branch if signaling */ 158*25c28e83SPiotr Jasiukajtis "nop\n\t" 159*25c28e83SPiotr Jasiukajtis "mov 4,%0\n\t" /* x is quiet NaN */ 160*25c28e83SPiotr Jasiukajtis "ba 2f\n\t" 161*25c28e83SPiotr Jasiukajtis "nop\n\t" 162*25c28e83SPiotr Jasiukajtis "1:\n\t" 163*25c28e83SPiotr Jasiukajtis "mov 5,%0\n\t" /* x is signaling NaN */ 164*25c28e83SPiotr Jasiukajtis "2:\n\t" 165*25c28e83SPiotr Jasiukajtis : "=&r" (ret), "=&r" (tmp) 166*25c28e83SPiotr Jasiukajtis : "r" (_HI_WORD(d)), "r" (_LO_WORD(d)) 167*25c28e83SPiotr Jasiukajtis : "cc"); 168*25c28e83SPiotr Jasiukajtis 169*25c28e83SPiotr Jasiukajtis return (ret); 170*25c28e83SPiotr Jasiukajtis } 171*25c28e83SPiotr Jasiukajtis 172*25c28e83SPiotr Jasiukajtis extern __inline__ int 173*25c28e83SPiotr Jasiukajtis __swapEX(int i) 174*25c28e83SPiotr Jasiukajtis { 175*25c28e83SPiotr Jasiukajtis int ret; 176*25c28e83SPiotr Jasiukajtis uint32_t fsr; 177*25c28e83SPiotr Jasiukajtis uint32_t tmp1, tmp2; 178*25c28e83SPiotr Jasiukajtis 179*25c28e83SPiotr Jasiukajtis __asm__ __volatile__( 180*25c28e83SPiotr Jasiukajtis "and %4,0x1f,%2\n\t" /* tmp1 = %2 = %o1 */ 181*25c28e83SPiotr Jasiukajtis "sll %2,5,%2\n\t" /* shift input to aexc bit location */ 182*25c28e83SPiotr Jasiukajtis ".volatile\n\t" 183*25c28e83SPiotr Jasiukajtis "st %%fsr,%1\n\t" 184*25c28e83SPiotr Jasiukajtis "ld %1,%0\n\t" /* %0 = fsr */ 185*25c28e83SPiotr Jasiukajtis "andn %0,0x3e0,%3\n\t" /* tmp2 = %3 = %o2 */ 186*25c28e83SPiotr Jasiukajtis "or %2,%3,%2\n\t" /* %2 = new fsr */ 187*25c28e83SPiotr Jasiukajtis "st %2,%1\n\t" 188*25c28e83SPiotr Jasiukajtis "ld %1,%%fsr\n\t" 189*25c28e83SPiotr Jasiukajtis "srl %0,5,%0\n\t" 190*25c28e83SPiotr Jasiukajtis "and %0,0x1f,%0\n\t" /* %0 = ret = %o0 */ 191*25c28e83SPiotr Jasiukajtis ".nonvolatile\n\t" 192*25c28e83SPiotr Jasiukajtis : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2) 193*25c28e83SPiotr Jasiukajtis : "r" (i) 194*25c28e83SPiotr Jasiukajtis : "cc"); 195*25c28e83SPiotr Jasiukajtis 196*25c28e83SPiotr Jasiukajtis return (ret); 197*25c28e83SPiotr Jasiukajtis } 198*25c28e83SPiotr Jasiukajtis 199*25c28e83SPiotr Jasiukajtis /* 200*25c28e83SPiotr Jasiukajtis * On the SPARC, __swapRP is a no-op; always return 0 for backward 201*25c28e83SPiotr Jasiukajtis * compatibility 202*25c28e83SPiotr Jasiukajtis */ 203*25c28e83SPiotr Jasiukajtis /* ARGSUSED */ 204*25c28e83SPiotr Jasiukajtis extern __inline__ enum fp_precision_type 205*25c28e83SPiotr Jasiukajtis __swapRP(enum fp_precision_type i) 206*25c28e83SPiotr Jasiukajtis { 207*25c28e83SPiotr Jasiukajtis return (0); 208*25c28e83SPiotr Jasiukajtis } 209*25c28e83SPiotr Jasiukajtis 210*25c28e83SPiotr Jasiukajtis extern __inline__ enum fp_direction_type 211*25c28e83SPiotr Jasiukajtis __swapRD(enum fp_direction_type d) 212*25c28e83SPiotr Jasiukajtis { 213*25c28e83SPiotr Jasiukajtis enum fp_direction_type ret; 214*25c28e83SPiotr Jasiukajtis uint32_t fsr; 215*25c28e83SPiotr Jasiukajtis uint32_t tmp1, tmp2, tmp3; 216*25c28e83SPiotr Jasiukajtis 217*25c28e83SPiotr Jasiukajtis __asm__ __volatile__( 218*25c28e83SPiotr Jasiukajtis "and %5,0x3,%0\n\t" 219*25c28e83SPiotr Jasiukajtis "sll %0,30,%2\n\t" /* shift input to RD bit location */ 220*25c28e83SPiotr Jasiukajtis ".volatile\n\t" 221*25c28e83SPiotr Jasiukajtis "st %%fsr,%1\n\t" 222*25c28e83SPiotr Jasiukajtis "ld %1,%0\n\t" /* %0 = fsr */ 223*25c28e83SPiotr Jasiukajtis "set 0xc0000000,%4\n\t" /* mask of rounding direction bits */ 224*25c28e83SPiotr Jasiukajtis "andn %0,%4,%3\n\t" 225*25c28e83SPiotr Jasiukajtis "or %2,%3,%2\n\t" /* %2 = new fsr */ 226*25c28e83SPiotr Jasiukajtis "st %2,%1\n\t" 227*25c28e83SPiotr Jasiukajtis "ld %1,%%fsr\n\t" 228*25c28e83SPiotr Jasiukajtis "srl %0,30,%0\n\t" 229*25c28e83SPiotr Jasiukajtis "and %0,0x3,%0\n\t" 230*25c28e83SPiotr Jasiukajtis ".nonvolatile\n\t" 231*25c28e83SPiotr Jasiukajtis : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3) 232*25c28e83SPiotr Jasiukajtis : "r" (d) 233*25c28e83SPiotr Jasiukajtis : "cc"); 234*25c28e83SPiotr Jasiukajtis 235*25c28e83SPiotr Jasiukajtis return (ret); 236*25c28e83SPiotr Jasiukajtis } 237*25c28e83SPiotr Jasiukajtis 238*25c28e83SPiotr Jasiukajtis extern __inline__ int 239*25c28e83SPiotr Jasiukajtis __swapTE(int i) 240*25c28e83SPiotr Jasiukajtis { 241*25c28e83SPiotr Jasiukajtis int ret; 242*25c28e83SPiotr Jasiukajtis uint32_t fsr, tmp1, tmp2; 243*25c28e83SPiotr Jasiukajtis 244*25c28e83SPiotr Jasiukajtis __asm__ __volatile__( 245*25c28e83SPiotr Jasiukajtis "and %4,0x1f,%0\n\t" 246*25c28e83SPiotr Jasiukajtis "sll %0,23,%2\n\t" /* shift input to TEM bit location */ 247*25c28e83SPiotr Jasiukajtis ".volatile\n\t" 248*25c28e83SPiotr Jasiukajtis "st %%fsr,%1\n\t" 249*25c28e83SPiotr Jasiukajtis "ld %1,%0\n\t" /* %0 = fsr */ 250*25c28e83SPiotr Jasiukajtis "set 0x0f800000,%3\n\t" /* mask of TEM (Trap Enable Mode bits) */ 251*25c28e83SPiotr Jasiukajtis "andn %0,%3,%3\n\t" 252*25c28e83SPiotr Jasiukajtis "or %2,%3,%2\n\t" /* %2 = new fsr */ 253*25c28e83SPiotr Jasiukajtis "st %2,%1\n\t" 254*25c28e83SPiotr Jasiukajtis "ld %1,%%fsr\n\t" 255*25c28e83SPiotr Jasiukajtis "srl %0,23,%0\n\t" 256*25c28e83SPiotr Jasiukajtis "and %0,0x1f,%0\n\t" 257*25c28e83SPiotr Jasiukajtis ".nonvolatile\n\t" 258*25c28e83SPiotr Jasiukajtis : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2) 259*25c28e83SPiotr Jasiukajtis : "r" (i) 260*25c28e83SPiotr Jasiukajtis : "cc"); 261*25c28e83SPiotr Jasiukajtis 262*25c28e83SPiotr Jasiukajtis return (ret); 263*25c28e83SPiotr Jasiukajtis } 264*25c28e83SPiotr Jasiukajtis 265*25c28e83SPiotr Jasiukajtis extern __inline__ double 266*25c28e83SPiotr Jasiukajtis sqrt(double d) 267*25c28e83SPiotr Jasiukajtis { 268*25c28e83SPiotr Jasiukajtis return (__inline_sqrt(d)); 269*25c28e83SPiotr Jasiukajtis } 270*25c28e83SPiotr Jasiukajtis 271*25c28e83SPiotr Jasiukajtis extern __inline__ float 272*25c28e83SPiotr Jasiukajtis sqrtf(float f) 273*25c28e83SPiotr Jasiukajtis { 274*25c28e83SPiotr Jasiukajtis return (__inline_sqrtf(f)); 275*25c28e83SPiotr Jasiukajtis } 276*25c28e83SPiotr Jasiukajtis 277*25c28e83SPiotr Jasiukajtis extern __inline__ double 278*25c28e83SPiotr Jasiukajtis fabs(double d) 279*25c28e83SPiotr Jasiukajtis { 280*25c28e83SPiotr Jasiukajtis double ret; 281*25c28e83SPiotr Jasiukajtis 282*25c28e83SPiotr Jasiukajtis __asm__ __volatile__("fabsd %1,%0\n\t" : "=e" (ret) : "e" (d)); 283*25c28e83SPiotr Jasiukajtis return (ret); 284*25c28e83SPiotr Jasiukajtis } 285*25c28e83SPiotr Jasiukajtis 286*25c28e83SPiotr Jasiukajtis extern __inline__ float 287*25c28e83SPiotr Jasiukajtis fabsf(float f) 288*25c28e83SPiotr Jasiukajtis { 289*25c28e83SPiotr Jasiukajtis float ret; 290*25c28e83SPiotr Jasiukajtis 291*25c28e83SPiotr Jasiukajtis __asm__ __volatile__("fabss %1,%0\n\t" : "=f" (ret) : "f" (f)); 292*25c28e83SPiotr Jasiukajtis return (ret); 293*25c28e83SPiotr Jasiukajtis } 294*25c28e83SPiotr Jasiukajtis 295*25c28e83SPiotr Jasiukajtis #ifdef __cplusplus 296*25c28e83SPiotr Jasiukajtis } 297*25c28e83SPiotr Jasiukajtis #endif 298*25c28e83SPiotr Jasiukajtis 299*25c28e83SPiotr Jasiukajtis #endif /* __GNUC */ 300*25c28e83SPiotr Jasiukajtis 301*25c28e83SPiotr Jasiukajtis #endif /* _LIBM_INLINES_H */ 302