Print this page




  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 /*
  26  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 
  30 /*
  31  * Copyright 2011, Richard Lowe.
  32  */
  33 
  34 /* Functions in this file are duplicated in libm.m4.  Keep them in sync */
  35 
  36 #ifndef _LIBM_INLINES_H
  37 #define _LIBM_INLINES_H
  38 
  39 #ifdef __GNUC__
  40 
  41 #ifdef __cplusplus
  42 extern "C" {
  43 #endif
  44 
  45 #include <sys/types.h>
  46 #include <sys/ieeefp.h>
  47 
  48 extern __inline__ double
  49 __ieee754_sqrt(double a)
  50 {
  51         double ret;
  52 
  53         __asm__ __volatile__("sqrtsd %1, %0\n\t" : "=x" (ret) : "x" (a));
  54         return (ret);
  55 }
  56 
  57 extern __inline__ float
  58 __inline_sqrtf(float a)
  59 {
  60         float ret;
  61 
  62         __asm__ __volatile__("sqrtss %1, %0\n\t" : "=x" (ret) : "x" (a));
  63         return (ret);
  64 }
  65 
  66 extern __inline__ double
  67 __inline_sqrt(double a)
  68 {
  69         double ret;
  70 
  71         __asm__ __volatile__("sqrtsd %1, %0\n\t" : "=x" (ret) : "x" (a));
  72         return (ret);
  73 }
  74 
  75 /* XXX: Not actually called */
  76 extern __inline__ short
  77 __inline_fstsw(void)
  78 {
  79         short ret;
  80 
  81         __asm__ __volatile__("fstsw %0\n\t" : "=r" (ret));
  82         return (ret);
  83 }
  84 
  85 /*
  86  * 00 - 24 bits
  87  * 01 - reserved
  88  * 10 - 53 bits
  89  * 11 - 64 bits
  90  */
  91 extern __inline__ int
  92 __swapRP(int i)
  93 {
  94         int ret;
  95         uint16_t cw;
  96 
  97         __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
  98 
  99         ret = (cw >> 8) & 0x3;
 100         cw = (cw & 0xfcff) | ((i & 0x3) << 8);
 101 
 102         __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));


 114 __swap87RD(enum fp_direction_type i)
 115 {
 116         int ret;
 117         uint16_t cw;
 118 
 119         __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
 120 
 121         ret = (cw >> 10) & 0x3;
 122         cw = (cw & 0xf3ff) | ((i & 0x3) << 10);
 123 
 124         __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
 125 
 126         return (ret);
 127 }
 128 
 129 extern __inline__ int
 130 abs(int i)
 131 {
 132         int ret;
 133         __asm__ __volatile__(
 134             "movl    %1,%0\n\t"
 135             "negl    %1\n\t"
 136             "cmovnsl %1,%0\n\t"
 137             : "=r" (ret), "+r" (i));


 138         return (ret);
 139 }
 140 
 141 extern __inline__ double
 142 copysign(double d1, double d2)
 143 {
 144         double ret;
 145 
 146         __asm__ __volatile__(
 147             "movq   $0x7fffffffffffffff,%%rax\n\t"
 148             "movd   %%rax,%%xmm2\n\t"
 149             "andpd  %%xmm2,%0\n\t"
 150             "andnpd %1,%%xmm2\n\t"
 151             "orpd   %%xmm2,%0\n\t"
 152             : "=x" (ret)
 153             : "x" (d2), "0" (d1)
 154             : "xmm2", "rax");
 155 
 156         return (ret);
 157 }
 158 
 159 extern __inline__ double
 160 d_sqrt_(double *d)
 161 {
 162         double ret;
 163         __asm__ __volatile__(
 164             "movlpd %1,%0\n\t"
 165             "sqrtsd %0,%0"
 166             : "=x" (ret)
 167             : "m" (*d));
 168         return (ret);
 169 }
 170 
 171 extern __inline__ double
 172 fabs(double d)
 173 {
 174         double ret;
 175 
 176         __asm__ __volatile__(
 177             "movq  $0x7fffffffffffffff,%%rax\n\t"
 178             "movd  %%rax,%%xmm1\n\t"
 179             "andpd %%xmm1,%0"
 180             : "=x" (ret)
 181             : "0" (d)
 182             : "rax", "xmm1");
 183 
 184         return (ret);
 185 }
 186 
 187 extern __inline__ float
 188 fabsf(float d)
 189 {
 190         float ret;
 191 
 192         __asm__ __volatile__(
 193             "andpd %2,%0"
 194             : "=x" (ret)
 195             : "0" (d), "x" (0x7fffffff));
 196 
 197         return (ret);
 198 }
 199 
 200 extern __inline__ int
 201 finite(double d)
 202 {
 203         long ret;                   /* A long, so gcc chooses an %r* for %0 */

 204 
 205         __asm__ __volatile__(
 206             "movq %1,%%rcx\n\t"
 207             "movq $0x7fffffffffffffff,%0\n\t"
 208             "andq %%rcx,%0\n\t"
 209             "movq $0x7ff0000000000000,%%rcx\n\t"
 210             "subq %%rcx,%0\n\t"
 211             "shrq $63,%0\n\t"
 212             : "=r" (ret)
 213             : "x" (d)
 214             : "rcx");
 215 
 216         return (ret);
 217 }
 218 
 219 extern __inline__ float
 220 r_sqrt_(float *f)
 221 {
 222         float ret;
 223 
 224         __asm__ __volatile__(
 225             "movss  %1,%0\n\t"
 226             "sqrtss %0,%0\n\t"
 227             : "+x" (ret)
 228             : "m" (*f));
 229         return (ret);
 230 }
 231 
 232 extern __inline__ int
 233 signbit(double d)
 234 {
 235         long ret;
 236         __asm__ __volatile__(
 237             "movmskpd %1,%0\n\t"
 238             "andq     $1, %0\n\t"
 239             : "=r" (ret)
 240             : "x" (d));
 241         return (ret);
 242 }
 243 
 244 extern __inline__ int
 245 signbitf(float f)
 246 {
 247         int ret;
 248         __asm__ __volatile__(
 249             "movskps %1,%0\n\t"
 250             "andq    $1, %0\n\t"
 251             : "=r" (ret)
 252             : "x" (f));
 253         return (ret);
 254 }
 255 
 256 extern __inline__ double
 257 sqrt(double d)
 258 {
 259         double ret;
 260 
 261         __asm__ __volatile__(
 262             "sqrtsd %0, %0"
 263             : "=x" (ret)
 264             : "0" (d));
 265         return (ret);
 266 }
 267 
 268 extern __inline__ float
 269 sqrtf(float f)
 270 {
 271         float ret;
 272 
 273         __asm__ __volatile__(
 274             "sqrtss %0, %0"
 275             : "=x" (ret)
 276             : "0" (f));
 277         return (ret);
 278 }
 279 
 280 #ifdef __cplusplus
 281 }
 282 #endif
 283 
 284 #endif  /* __GNUC__ */
 285 
 286 #endif /* _LIBM_INLINES_H */


  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 /*
  26  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 
  30 /*
  31  * Copyright 2011, Richard Lowe.
  32  */
  33 
  34 /* Functions in this file are duplicated in locallibm.il.  Keep them in sync */
  35 
  36 #ifndef _LIBM_INLINES_H
  37 #define _LIBM_INLINES_H
  38 
  39 #ifdef __GNUC__
  40 
  41 #ifdef __cplusplus
  42 extern "C" {
  43 #endif
  44 
  45 #include <sys/types.h>
  46 #include <sys/ieeefp.h>
  47 









  48 extern __inline__ float
  49 __inline_sqrtf(float a)
  50 {
  51         float ret;
  52 
  53         __asm__ __volatile__("sqrtss %1, %0\n\t" : "=x" (ret) : "x" (a));
  54         return (ret);
  55 }
  56 
  57 extern __inline__ double
  58 __inline_sqrt(double a)
  59 {
  60         double ret;
  61 
  62         __asm__ __volatile__("sqrtsd %1, %0\n\t" : "=x" (ret) : "x" (a));
  63         return (ret);
  64 }
  65 
  66 extern __inline__ double
  67 __ieee754_sqrt(double a)

  68 {
  69         return (__inline_sqrt(a));



  70 }
  71 
  72 /*
  73  * 00 - 24 bits
  74  * 01 - reserved
  75  * 10 - 53 bits
  76  * 11 - 64 bits
  77  */
  78 extern __inline__ int
  79 __swapRP(int i)
  80 {
  81         int ret;
  82         uint16_t cw;
  83 
  84         __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
  85 
  86         ret = (cw >> 8) & 0x3;
  87         cw = (cw & 0xfcff) | ((i & 0x3) << 8);
  88 
  89         __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));


 101 __swap87RD(enum fp_direction_type i)
 102 {
 103         int ret;
 104         uint16_t cw;
 105 
 106         __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
 107 
 108         ret = (cw >> 10) & 0x3;
 109         cw = (cw & 0xf3ff) | ((i & 0x3) << 10);
 110 
 111         __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
 112 
 113         return (ret);
 114 }
 115 
 116 extern __inline__ int
 117 abs(int i)
 118 {
 119         int ret;
 120         __asm__ __volatile__(
 121             "movl    %1, %0\n\t"
 122             "negl    %1\n\t"
 123             "cmovnsl %1, %0\n\t"
 124             : "=r" (ret), "+r" (i)
 125             :
 126             : "cc");
 127         return (ret);
 128 }
 129 
 130 extern __inline__ double
 131 copysign(double d1, double d2)
 132 {
 133         double tmpd;
 134 
 135         __asm__ __volatile__(
 136             "movd %3, %1\n\t"
 137             "andpd %1, %0\n\t"
 138             "andnpd %2, %1\n\t"
 139             "orpd %1, %0\n\t"
 140             : "+x" (d1), "=x" (tmpd)
 141             : "x" (d2), "r" (0x7fffffffffffffff));


 142 
 143         return (d1);












 144 }
 145 
 146 extern __inline__ double
 147 fabs(double d)
 148 {
 149         double tmp;
 150 
 151         __asm__ __volatile__(
 152             "movd  %2, %1\n\t"
 153             "andpd %1, %0"
 154             : "+x" (d), "=x" (tmp)
 155             : "r" (0x7fffffffffffffff));


 156 
 157         return (d);
 158 }
 159 
 160 extern __inline__ float
 161 fabsf(float d)
 162 {


 163         __asm__ __volatile__(
 164             "andpd %1, %0"
 165             : "+x" (d)
 166             : "x" (0x7fffffff));
 167 
 168         return (d);
 169 }
 170 
 171 extern __inline__ int
 172 finite(double d)
 173 {
 174     long ret = 0x7fffffffffffffff;
 175         uint64_t tmp;
 176 
 177         __asm__ __volatile__(
 178             "movq %2, %1\n\t"
 179             "andq %1, %0\n\t"
 180             "movq $0x7ff0000000000000, %1\n\t"
 181             "subq %1, %0\n\t"
 182             "shrq $63, %0\n\t"
 183             : "+r" (ret), "=r" (tmp)

 184             : "x" (d)
 185             : "cc");








 186 





 187         return (ret);
 188 }
 189 
 190 extern __inline__ int
 191 signbit(double d)
 192 {
 193         long ret;
 194         __asm__ __volatile__(
 195             "movmskpd %1, %0\n\t"
 196             "andq     $1, %0\n\t"
 197             : "=r" (ret)
 198             : "x" (d)
 199             : "cc");











 200         return (ret);
 201 }
 202 
 203 extern __inline__ double
 204 sqrt(double d)
 205 {
 206         return (__inline_sqrt(d));






 207 }
 208 
 209 extern __inline__ float
 210 sqrtf(float f)
 211 {
 212         return (__inline_sqrtf(f));






 213 }
 214 
 215 #ifdef __cplusplus
 216 }
 217 #endif
 218 
 219 #endif  /* __GNUC__ */
 220 
 221 #endif /* _LIBM_INLINES_H */