/home/arjun/llvm-project/llvm/include/llvm/ADT/FloatingPointMode.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/Support/FloatingPointMode.h -------------------------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // Utilities for dealing with flags related to floating point mode controls. |
10 | | // |
11 | | //===----------------------------------------------------------------------===/ |
12 | | |
13 | | #ifndef LLVM_FLOATINGPOINTMODE_H |
14 | | #define LLVM_FLOATINGPOINTMODE_H |
15 | | |
16 | | #include "llvm/ADT/StringSwitch.h" |
17 | | #include "llvm/Support/raw_ostream.h" |
18 | | |
19 | | namespace llvm { |
20 | | |
21 | | /// Rounding mode. |
22 | | /// |
23 | | /// Enumerates supported rounding modes, as well as some special values. The set |
24 | | /// of the modes must agree with IEEE-754, 4.3.1 and 4.3.2. The constants |
25 | | /// assigned to the IEEE rounding modes must agree with the values used by |
26 | | /// FLT_ROUNDS (C11, 5.2.4.2.2p8). |
27 | | /// |
28 | | /// This value is packed into bitfield in some cases, including \c FPOptions, so |
29 | | /// the rounding mode values and the special value \c Dynamic must fit into the |
30 | | /// the bit field (now - 3 bits). The value \c Invalid is used only in values |
31 | | /// returned by intrinsics to indicate errors, it should never be stored as |
32 | | /// rounding mode value, so it does not need to fit the bit fields. |
33 | | /// |
34 | | enum class RoundingMode : int8_t { |
35 | | // Rounding mode defined in IEEE-754. |
36 | | TowardZero = 0, ///< roundTowardZero. |
37 | | NearestTiesToEven = 1, ///< roundTiesToEven. |
38 | | TowardPositive = 2, ///< roundTowardPositive. |
39 | | TowardNegative = 3, ///< roundTowardNegative. |
40 | | NearestTiesToAway = 4, ///< roundTiesToAway. |
41 | | |
42 | | // Special values. |
43 | | Dynamic = 7, ///< Denotes mode unknown at compile time. |
44 | | Invalid = -1 ///< Denotes invalid value. |
45 | | }; |
46 | | |
47 | | /// Represent subnormal handling kind for floating point instruction inputs and |
48 | | /// outputs. |
49 | | struct DenormalMode { |
50 | | /// Represent handled modes for denormal (aka subnormal) modes in the floating |
51 | | /// point environment. |
52 | | enum DenormalModeKind : int8_t { |
53 | | Invalid = -1, |
54 | | |
55 | | /// IEEE-754 denormal numbers preserved. |
56 | | IEEE, |
57 | | |
58 | | /// The sign of a flushed-to-zero number is preserved in the sign of 0 |
59 | | PreserveSign, |
60 | | |
61 | | /// Denormals are flushed to positive zero. |
62 | | PositiveZero |
63 | | }; |
64 | | |
65 | | /// Denormal flushing mode for floating point instruction results in the |
66 | | /// default floating point environment. |
67 | | DenormalModeKind Output = DenormalModeKind::Invalid; |
68 | | |
69 | | /// Denormal treatment kind for floating point instruction inputs in the |
70 | | /// default floating-point environment. If this is not DenormalModeKind::IEEE, |
71 | | /// floating-point instructions implicitly treat the input value as 0. |
72 | | DenormalModeKind Input = DenormalModeKind::Invalid; |
73 | | |
74 | | constexpr DenormalMode() = default; |
75 | | constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) : |
76 | 0 | Output(Out), Input(In) {} |
77 | | |
78 | | |
79 | 0 | static constexpr DenormalMode getInvalid() { |
80 | 0 | return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid); |
81 | 0 | } |
82 | | |
83 | 0 | static constexpr DenormalMode getIEEE() { |
84 | 0 | return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE); |
85 | 0 | } |
86 | | |
87 | 0 | static constexpr DenormalMode getPreserveSign() { |
88 | 0 | return DenormalMode(DenormalModeKind::PreserveSign, |
89 | 0 | DenormalModeKind::PreserveSign); |
90 | 0 | } |
91 | | |
92 | 0 | static constexpr DenormalMode getPositiveZero() { |
93 | 0 | return DenormalMode(DenormalModeKind::PositiveZero, |
94 | 0 | DenormalModeKind::PositiveZero); |
95 | 0 | } |
96 | | |
97 | 0 | bool operator==(DenormalMode Other) const { |
98 | 0 | return Output == Other.Output && Input == Other.Input; |
99 | 0 | } |
100 | | |
101 | 0 | bool operator!=(DenormalMode Other) const { |
102 | 0 | return !(*this == Other); |
103 | 0 | } |
104 | | |
105 | 0 | bool isSimple() const { |
106 | 0 | return Input == Output; |
107 | 0 | } |
108 | | |
109 | 0 | bool isValid() const { |
110 | 0 | return Output != DenormalModeKind::Invalid && |
111 | 0 | Input != DenormalModeKind::Invalid; |
112 | 0 | } |
113 | | |
114 | | inline void print(raw_ostream &OS) const; |
115 | | |
116 | 0 | inline std::string str() const { |
117 | 0 | std::string storage; |
118 | 0 | raw_string_ostream OS(storage); |
119 | 0 | print(OS); |
120 | 0 | return OS.str(); |
121 | 0 | } |
122 | | }; |
123 | | |
124 | 0 | inline raw_ostream& operator<<(raw_ostream &OS, DenormalMode Mode) { |
125 | 0 | Mode.print(OS); |
126 | 0 | return OS; |
127 | 0 | } |
128 | | |
129 | | /// Parse the expected names from the denormal-fp-math attribute. |
130 | | inline DenormalMode::DenormalModeKind |
131 | 0 | parseDenormalFPAttributeComponent(StringRef Str) { |
132 | 0 | // Assume ieee on unspecified attribute. |
133 | 0 | return StringSwitch<DenormalMode::DenormalModeKind>(Str) |
134 | 0 | .Cases("", "ieee", DenormalMode::IEEE) |
135 | 0 | .Case("preserve-sign", DenormalMode::PreserveSign) |
136 | 0 | .Case("positive-zero", DenormalMode::PositiveZero) |
137 | 0 | .Default(DenormalMode::Invalid); |
138 | 0 | } |
139 | | |
140 | | /// Return the name used for the denormal handling mode used by the the |
141 | | /// expected names from the denormal-fp-math attribute. |
142 | 0 | inline StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode) { |
143 | 0 | switch (Mode) { |
144 | 0 | case DenormalMode::IEEE: |
145 | 0 | return "ieee"; |
146 | 0 | case DenormalMode::PreserveSign: |
147 | 0 | return "preserve-sign"; |
148 | 0 | case DenormalMode::PositiveZero: |
149 | 0 | return "positive-zero"; |
150 | 0 | default: |
151 | 0 | return ""; |
152 | 0 | } |
153 | 0 | } |
154 | | |
155 | | /// Returns the denormal mode to use for inputs and outputs. |
156 | 0 | inline DenormalMode parseDenormalFPAttribute(StringRef Str) { |
157 | 0 | StringRef OutputStr, InputStr; |
158 | 0 | std::tie(OutputStr, InputStr) = Str.split(','); |
159 | 0 |
|
160 | 0 | DenormalMode Mode; |
161 | 0 | Mode.Output = parseDenormalFPAttributeComponent(OutputStr); |
162 | 0 |
|
163 | 0 | // Maintain compatability with old form of the attribute which only specified |
164 | 0 | // one component. |
165 | 0 | Mode.Input = InputStr.empty() ? Mode.Output : |
166 | 0 | parseDenormalFPAttributeComponent(InputStr); |
167 | 0 |
|
168 | 0 | return Mode; |
169 | 0 | } |
170 | | |
171 | 0 | void DenormalMode::print(raw_ostream &OS) const { |
172 | 0 | OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input); |
173 | 0 | } |
174 | | |
175 | | } |
176 | | |
177 | | #endif // LLVM_FLOATINGPOINTMODE_H |