xref: /freebsd/contrib/llvm-project/llvm/lib/Support/FloatingPointMode.cpp (revision f81cdf24ba5436367377f7c8e8f51f6df2a75ca7)
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 
12 using namespace llvm;
13 
14 FPClassTest 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 
35 FPClassTest llvm::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 
48 // Every bitfield has a unique name and one or more aliasing names that cover
49 // multiple bits. Names should be listed in order of preference, with higher
50 // popcounts listed first.
51 //
52 // Bits are consumed as printed. Each field should only be represented in one
53 // printed field.
54 static constexpr std::pair<FPClassTest, StringLiteral> NoFPClassName[] = {
55   {fcAllFlags, "all"},
56   {fcNan, "nan"},
57   {fcSNan, "snan"},
58   {fcQNan, "qnan"},
59   {fcInf, "inf"},
60   {fcNegInf, "ninf"},
61   {fcPosInf, "pinf"},
62   {fcZero, "zero"},
63   {fcNegZero, "nzero"},
64   {fcPosZero, "pzero"},
65   {fcSubnormal, "sub"},
66   {fcNegSubnormal, "nsub"},
67   {fcPosSubnormal, "psub"},
68   {fcNormal, "norm"},
69   {fcNegNormal, "nnorm"},
70   {fcPosNormal, "pnorm"}
71 };
72 
73 raw_ostream &llvm::operator<<(raw_ostream &OS, FPClassTest Mask) {
74   OS << '(';
75 
76   if (Mask == fcNone) {
77     OS << "none)";
78     return OS;
79   }
80 
81   ListSeparator LS(" ");
82   for (auto [BitTest, Name] : NoFPClassName) {
83     if ((Mask & BitTest) == BitTest) {
84       OS << LS << Name;
85 
86       // Clear the bits so we don't print any aliased names later.
87       Mask &= ~BitTest;
88     }
89   }
90 
91   assert(Mask == 0 && "didn't print some mask bits");
92 
93   OS << ')';
94   return OS;
95 }
96