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