diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp b/contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp new file mode 100644 index 000000000000..9543884ff46e --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp @@ -0,0 +1,95 @@ +//===- FloatingPointMode.cpp ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/FloatingPointMode.h" +#include "llvm/ADT/StringExtras.h" + +using namespace llvm; + +FPClassTest llvm::fneg(FPClassTest Mask) { + FPClassTest NewMask = Mask & fcNan; + if (Mask & fcNegInf) + NewMask |= fcPosInf; + if (Mask & fcNegNormal) + NewMask |= fcPosNormal; + if (Mask & fcNegSubnormal) + NewMask |= fcPosSubnormal; + if (Mask & fcNegZero) + NewMask |= fcPosZero; + if (Mask & fcPosZero) + NewMask |= fcNegZero; + if (Mask & fcPosSubnormal) + NewMask |= fcNegSubnormal; + if (Mask & fcPosNormal) + NewMask |= fcNegNormal; + if (Mask & fcPosInf) + NewMask |= fcNegInf; + return NewMask; +} + +FPClassTest llvm::fabs(FPClassTest Mask) { + FPClassTest NewMask = Mask & fcNan; + if (Mask & fcPosZero) + NewMask |= fcZero; + if (Mask & fcPosSubnormal) + NewMask |= fcSubnormal; + if (Mask & fcPosNormal) + NewMask |= fcNormal; + if (Mask & fcPosInf) + NewMask |= fcInf; + return NewMask; +} + +// Every bitfield has a unique name and one or more aliasing names that cover +// multiple bits. Names should be listed in order of preference, with higher +// popcounts listed first. +// +// Bits are consumed as printed. Each field should only be represented in one +// printed field. +static constexpr std::pair<FPClassTest, StringLiteral> NoFPClassName[] = { + {fcAllFlags, "all"}, + {fcNan, "nan"}, + {fcSNan, "snan"}, + {fcQNan, "qnan"}, + {fcInf, "inf"}, + {fcNegInf, "ninf"}, + {fcPosInf, "pinf"}, + {fcZero, "zero"}, + {fcNegZero, "nzero"}, + {fcPosZero, "pzero"}, + {fcSubnormal, "sub"}, + {fcNegSubnormal, "nsub"}, + {fcPosSubnormal, "psub"}, + {fcNormal, "norm"}, + {fcNegNormal, "nnorm"}, + {fcPosNormal, "pnorm"} +}; + +raw_ostream &llvm::operator<<(raw_ostream &OS, FPClassTest Mask) { + OS << '('; + + if (Mask == fcNone) { + OS << "none)"; + return OS; + } + + ListSeparator LS(" "); + for (auto [BitTest, Name] : NoFPClassName) { + if ((Mask & BitTest) == BitTest) { + OS << LS << Name; + + // Clear the bits so we don't print any aliased names later. + Mask &= ~BitTest; + } + } + + assert(Mask == 0 && "didn't print some mask bits"); + + OS << ')'; + return OS; +} |