blob: 5a2836eb82434221c5233777f5add91080a204a0 [file] [log] [blame]
//===- 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::inverse_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;
}
FPClassTest llvm::unknown_sign(FPClassTest Mask) {
FPClassTest NewMask = Mask & fcNan;
if (Mask & fcZero)
NewMask |= fcZero;
if (Mask & fcSubnormal)
NewMask |= fcSubnormal;
if (Mask & fcNormal)
NewMask |= fcNormal;
if (Mask & fcInf)
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;
}