fenv_private.h 5.0 KB

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