File indexing completed on 2026-05-10 08:43:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_ADT_FLOATINGPOINTMODE_H
0016 #define LLVM_ADT_FLOATINGPOINTMODE_H
0017
0018 #include "llvm/ADT/BitmaskEnum.h"
0019 #include "llvm/ADT/StringSwitch.h"
0020 #include "llvm/Support/raw_ostream.h"
0021
0022 namespace llvm {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 enum class RoundingMode : int8_t {
0038
0039 TowardZero = 0,
0040 NearestTiesToEven = 1,
0041 TowardPositive = 2,
0042 TowardNegative = 3,
0043 NearestTiesToAway = 4,
0044
0045
0046 Dynamic = 7,
0047 Invalid = -1
0048 };
0049
0050
0051 inline StringRef spell(RoundingMode RM) {
0052 switch (RM) {
0053 case RoundingMode::TowardZero: return "towardzero";
0054 case RoundingMode::NearestTiesToEven: return "tonearest";
0055 case RoundingMode::TowardPositive: return "upward";
0056 case RoundingMode::TowardNegative: return "downward";
0057 case RoundingMode::NearestTiesToAway: return "tonearestaway";
0058 case RoundingMode::Dynamic: return "dynamic";
0059 default: return "invalid";
0060 }
0061 }
0062
0063 inline raw_ostream &operator << (raw_ostream &OS, RoundingMode RM) {
0064 OS << spell(RM);
0065 return OS;
0066 }
0067
0068
0069
0070 struct DenormalMode {
0071
0072
0073 enum DenormalModeKind : int8_t {
0074 Invalid = -1,
0075
0076
0077 IEEE,
0078
0079
0080 PreserveSign,
0081
0082
0083 PositiveZero,
0084
0085
0086 Dynamic
0087 };
0088
0089
0090
0091 DenormalModeKind Output = DenormalModeKind::Invalid;
0092
0093
0094
0095
0096 DenormalModeKind Input = DenormalModeKind::Invalid;
0097
0098 constexpr DenormalMode() = default;
0099 constexpr DenormalMode(const DenormalMode &) = default;
0100 constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) :
0101 Output(Out), Input(In) {}
0102
0103 DenormalMode &operator=(const DenormalMode &) = default;
0104
0105 static constexpr DenormalMode getInvalid() {
0106 return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid);
0107 }
0108
0109
0110 static constexpr DenormalMode getDefault() {
0111 return getIEEE();
0112 }
0113
0114 static constexpr DenormalMode getIEEE() {
0115 return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE);
0116 }
0117
0118 static constexpr DenormalMode getPreserveSign() {
0119 return DenormalMode(DenormalModeKind::PreserveSign,
0120 DenormalModeKind::PreserveSign);
0121 }
0122
0123 static constexpr DenormalMode getPositiveZero() {
0124 return DenormalMode(DenormalModeKind::PositiveZero,
0125 DenormalModeKind::PositiveZero);
0126 }
0127
0128 static constexpr DenormalMode getDynamic() {
0129 return DenormalMode(DenormalModeKind::Dynamic, DenormalModeKind::Dynamic);
0130 }
0131
0132 bool operator==(DenormalMode Other) const {
0133 return Output == Other.Output && Input == Other.Input;
0134 }
0135
0136 bool operator!=(DenormalMode Other) const {
0137 return !(*this == Other);
0138 }
0139
0140 bool isSimple() const {
0141 return Input == Output;
0142 }
0143
0144 bool isValid() const {
0145 return Output != DenormalModeKind::Invalid &&
0146 Input != DenormalModeKind::Invalid;
0147 }
0148
0149
0150 constexpr bool inputsAreZero() const {
0151 return Input == DenormalModeKind::PreserveSign ||
0152 Input == DenormalModeKind::PositiveZero;
0153 }
0154
0155
0156 constexpr bool outputsAreZero() const {
0157 return Output == DenormalModeKind::PreserveSign ||
0158 Output == DenormalModeKind::PositiveZero;
0159 }
0160
0161
0162
0163
0164 DenormalMode mergeCalleeMode(DenormalMode Callee) const {
0165 DenormalMode MergedMode = Callee;
0166 if (Callee.Input == DenormalMode::Dynamic)
0167 MergedMode.Input = Input;
0168 if (Callee.Output == DenormalMode::Dynamic)
0169 MergedMode.Output = Output;
0170 return MergedMode;
0171 }
0172
0173 inline void print(raw_ostream &OS) const;
0174
0175 inline std::string str() const {
0176 std::string storage;
0177 raw_string_ostream OS(storage);
0178 print(OS);
0179 return storage;
0180 }
0181 };
0182
0183 inline raw_ostream& operator<<(raw_ostream &OS, DenormalMode Mode) {
0184 Mode.print(OS);
0185 return OS;
0186 }
0187
0188
0189 inline DenormalMode::DenormalModeKind
0190 parseDenormalFPAttributeComponent(StringRef Str) {
0191
0192 return StringSwitch<DenormalMode::DenormalModeKind>(Str)
0193 .Cases("", "ieee", DenormalMode::IEEE)
0194 .Case("preserve-sign", DenormalMode::PreserveSign)
0195 .Case("positive-zero", DenormalMode::PositiveZero)
0196 .Case("dynamic", DenormalMode::Dynamic)
0197 .Default(DenormalMode::Invalid);
0198 }
0199
0200
0201
0202 inline StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode) {
0203 switch (Mode) {
0204 case DenormalMode::IEEE:
0205 return "ieee";
0206 case DenormalMode::PreserveSign:
0207 return "preserve-sign";
0208 case DenormalMode::PositiveZero:
0209 return "positive-zero";
0210 case DenormalMode::Dynamic:
0211 return "dynamic";
0212 default:
0213 return "";
0214 }
0215 }
0216
0217
0218 inline DenormalMode parseDenormalFPAttribute(StringRef Str) {
0219 StringRef OutputStr, InputStr;
0220 std::tie(OutputStr, InputStr) = Str.split(',');
0221
0222 DenormalMode Mode;
0223 Mode.Output = parseDenormalFPAttributeComponent(OutputStr);
0224
0225
0226
0227 Mode.Input = InputStr.empty() ? Mode.Output :
0228 parseDenormalFPAttributeComponent(InputStr);
0229
0230 return Mode;
0231 }
0232
0233 void DenormalMode::print(raw_ostream &OS) const {
0234 OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input);
0235 }
0236
0237
0238
0239 enum FPClassTest : unsigned {
0240 fcNone = 0,
0241
0242 fcSNan = 0x0001,
0243 fcQNan = 0x0002,
0244 fcNegInf = 0x0004,
0245 fcNegNormal = 0x0008,
0246 fcNegSubnormal = 0x0010,
0247 fcNegZero = 0x0020,
0248 fcPosZero = 0x0040,
0249 fcPosSubnormal = 0x0080,
0250 fcPosNormal = 0x0100,
0251 fcPosInf = 0x0200,
0252
0253 fcNan = fcSNan | fcQNan,
0254 fcInf = fcPosInf | fcNegInf,
0255 fcNormal = fcPosNormal | fcNegNormal,
0256 fcSubnormal = fcPosSubnormal | fcNegSubnormal,
0257 fcZero = fcPosZero | fcNegZero,
0258 fcPosFinite = fcPosNormal | fcPosSubnormal | fcPosZero,
0259 fcNegFinite = fcNegNormal | fcNegSubnormal | fcNegZero,
0260 fcFinite = fcPosFinite | fcNegFinite,
0261 fcPositive = fcPosFinite | fcPosInf,
0262 fcNegative = fcNegFinite | fcNegInf,
0263
0264 fcAllFlags = fcNan | fcInf | fcFinite,
0265 };
0266
0267 LLVM_DECLARE_ENUM_AS_BITMASK(FPClassTest, fcPosInf);
0268
0269
0270 FPClassTest fneg(FPClassTest Mask);
0271
0272
0273 FPClassTest inverse_fabs(FPClassTest Mask);
0274
0275
0276
0277 FPClassTest unknown_sign(FPClassTest Mask);
0278
0279
0280 raw_ostream &operator<<(raw_ostream &OS, FPClassTest Mask);
0281
0282 }
0283
0284 #endif