xref: /src/contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
17fa27ce4SDimitry Andric //===- FloatingPointMode.cpp ------------------------------------*- C++ -*-===//
27fa27ce4SDimitry Andric //
37fa27ce4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47fa27ce4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
57fa27ce4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67fa27ce4SDimitry Andric //
77fa27ce4SDimitry Andric //===----------------------------------------------------------------------===//
87fa27ce4SDimitry Andric 
97fa27ce4SDimitry Andric #include "llvm/ADT/FloatingPointMode.h"
107fa27ce4SDimitry Andric #include "llvm/ADT/StringExtras.h"
117fa27ce4SDimitry Andric 
127fa27ce4SDimitry Andric using namespace llvm;
137fa27ce4SDimitry Andric 
fneg(FPClassTest Mask)147fa27ce4SDimitry Andric FPClassTest llvm::fneg(FPClassTest Mask) {
157fa27ce4SDimitry Andric   FPClassTest NewMask = Mask & fcNan;
167fa27ce4SDimitry Andric   if (Mask & fcNegInf)
177fa27ce4SDimitry Andric     NewMask |= fcPosInf;
187fa27ce4SDimitry Andric   if (Mask & fcNegNormal)
197fa27ce4SDimitry Andric     NewMask |= fcPosNormal;
207fa27ce4SDimitry Andric   if (Mask & fcNegSubnormal)
217fa27ce4SDimitry Andric     NewMask |= fcPosSubnormal;
227fa27ce4SDimitry Andric   if (Mask & fcNegZero)
237fa27ce4SDimitry Andric     NewMask |= fcPosZero;
247fa27ce4SDimitry Andric   if (Mask & fcPosZero)
257fa27ce4SDimitry Andric     NewMask |= fcNegZero;
267fa27ce4SDimitry Andric   if (Mask & fcPosSubnormal)
277fa27ce4SDimitry Andric     NewMask |= fcNegSubnormal;
287fa27ce4SDimitry Andric   if (Mask & fcPosNormal)
297fa27ce4SDimitry Andric     NewMask |= fcNegNormal;
307fa27ce4SDimitry Andric   if (Mask & fcPosInf)
317fa27ce4SDimitry Andric     NewMask |= fcNegInf;
327fa27ce4SDimitry Andric   return NewMask;
337fa27ce4SDimitry Andric }
347fa27ce4SDimitry Andric 
inverse_fabs(FPClassTest Mask)35b1c73532SDimitry Andric FPClassTest llvm::inverse_fabs(FPClassTest Mask) {
367fa27ce4SDimitry Andric   FPClassTest NewMask = Mask & fcNan;
377fa27ce4SDimitry Andric   if (Mask & fcPosZero)
387fa27ce4SDimitry Andric     NewMask |= fcZero;
397fa27ce4SDimitry Andric   if (Mask & fcPosSubnormal)
407fa27ce4SDimitry Andric     NewMask |= fcSubnormal;
417fa27ce4SDimitry Andric   if (Mask & fcPosNormal)
427fa27ce4SDimitry Andric     NewMask |= fcNormal;
437fa27ce4SDimitry Andric   if (Mask & fcPosInf)
447fa27ce4SDimitry Andric     NewMask |= fcInf;
457fa27ce4SDimitry Andric   return NewMask;
467fa27ce4SDimitry Andric }
477fa27ce4SDimitry Andric 
unknown_sign(FPClassTest Mask)48b1c73532SDimitry Andric FPClassTest llvm::unknown_sign(FPClassTest Mask) {
49b1c73532SDimitry Andric   FPClassTest NewMask = Mask & fcNan;
50b1c73532SDimitry Andric   if (Mask & fcZero)
51b1c73532SDimitry Andric     NewMask |= fcZero;
52b1c73532SDimitry Andric   if (Mask & fcSubnormal)
53b1c73532SDimitry Andric     NewMask |= fcSubnormal;
54b1c73532SDimitry Andric   if (Mask & fcNormal)
55b1c73532SDimitry Andric     NewMask |= fcNormal;
56b1c73532SDimitry Andric   if (Mask & fcInf)
57b1c73532SDimitry Andric     NewMask |= fcInf;
58b1c73532SDimitry Andric   return NewMask;
59b1c73532SDimitry Andric }
60b1c73532SDimitry Andric 
617fa27ce4SDimitry Andric // Every bitfield has a unique name and one or more aliasing names that cover
627fa27ce4SDimitry Andric // multiple bits. Names should be listed in order of preference, with higher
637fa27ce4SDimitry Andric // popcounts listed first.
647fa27ce4SDimitry Andric //
657fa27ce4SDimitry Andric // Bits are consumed as printed. Each field should only be represented in one
667fa27ce4SDimitry Andric // printed field.
677fa27ce4SDimitry Andric static constexpr std::pair<FPClassTest, StringLiteral> NoFPClassName[] = {
687fa27ce4SDimitry Andric   {fcAllFlags, "all"},
697fa27ce4SDimitry Andric   {fcNan, "nan"},
707fa27ce4SDimitry Andric   {fcSNan, "snan"},
717fa27ce4SDimitry Andric   {fcQNan, "qnan"},
727fa27ce4SDimitry Andric   {fcInf, "inf"},
737fa27ce4SDimitry Andric   {fcNegInf, "ninf"},
747fa27ce4SDimitry Andric   {fcPosInf, "pinf"},
757fa27ce4SDimitry Andric   {fcZero, "zero"},
767fa27ce4SDimitry Andric   {fcNegZero, "nzero"},
777fa27ce4SDimitry Andric   {fcPosZero, "pzero"},
787fa27ce4SDimitry Andric   {fcSubnormal, "sub"},
797fa27ce4SDimitry Andric   {fcNegSubnormal, "nsub"},
807fa27ce4SDimitry Andric   {fcPosSubnormal, "psub"},
817fa27ce4SDimitry Andric   {fcNormal, "norm"},
827fa27ce4SDimitry Andric   {fcNegNormal, "nnorm"},
837fa27ce4SDimitry Andric   {fcPosNormal, "pnorm"}
847fa27ce4SDimitry Andric };
857fa27ce4SDimitry Andric 
operator <<(raw_ostream & OS,FPClassTest Mask)867fa27ce4SDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, FPClassTest Mask) {
877fa27ce4SDimitry Andric   OS << '(';
887fa27ce4SDimitry Andric 
897fa27ce4SDimitry Andric   if (Mask == fcNone) {
907fa27ce4SDimitry Andric     OS << "none)";
917fa27ce4SDimitry Andric     return OS;
927fa27ce4SDimitry Andric   }
937fa27ce4SDimitry Andric 
947fa27ce4SDimitry Andric   ListSeparator LS(" ");
957fa27ce4SDimitry Andric   for (auto [BitTest, Name] : NoFPClassName) {
967fa27ce4SDimitry Andric     if ((Mask & BitTest) == BitTest) {
977fa27ce4SDimitry Andric       OS << LS << Name;
987fa27ce4SDimitry Andric 
997fa27ce4SDimitry Andric       // Clear the bits so we don't print any aliased names later.
1007fa27ce4SDimitry Andric       Mask &= ~BitTest;
1017fa27ce4SDimitry Andric     }
1027fa27ce4SDimitry Andric   }
1037fa27ce4SDimitry Andric 
1047fa27ce4SDimitry Andric   assert(Mask == 0 && "didn't print some mask bits");
1057fa27ce4SDimitry Andric 
1067fa27ce4SDimitry Andric   OS << ')';
1077fa27ce4SDimitry Andric   return OS;
1087fa27ce4SDimitry Andric }
109