fraiseexcpt.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Copyright (C) 2016-2017 Andes Technology, Inc.
  3. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  4. */
  5. /* Raise given exceptions.
  6. Copyright (C) 2004-2013 Free Software Foundation, Inc.
  7. The GNU C Library is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The GNU C Library is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the GNU C Library. If not, see
  17. <http://www.gnu.org/licenses/>. */
  18. #include <fpu_control.h>
  19. #include <fenv.h>
  20. #include <float.h>
  21. #include "fenv_libc.h"
  22. int
  23. feraiseexcept (int excepts)
  24. {
  25. #ifdef __NDS32_ABI_2FP_PLUS__
  26. float temp1 = 0.0, temp2 = 1.0;
  27. if (FE_INVALID & excepts)
  28. {
  29. __asm__ volatile(
  30. "fmtsr\t %0, $fs0\n\t"
  31. "fdivs\t $fs0, $fs0, $fs0\n\t"
  32. :
  33. :"r"(temp1)
  34. :"$fs0"
  35. );
  36. }
  37. if (FE_DIVBYZERO & excepts)
  38. {
  39. __asm__ volatile(
  40. "fmtsr\t %0, $fs0\n\t"
  41. "fmtsr\t %1, $fs1\n\t"
  42. "fdivs\t $fs0, $fs1, $fs0\n\t"
  43. :
  44. :"r"(temp1),"r"(temp2)
  45. :"$fs0"
  46. );
  47. }
  48. if (FE_OVERFLOW & excepts)
  49. {
  50. /* There's no way to raise overflow without also raising inexact.
  51. */
  52. unsigned int fpcsr;
  53. temp1 = FLT_MAX;
  54. __asm__ volatile(
  55. "fmfcsr\t %0\n\t"
  56. "fmtsr\t %1, $fs0\n\t"
  57. "fadds\t $fs0, $fs0, $fs0\n\t"
  58. "ori\t %0,%0,0x10\n\t"
  59. "fmtcsr\t %0\n\t"
  60. :"=&r"(fpcsr)
  61. :"r"(temp1)
  62. :"$fs0"
  63. );
  64. }
  65. if (FE_UNDERFLOW & excepts)
  66. {
  67. /* There's no way to raise overflow without also raising inexact.
  68. */
  69. temp1 = FLT_MIN;
  70. temp2 = 2.0;
  71. __asm__ volatile(
  72. "fmtsr\t %0, $fs0\n\t"
  73. "fmtsr\t %1, $fs1\n\t"
  74. "fdivs\t $fs1, $fs0, $fs1\n\t"
  75. :
  76. :"r"(temp1),"r"(temp2)
  77. :"$fs0","$fs1"
  78. );
  79. }
  80. if (FE_INEXACT & excepts)
  81. {
  82. temp1 = 3.0;
  83. __asm__ volatile(
  84. "fmtsr\t %0, $fs1\n\t"
  85. "fmtsr\t %1, $fs0\n\t"
  86. "fdivs\t $fs1, $fs0, $fs1\n\t"
  87. :
  88. :"r"(temp1),"r"(temp2)
  89. :"$fs0","$fs1"
  90. );
  91. }
  92. return 0;
  93. #endif
  94. /* Unsupported, so fail unless nothing needs to be done. */
  95. return (excepts != 0);
  96. }