diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-09-02 21:17:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:34:50 +0000 |
commit | 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch) | |
tree | 62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp | |
parent | cf037972ea8863e2bab7461d77345367d2c1e054 (diff) | |
parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) |
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; +} |