2023-02-24 22:35:49 +08:00
|
|
|
//===- 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;
|
|
|
|
|
2023-03-02 17:47:52 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-02-24 22:35:49 +08:00
|
|
|
// 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;
|
|
|
|
}
|