Print this page


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