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