xref: /llvm-project/llvm/lib/Support/FloatingPointMode.cpp (revision 07acfe3a4d473fccbb2b027cc8c77aec25d1dbe3)
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