(root)/
glibc-2.38/
sysdeps/
sparc/
fpu/
fenv_private.h
       1  #ifndef SPARC_FENV_PRIVATE_H
       2  #define SPARC_FENV_PRIVATE_H 1
       3  
       4  #include <fenv.h>
       5  
       6  /* For internal use only: access the fp state register.  */
       7  #if __WORDSIZE == 64
       8  # define __fenv_stfsr(X)   __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (X))
       9  # define __fenv_ldfsr(X)   __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (X))
      10  #else
      11  # define __fenv_stfsr(X)   __asm__ __volatile__ ("st %%fsr,%0" : "=m" (X))
      12  # define __fenv_ldfsr(X)   __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X))
      13  #endif
      14  
      15  static __always_inline void
      16  libc_feholdexcept (fenv_t *e)
      17  {
      18    fenv_t etmp;
      19    __fenv_stfsr(etmp);
      20    *(e) = etmp;
      21    etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT);
      22    __fenv_ldfsr(etmp);
      23  }
      24  
      25  static __always_inline void
      26  libc_fesetround (int r)
      27  {
      28    fenv_t etmp;
      29    __fenv_stfsr(etmp);
      30    etmp = (etmp & ~__FE_ROUND_MASK) | (r);
      31    __fenv_ldfsr(etmp);
      32  }
      33  
      34  static __always_inline void
      35  libc_feholdexcept_setround (fenv_t *e, int r)
      36  {
      37    fenv_t etmp;
      38    __fenv_stfsr(etmp);
      39    *(e) = etmp;
      40    etmp = etmp & ~((0x1f << 23) | FE_ALL_EXCEPT);
      41    etmp = (etmp & ~__FE_ROUND_MASK) | (r);
      42    __fenv_ldfsr(etmp);
      43  }
      44  
      45  static __always_inline int
      46  libc_fetestexcept (int e)
      47  {
      48    fenv_t etmp;
      49    __fenv_stfsr(etmp);
      50    return etmp & (e) & FE_ALL_EXCEPT;
      51  }
      52  
      53  static __always_inline void
      54  libc_fesetenv (fenv_t *e)
      55  {
      56    __fenv_ldfsr(*e);
      57  }
      58  
      59  static __always_inline int
      60  libc_feupdateenv_test (fenv_t *e, int ex)
      61  {
      62    fenv_t etmp;
      63  
      64    __fenv_stfsr(etmp);
      65    etmp &= FE_ALL_EXCEPT;
      66  
      67    __fenv_ldfsr(*e);
      68  
      69    __feraiseexcept (etmp);
      70  
      71    return etmp & ex;
      72  }
      73  
      74  static __always_inline void
      75  libc_feupdateenv (fenv_t *e)
      76  {
      77    libc_feupdateenv_test (e, 0);
      78  }
      79  
      80  static __always_inline void
      81  libc_feholdsetround (fenv_t *e, int r)
      82  {
      83    fenv_t etmp;
      84    __fenv_stfsr(etmp);
      85    *(e) = etmp;
      86    etmp = (etmp & ~__FE_ROUND_MASK) | (r);
      87    __fenv_ldfsr(etmp);
      88  }
      89  
      90  static __always_inline void
      91  libc_feresetround (fenv_t *e)
      92  {
      93    fenv_t etmp;
      94    __fenv_stfsr(etmp);
      95    etmp = (etmp & ~__FE_ROUND_MASK) | (*e & __FE_ROUND_MASK);
      96    __fenv_ldfsr(etmp);
      97  }
      98  
      99  #define libc_feholdexceptf		libc_feholdexcept
     100  #define libc_fesetroundf		libc_fesetround
     101  #define libc_feholdexcept_setroundf	libc_feholdexcept_setround
     102  #define libc_fetestexceptf		libc_fetestexcept
     103  #define libc_fesetenvf			libc_fesetenv
     104  #define libc_feupdateenv_testf		libc_feupdateenv_test
     105  #define libc_feupdateenvf		libc_feupdateenv
     106  #define libc_feholdsetroundf		libc_feholdsetround
     107  #define libc_feresetroundf		libc_feresetround
     108  #define libc_feholdexcept		libc_feholdexcept
     109  #define libc_fesetround			libc_fesetround
     110  #define libc_feholdexcept_setround	libc_feholdexcept_setround
     111  #define libc_fetestexcept		libc_fetestexcept
     112  #define libc_fesetenv			libc_fesetenv
     113  #define libc_feupdateenv_test		libc_feupdateenv_test
     114  #define libc_feupdateenv		libc_feupdateenv
     115  #define libc_feholdsetround		libc_feholdsetround
     116  #define libc_feresetround		libc_feresetround
     117  #define libc_feholdexceptl		libc_feholdexcept
     118  #define libc_fesetroundl		libc_fesetround
     119  #define libc_feholdexcept_setroundl	libc_feholdexcept_setround
     120  #define libc_fetestexceptl		libc_fetestexcept
     121  #define libc_fesetenvl			libc_fesetenv
     122  #define libc_feupdateenv_testl		libc_feupdateenv_test
     123  #define libc_feupdateenvl		libc_feupdateenv
     124  #define libc_feholdsetroundl		libc_feholdsetround
     125  #define libc_feresetroundl		libc_feresetround
     126  
     127  /* We have support for rounding mode context.  */
     128  #define HAVE_RM_CTX 1
     129  
     130  static __always_inline void
     131  libc_feholdexcept_setround_sparc_ctx (struct rm_ctx *ctx, int round)
     132  {
     133    fenv_t new;
     134  
     135    __fenv_stfsr(ctx->env);
     136    new = ctx->env & ~((0x1f << 23) | FE_ALL_EXCEPT);
     137    new = (new & ~__FE_ROUND_MASK) | round;
     138    if (__glibc_unlikely (new != ctx->env))
     139      {
     140        __fenv_ldfsr(new);
     141        ctx->updated_status = true;
     142      }
     143    else
     144      ctx->updated_status = false;
     145  }
     146  
     147  static __always_inline void
     148  libc_fesetenv_sparc_ctx (struct rm_ctx *ctx)
     149  {
     150    libc_fesetenv(&ctx->env);
     151  }
     152  
     153  static __always_inline void
     154  libc_feupdateenv_sparc_ctx (struct rm_ctx *ctx)
     155  {
     156    if (__glibc_unlikely (ctx->updated_status))
     157      libc_feupdateenv_test (&ctx->env, 0);
     158  }
     159  
     160  static __always_inline void
     161  libc_feholdsetround_sparc_ctx (struct rm_ctx *ctx, int round)
     162  {
     163    fenv_t new;
     164  
     165    __fenv_stfsr(ctx->env);
     166    new = (ctx->env & ~__FE_ROUND_MASK) | round;
     167    if (__glibc_unlikely (new != ctx->env))
     168      {
     169        __fenv_ldfsr(new);
     170        ctx->updated_status = true;
     171      }
     172    else
     173      ctx->updated_status = false;
     174  }
     175  #define libc_feholdexcept_setround_ctx   libc_feholdexcept_setround_sparc_ctx
     176  #define libc_feholdexcept_setroundf_ctx  libc_feholdexcept_setround_sparc_ctx
     177  #define libc_feholdexcept_setroundl_ctx  libc_feholdexcept_setround_sparc_ctx
     178  #define libc_fesetenv_ctx                libc_fesetenv_sparc_ctx
     179  #define libc_fesetenvf_ctx               libc_fesetenv_sparc_ctx
     180  #define libc_fesetenvl_ctx               libc_fesetenv_sparc_ctx
     181  #define libc_feupdateenv_ctx             libc_feupdateenv_sparc_ctx
     182  #define libc_feupdateenvf_ctx            libc_feupdateenv_sparc_ctx
     183  #define libc_feupdateenvl_ctx            libc_feupdateenv_sparc_ctx
     184  #define libc_feresetround_ctx            libc_feupdateenv_sparc_ctx
     185  #define libc_feresetroundf_ctx           libc_feupdateenv_sparc_ctx
     186  #define libc_feresetroundl_ctx           libc_feupdateenv_sparc_ctx
     187  #define libc_feholdsetround_ctx          libc_feholdsetround_sparc_ctx
     188  #define libc_feholdsetroundf_ctx         libc_feholdsetround_sparc_ctx
     189  #define libc_feholdsetroundl_ctx         libc_feholdsetround_sparc_ctx
     190  
     191  #include_next <fenv_private.h>
     192  
     193  #endif /* SPARC_FENV_PRIVATE_H */