LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
fpControl.h
Go to the documentation of this file.
1 #ifndef art_Framework_Services_System_detail_fpControl_h
2 #define art_Framework_Services_System_detail_fpControl_h
3 
4 extern "C" {
5 #if defined __i386__ || defined __x86_64__
6 #include <fenv.h>
7 #ifdef __linux__
8 #define fpControl_DENORMALOPERAND __FE_DENORM
9 #include <fpu_control.h>
10 #define fpControl_EXTENDED_PREC _FPU_EXTENDED
11 #define fpControl_DOUBLE_PREC _FPU_DOUBLE
12 #define fpControl_SINGLE_PREC _FPU_SINGLE
13 #elif defined __APPLE__
14 #ifndef __GNUC__
15 #pragma STDC FENV_ACCESS ON
16 #endif
17 #define fpControl_DENORMALOPERAND FE_DENORMALOPERAND
18 #define fpControl_EXTENDED_PREC 0x300
19 #define fpControl_DOUBLE_PREC 0x200
20 #define fpControl_SINGLE_PREC 0x0
21 #else
22 #error OS not valid for FP control
23 #endif
24 #define fpControl_ALL_PREC \
25  (fpControl_EXTENDED_PREC | fpControl_DOUBLE_PREC | fpControl_SINGLE_PREC)
26 #ifdef __x86_64__
27 #define fpControl_HAVE_MXCSR
28 // for the MMU (SSE), here are the bit definitions
29 // Pnemonic Bit Location Description
30 // FZ bit 15 Flush To Zero
31 #define fpControl_FZ 0x8000
32 // R+ bit 14 Round Positive
33 #define fpControl_R_PLUS 0x4000
34 // R- bit 13 Round Negative
35 #define fpControl_R_MINUS 0x2000
36 // RZ bits 13 and 14 Round To Zero
37 #define fpControl_RZ (fpControl_R_PLUS | fpControl_R_MINUS)
38 // RN bits 13 and 14 are 0 Round To Nearest
39 #define fpControl_RN_MASK fpControl_RZ
40 // PM bit 12 Precision Mask
41 #define fpControl_PM_MASK (0x1000)
42 // UM bit 11 Underflow Mask
43 #define fpControl_UM_MASK (0x0800)
44 // OM bit 10 Overflow Mask
45 #define fpControl_OM_MASK (0x0400)
46 // ZM bit 9 Divide By Zero Mask
47 #define fpControl_ZM_MASK (0x0200)
48 // DM bit 8 Denormal Mask
49 #define fpControl_DM_MASK (0x0100)
50 // IM bit 7 Invalid Operation Mask
51 #define fpControl_IM_MASK (0x0080)
52 // DAZ bit 6 Denormals Are Zero
53 #define fpControl_DAX 0x0040
54 // PE bit 5 Precision Flag
55 #define fpControl_PE 0x0020
56 // UE bit 4 Underflow Flag
57 #define fpControl_UE 0x0010
58 // OE bit 3 Overflow Flag
59 #define fpControl_OE 0x0008
60 // ZE bit 2 Divide By Zero Flag
61 #define fpControl_ZE 0x0004
62 // DE bit 1 Denormal Flag
63 #define fpControl_DE 0x0002
64 // IE bit 0 Invalid Operation Flag
65 #define fpControl_IE 0x0001
66 // All mask bits
67 #define fpControl_ALL_SSE_EXCEPT 0x1f80
68 // All flag bits
69 #define fpControl_ALL_SSE_FLAGS 0x3f
70 #endif /* __x86_64__ */
71 #else
72 #error Architecture not valid for FP control
73 #endif
74 }
75 
76 namespace art {
77  namespace fp_detail {
78 
79  enum class precision_t {
80  SINGLE = fpControl_SINGLE_PREC,
81  DOUBLE = fpControl_DOUBLE_PREC,
82  EXTENDED = fpControl_EXTENDED_PREC
83  };
84 
85  using fpsw_t =
86 #ifdef __linux__
87  decltype(fenv_t::__status_word)
88 #elif __APPLE__
89  decltype(fenv_t::__status)
90 #endif
91  ;
92 
93  using fpcw_t =
94 #ifdef __linux__
95  decltype(fenv_t::__control_word)
96 #elif __APPLE__
97  decltype(fenv_t::__control)
98 #endif
99  ;
100 
101 #ifdef fpControl_HAVE_MXCSR
102  using mxcsr_t = decltype(fenv_t::__mxcsr);
103 #endif
104 
105  struct fp_control_t {
107 #ifdef fpControl_HAVE_MXCSR
108  mxcsr_t mxcsr; // SSE
109 #endif
110  };
111 
112  fpsw_t getFPSW();
113 
114  fpcw_t getFPCW();
115  fpcw_t setFPCW(fpcw_t fpcw);
116 
117 #ifdef fpControl_HAVE_MXCSR
118  mxcsr_t getMXCSR();
119  mxcsr_t setMXCSR(mxcsr_t mxcsr);
120 #endif
121 
123  fp_control_t setFPControl(fp_control_t const& fpControl);
124 
125  char const* on_or_off(bool const b);
126  } // namespace fp_detail
127 } // namespace art
128 
131 {
132  fp_control_t result{getFPCW()
133 #ifdef fpControl_HAVE_MXCSR
134  ,
135  getMXCSR()
136 #endif
137  };
138  return result;
139 }
140 
143 {
144  fp_control_t result{setFPCW(fpControl.fpcw)
145 #ifdef fpControl_HAVE_MXCSR
146  ,
147  setMXCSR(fpControl.mxcsr)
148 #endif
149  };
150  return result;
151 }
152 
153 inline char const*
155 {
156  return b ? " on " : " off";
157 }
158 #endif /* art_Framework_Services_System_detail_fpControl_h */
159 
160 // Local Variables:
161 // mode: c++
162 // End:
fpcw_t setFPCW(fpcw_t fpcw)
Definition: fpControl.cc:36
fpsw_t getFPSW()
Definition: fpControl.cc:21
char const * on_or_off(bool const b)
Definition: fpControl.h:154
typedef fpsw_t
Definition: fpControl.h:91
fpcw_t getFPCW()
Definition: fpControl.cc:28
Definition: MVAAlg.h:12
fp_control_t getFPControl()
Definition: fpControl.h:130
typedef fpcw_t
Definition: fpControl.h:99
fp_control_t setFPControl(fp_control_t const &fpControl)
Definition: fpControl.h:142