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