10eb59cabSMatt Arsenault //===- FloatingPointMode.cpp ------------------------------------*- C++ -*-===//
20eb59cabSMatt Arsenault //
30eb59cabSMatt Arsenault // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40eb59cabSMatt Arsenault // See https://llvm.org/LICENSE.txt for license information.
50eb59cabSMatt Arsenault // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60eb59cabSMatt Arsenault //
70eb59cabSMatt Arsenault //===----------------------------------------------------------------------===//
80eb59cabSMatt Arsenault
90eb59cabSMatt Arsenault #include "llvm/ADT/FloatingPointMode.h"
100eb59cabSMatt Arsenault #include "llvm/ADT/StringExtras.h"
110eb59cabSMatt Arsenault
120eb59cabSMatt Arsenault using namespace llvm;
130eb59cabSMatt Arsenault
fneg(FPClassTest Mask)1418fa83edSMatt Arsenault FPClassTest llvm::fneg(FPClassTest Mask) {
1518fa83edSMatt Arsenault FPClassTest NewMask = Mask & fcNan;
1618fa83edSMatt Arsenault if (Mask & fcNegInf)
1718fa83edSMatt Arsenault NewMask |= fcPosInf;
1818fa83edSMatt Arsenault if (Mask & fcNegNormal)
1918fa83edSMatt Arsenault NewMask |= fcPosNormal;
2018fa83edSMatt Arsenault if (Mask & fcNegSubnormal)
2118fa83edSMatt Arsenault NewMask |= fcPosSubnormal;
2218fa83edSMatt Arsenault if (Mask & fcNegZero)
2318fa83edSMatt Arsenault NewMask |= fcPosZero;
2418fa83edSMatt Arsenault if (Mask & fcPosZero)
2518fa83edSMatt Arsenault NewMask |= fcNegZero;
2618fa83edSMatt Arsenault if (Mask & fcPosSubnormal)
2718fa83edSMatt Arsenault NewMask |= fcNegSubnormal;
2818fa83edSMatt Arsenault if (Mask & fcPosNormal)
2918fa83edSMatt Arsenault NewMask |= fcNegNormal;
3018fa83edSMatt Arsenault if (Mask & fcPosInf)
3118fa83edSMatt Arsenault NewMask |= fcNegInf;
3218fa83edSMatt Arsenault return NewMask;
3318fa83edSMatt Arsenault }
3418fa83edSMatt Arsenault
inverse_fabs(FPClassTest Mask)35*07acfe3aSMatt Arsenault FPClassTest llvm::inverse_fabs(FPClassTest Mask) {
3618fa83edSMatt Arsenault FPClassTest NewMask = Mask & fcNan;
3718fa83edSMatt Arsenault if (Mask & fcPosZero)
3818fa83edSMatt Arsenault NewMask |= fcZero;
3918fa83edSMatt Arsenault if (Mask & fcPosSubnormal)
4018fa83edSMatt Arsenault NewMask |= fcSubnormal;
4118fa83edSMatt Arsenault if (Mask & fcPosNormal)
4218fa83edSMatt Arsenault NewMask |= fcNormal;
4318fa83edSMatt Arsenault if (Mask & fcPosInf)
4418fa83edSMatt Arsenault NewMask |= fcInf;
4518fa83edSMatt Arsenault return NewMask;
4618fa83edSMatt Arsenault }
4718fa83edSMatt Arsenault
unknown_sign(FPClassTest Mask)48*07acfe3aSMatt Arsenault FPClassTest llvm::unknown_sign(FPClassTest Mask) {
49*07acfe3aSMatt Arsenault FPClassTest NewMask = Mask & fcNan;
50*07acfe3aSMatt Arsenault if (Mask & fcZero)
51*07acfe3aSMatt Arsenault NewMask |= fcZero;
52*07acfe3aSMatt Arsenault if (Mask & fcSubnormal)
53*07acfe3aSMatt Arsenault NewMask |= fcSubnormal;
54*07acfe3aSMatt Arsenault if (Mask & fcNormal)
55*07acfe3aSMatt Arsenault NewMask |= fcNormal;
56*07acfe3aSMatt Arsenault if (Mask & fcInf)
57*07acfe3aSMatt Arsenault NewMask |= fcInf;
58*07acfe3aSMatt Arsenault return NewMask;
59*07acfe3aSMatt Arsenault }
60*07acfe3aSMatt Arsenault
610eb59cabSMatt Arsenault // Every bitfield has a unique name and one or more aliasing names that cover
620eb59cabSMatt Arsenault // multiple bits. Names should be listed in order of preference, with higher
630eb59cabSMatt Arsenault // popcounts listed first.
640eb59cabSMatt Arsenault //
650eb59cabSMatt Arsenault // Bits are consumed as printed. Each field should only be represented in one
660eb59cabSMatt Arsenault // printed field.
670eb59cabSMatt Arsenault static constexpr std::pair<FPClassTest, StringLiteral> NoFPClassName[] = {
680eb59cabSMatt Arsenault {fcAllFlags, "all"},
690eb59cabSMatt Arsenault {fcNan, "nan"},
700eb59cabSMatt Arsenault {fcSNan, "snan"},
710eb59cabSMatt Arsenault {fcQNan, "qnan"},
720eb59cabSMatt Arsenault {fcInf, "inf"},
730eb59cabSMatt Arsenault {fcNegInf, "ninf"},
740eb59cabSMatt Arsenault {fcPosInf, "pinf"},
750eb59cabSMatt Arsenault {fcZero, "zero"},
760eb59cabSMatt Arsenault {fcNegZero, "nzero"},
770eb59cabSMatt Arsenault {fcPosZero, "pzero"},
780eb59cabSMatt Arsenault {fcSubnormal, "sub"},
790eb59cabSMatt Arsenault {fcNegSubnormal, "nsub"},
800eb59cabSMatt Arsenault {fcPosSubnormal, "psub"},
810eb59cabSMatt Arsenault {fcNormal, "norm"},
820eb59cabSMatt Arsenault {fcNegNormal, "nnorm"},
830eb59cabSMatt Arsenault {fcPosNormal, "pnorm"}
840eb59cabSMatt Arsenault };
850eb59cabSMatt Arsenault
operator <<(raw_ostream & OS,FPClassTest Mask)860eb59cabSMatt Arsenault raw_ostream &llvm::operator<<(raw_ostream &OS, FPClassTest Mask) {
870eb59cabSMatt Arsenault OS << '(';
880eb59cabSMatt Arsenault
890eb59cabSMatt Arsenault if (Mask == fcNone) {
900eb59cabSMatt Arsenault OS << "none)";
910eb59cabSMatt Arsenault return OS;
920eb59cabSMatt Arsenault }
930eb59cabSMatt Arsenault
940eb59cabSMatt Arsenault ListSeparator LS(" ");
950eb59cabSMatt Arsenault for (auto [BitTest, Name] : NoFPClassName) {
960eb59cabSMatt Arsenault if ((Mask & BitTest) == BitTest) {
970eb59cabSMatt Arsenault OS << LS << Name;
980eb59cabSMatt Arsenault
990eb59cabSMatt Arsenault // Clear the bits so we don't print any aliased names later.
1000eb59cabSMatt Arsenault Mask &= ~BitTest;
1010eb59cabSMatt Arsenault }
1020eb59cabSMatt Arsenault }
1030eb59cabSMatt Arsenault
1040eb59cabSMatt Arsenault assert(Mask == 0 && "didn't print some mask bits");
1050eb59cabSMatt Arsenault
1060eb59cabSMatt Arsenault OS << ')';
1070eb59cabSMatt Arsenault return OS;
1080eb59cabSMatt Arsenault }
109