#ifndef LLVM_ADT_FLOATINGPOINTMODE_H
#define LLVM_ADT_FLOATINGPOINTMODE_H
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
enum class RoundingMode : int8_t {
TowardZero = 0, NearestTiesToEven = 1, TowardPositive = 2, TowardNegative = 3, NearestTiesToAway = 4,
Dynamic = 7, Invalid = -1 };
inline StringRef spell(RoundingMode RM) {
switch (RM) {
case RoundingMode::TowardZero: return "towardzero";
case RoundingMode::NearestTiesToEven: return "tonearest";
case RoundingMode::TowardPositive: return "upward";
case RoundingMode::TowardNegative: return "downward";
case RoundingMode::NearestTiesToAway: return "tonearestaway";
case RoundingMode::Dynamic: return "dynamic";
default: return "invalid";
}
}
inline raw_ostream &operator << (raw_ostream &OS, RoundingMode RM) {
OS << spell(RM);
return OS;
}
struct DenormalMode {
enum DenormalModeKind : int8_t {
Invalid = -1,
IEEE,
PreserveSign,
PositiveZero
};
DenormalModeKind Output = DenormalModeKind::Invalid;
DenormalModeKind Input = DenormalModeKind::Invalid;
constexpr DenormalMode() = default;
constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) :
Output(Out), Input(In) {}
static constexpr DenormalMode getInvalid() {
return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid);
}
static constexpr DenormalMode getIEEE() {
return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE);
}
static constexpr DenormalMode getPreserveSign() {
return DenormalMode(DenormalModeKind::PreserveSign,
DenormalModeKind::PreserveSign);
}
static constexpr DenormalMode getPositiveZero() {
return DenormalMode(DenormalModeKind::PositiveZero,
DenormalModeKind::PositiveZero);
}
bool operator==(DenormalMode Other) const {
return Output == Other.Output && Input == Other.Input;
}
bool operator!=(DenormalMode Other) const {
return !(*this == Other);
}
bool isSimple() const {
return Input == Output;
}
bool isValid() const {
return Output != DenormalModeKind::Invalid &&
Input != DenormalModeKind::Invalid;
}
inline void print(raw_ostream &OS) const;
inline std::string str() const {
std::string storage;
raw_string_ostream OS(storage);
print(OS);
return OS.str();
}
};
inline raw_ostream& operator<<(raw_ostream &OS, DenormalMode Mode) {
Mode.print(OS);
return OS;
}
inline DenormalMode::DenormalModeKind
parseDenormalFPAttributeComponent(StringRef Str) {
return StringSwitch<DenormalMode::DenormalModeKind>(Str)
.Cases("", "ieee", DenormalMode::IEEE)
.Case("preserve-sign", DenormalMode::PreserveSign)
.Case("positive-zero", DenormalMode::PositiveZero)
.Default(DenormalMode::Invalid);
}
inline StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode) {
switch (Mode) {
case DenormalMode::IEEE:
return "ieee";
case DenormalMode::PreserveSign:
return "preserve-sign";
case DenormalMode::PositiveZero:
return "positive-zero";
default:
return "";
}
}
inline DenormalMode parseDenormalFPAttribute(StringRef Str) {
StringRef OutputStr, InputStr;
std::tie(OutputStr, InputStr) = Str.split(',');
DenormalMode Mode;
Mode.Output = parseDenormalFPAttributeComponent(OutputStr);
Mode.Input = InputStr.empty() ? Mode.Output :
parseDenormalFPAttributeComponent(InputStr);
return Mode;
}
void DenormalMode::print(raw_ostream &OS) const {
OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input);
}
}
enum FPClassTest {
fcSNan = 0x0001,
fcQNan = 0x0002,
fcNegInf = 0x0004,
fcNegNormal = 0x0008,
fcNegSubnormal = 0x0010,
fcNegZero = 0x0020,
fcPosZero = 0x0040,
fcPosSubnormal = 0x0080,
fcPosNormal = 0x0100,
fcPosInf = 0x0200,
fcNan = fcSNan | fcQNan,
fcInf = fcPosInf | fcNegInf,
fcNormal = fcPosNormal | fcNegNormal,
fcSubnormal = fcPosSubnormal | fcNegSubnormal,
fcZero = fcPosZero | fcNegZero,
fcPosFinite = fcPosNormal | fcPosSubnormal | fcPosZero,
fcNegFinite = fcNegNormal | fcNegSubnormal | fcNegZero,
fcFinite = fcPosFinite | fcNegFinite,
fcAllFlags = fcNan | fcInf | fcFinite
};
#endif