fpu_control.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /* FPU control word bits. ARC version.
  2. Copyright (C) 2020-2025 Free Software Foundation, Inc.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library. If not, see
  13. <https://www.gnu.org/licenses/>. */
  14. #ifndef _FPU_CONTROL_H
  15. #define _FPU_CONTROL_H
  16. /* ARC FPU control register bits.
  17. [ 0] -> IVE: Enable invalid operation exception.
  18. if 0, soft exception: status register IV flag set.
  19. if 1, hardware exception trap (not supported in Linux yet).
  20. [ 1] -> DZE: Enable division by zero exception.
  21. if 0, soft exception: status register IV flag set.
  22. if 1, hardware exception: (not supported in Linux yet).
  23. [9:8] -> RM: Rounding Mode:
  24. 00 - Rounding toward zero.
  25. 01 - Rounding to nearest (default).
  26. 10 - Rounding (up) toward plus infinity.
  27. 11 - Rounding (down)toward minus infinity.
  28. ARC FPU status register bits.
  29. [ 0] -> IV: flag invalid operation.
  30. [ 1] -> DZ: flag division by zero.
  31. [ 2] -> OV: flag Overflow operation.
  32. [ 3] -> UV: flag Underflow operation.
  33. [ 4] -> IX: flag Inexact operation.
  34. [31] -> FWE: Flag Write Enable.
  35. If 1, above flags writable explicitly (clearing),
  36. else IoW and only writable indirectly via bits [12:7]. */
  37. #include <features.h>
  38. #if !defined(__ARC_FPU_SP__) && !defined(__ARC_FPU_DP__)
  39. # define _FPU_RESERVED 0xffffffff
  40. # define _FPU_DEFAULT 0x00000000
  41. typedef unsigned int fpu_control_t;
  42. # define _FPU_GETCW(cw) (cw) = 0
  43. # define _FPU_SETCW(cw) (void) (cw)
  44. # define _FPU_GETS(cw) (cw) = 0
  45. # define _FPU_SETS(cw) (void) (cw)
  46. extern fpu_control_t __fpu_control;
  47. #else
  48. #define _FPU_RESERVED 0
  49. /* The fdlibm code requires strict IEEE double precision arithmetic,
  50. and no interrupts for exceptions, rounding to nearest.
  51. So only RM set to b'01. */
  52. # define _FPU_DEFAULT 0x00000100
  53. /* Actually default needs to have FWE bit as 1 but that is already
  54. ingrained into _FPU_SETS macro below. */
  55. #define _FPU_FPSR_DEFAULT 0x00000000
  56. #define __FPU_RND_SHIFT 8
  57. #define __FPU_RND_MASK 0x3
  58. /* Type of the control word. */
  59. typedef unsigned int fpu_control_t;
  60. /* Macros for accessing the hardware control word. */
  61. # define _FPU_GETCW(cw) __asm__ volatile ("lr %0, [0x300]" : "=r" (cw))
  62. # define _FPU_SETCW(cw) __asm__ volatile ("sr %0, [0x300]" : : "r" (cw))
  63. /* Macros for accessing the hardware status word.
  64. Writing to FPU_STATUS requires a "control" bit FWE to be able to set the
  65. exception flags directly (as opposed to side-effects of FP instructions).
  66. That is done in the macro here to keeps callers agnostic of this detail.
  67. And given FWE is write-only and RAZ, no need to "clear" it in _FPU_GETS
  68. macro. */
  69. # define _FPU_GETS(cw) \
  70. __asm__ volatile ("lr %0, [0x301] \r\n" \
  71. : "=r" (cw))
  72. # define _FPU_SETS(cw) \
  73. do { \
  74. unsigned int __fwe = 0x80000000 | (cw); \
  75. __asm__ volatile ("sr %0, [0x301] \r\n" \
  76. : : "r" (__fwe)); \
  77. } while (0)
  78. /* Default control word set at startup. */
  79. extern fpu_control_t __fpu_control;
  80. #endif
  81. #endif /* fpu_control.h */