1fe013be4SDimitry Andric //===- FloatingPointMode.cpp ------------------------------------*- C++ -*-===//
2fe013be4SDimitry Andric //
3fe013be4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe013be4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe013be4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe013be4SDimitry Andric //
7fe013be4SDimitry Andric //===----------------------------------------------------------------------===//
8fe013be4SDimitry Andric
9fe013be4SDimitry Andric #include "llvm/ADT/FloatingPointMode.h"
10fe013be4SDimitry Andric #include "llvm/ADT/StringExtras.h"
11fe013be4SDimitry Andric
12fe013be4SDimitry Andric using namespace llvm;
13fe013be4SDimitry Andric
fneg(FPClassTest Mask)14fe013be4SDimitry Andric FPClassTest llvm::fneg(FPClassTest Mask) {
15fe013be4SDimitry Andric FPClassTest NewMask = Mask & fcNan;
16fe013be4SDimitry Andric if (Mask & fcNegInf)
17fe013be4SDimitry Andric NewMask |= fcPosInf;
18fe013be4SDimitry Andric if (Mask & fcNegNormal)
19fe013be4SDimitry Andric NewMask |= fcPosNormal;
20fe013be4SDimitry Andric if (Mask & fcNegSubnormal)
21fe013be4SDimitry Andric NewMask |= fcPosSubnormal;
22fe013be4SDimitry Andric if (Mask & fcNegZero)
23fe013be4SDimitry Andric NewMask |= fcPosZero;
24fe013be4SDimitry Andric if (Mask & fcPosZero)
25fe013be4SDimitry Andric NewMask |= fcNegZero;
26fe013be4SDimitry Andric if (Mask & fcPosSubnormal)
27fe013be4SDimitry Andric NewMask |= fcNegSubnormal;
28fe013be4SDimitry Andric if (Mask & fcPosNormal)
29fe013be4SDimitry Andric NewMask |= fcNegNormal;
30fe013be4SDimitry Andric if (Mask & fcPosInf)
31fe013be4SDimitry Andric NewMask |= fcNegInf;
32fe013be4SDimitry Andric return NewMask;
33fe013be4SDimitry Andric }
34fe013be4SDimitry Andric
inverse_fabs(FPClassTest Mask)35*c9157d92SDimitry Andric FPClassTest llvm::inverse_fabs(FPClassTest Mask) {
36fe013be4SDimitry Andric FPClassTest NewMask = Mask & fcNan;
37fe013be4SDimitry Andric if (Mask & fcPosZero)
38fe013be4SDimitry Andric NewMask |= fcZero;
39fe013be4SDimitry Andric if (Mask & fcPosSubnormal)
40fe013be4SDimitry Andric NewMask |= fcSubnormal;
41fe013be4SDimitry Andric if (Mask & fcPosNormal)
42fe013be4SDimitry Andric NewMask |= fcNormal;
43fe013be4SDimitry Andric if (Mask & fcPosInf)
44fe013be4SDimitry Andric NewMask |= fcInf;
45fe013be4SDimitry Andric return NewMask;
46fe013be4SDimitry Andric }
47fe013be4SDimitry Andric
unknown_sign(FPClassTest Mask)48*c9157d92SDimitry Andric FPClassTest llvm::unknown_sign(FPClassTest Mask) {
49*c9157d92SDimitry Andric FPClassTest NewMask = Mask & fcNan;
50*c9157d92SDimitry Andric if (Mask & fcZero)
51*c9157d92SDimitry Andric NewMask |= fcZero;
52*c9157d92SDimitry Andric if (Mask & fcSubnormal)
53*c9157d92SDimitry Andric NewMask |= fcSubnormal;
54*c9157d92SDimitry Andric if (Mask & fcNormal)
55*c9157d92SDimitry Andric NewMask |= fcNormal;
56*c9157d92SDimitry Andric if (Mask & fcInf)
57*c9157d92SDimitry Andric NewMask |= fcInf;
58*c9157d92SDimitry Andric return NewMask;
59*c9157d92SDimitry Andric }
60*c9157d92SDimitry Andric
61fe013be4SDimitry Andric // Every bitfield has a unique name and one or more aliasing names that cover
62fe013be4SDimitry Andric // multiple bits. Names should be listed in order of preference, with higher
63fe013be4SDimitry Andric // popcounts listed first.
64fe013be4SDimitry Andric //
65fe013be4SDimitry Andric // Bits are consumed as printed. Each field should only be represented in one
66fe013be4SDimitry Andric // printed field.
67fe013be4SDimitry Andric static constexpr std::pair<FPClassTest, StringLiteral> NoFPClassName[] = {
68fe013be4SDimitry Andric {fcAllFlags, "all"},
69fe013be4SDimitry Andric {fcNan, "nan"},
70fe013be4SDimitry Andric {fcSNan, "snan"},
71fe013be4SDimitry Andric {fcQNan, "qnan"},
72fe013be4SDimitry Andric {fcInf, "inf"},
73fe013be4SDimitry Andric {fcNegInf, "ninf"},
74fe013be4SDimitry Andric {fcPosInf, "pinf"},
75fe013be4SDimitry Andric {fcZero, "zero"},
76fe013be4SDimitry Andric {fcNegZero, "nzero"},
77fe013be4SDimitry Andric {fcPosZero, "pzero"},
78fe013be4SDimitry Andric {fcSubnormal, "sub"},
79fe013be4SDimitry Andric {fcNegSubnormal, "nsub"},
80fe013be4SDimitry Andric {fcPosSubnormal, "psub"},
81fe013be4SDimitry Andric {fcNormal, "norm"},
82fe013be4SDimitry Andric {fcNegNormal, "nnorm"},
83fe013be4SDimitry Andric {fcPosNormal, "pnorm"}
84fe013be4SDimitry Andric };
85fe013be4SDimitry Andric
operator <<(raw_ostream & OS,FPClassTest Mask)86fe013be4SDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, FPClassTest Mask) {
87fe013be4SDimitry Andric OS << '(';
88fe013be4SDimitry Andric
89fe013be4SDimitry Andric if (Mask == fcNone) {
90fe013be4SDimitry Andric OS << "none)";
91fe013be4SDimitry Andric return OS;
92fe013be4SDimitry Andric }
93fe013be4SDimitry Andric
94fe013be4SDimitry Andric ListSeparator LS(" ");
95fe013be4SDimitry Andric for (auto [BitTest, Name] : NoFPClassName) {
96fe013be4SDimitry Andric if ((Mask & BitTest) == BitTest) {
97fe013be4SDimitry Andric OS << LS << Name;
98fe013be4SDimitry Andric
99fe013be4SDimitry Andric // Clear the bits so we don't print any aliased names later.
100fe013be4SDimitry Andric Mask &= ~BitTest;
101fe013be4SDimitry Andric }
102fe013be4SDimitry Andric }
103fe013be4SDimitry Andric
104fe013be4SDimitry Andric assert(Mask == 0 && "didn't print some mask bits");
105fe013be4SDimitry Andric
106fe013be4SDimitry Andric OS << ')';
107fe013be4SDimitry Andric return OS;
108fe013be4SDimitry Andric }
109