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::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 48 FPClassTest 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. 67 static 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 86 raw_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