Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- llvm/Support/FloatingPointMode.h -------------------------*- 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
/// \file
10
/// Utilities for dealing with flags related to floating point properties and
11
/// mode controls.
12
///
13
//===----------------------------------------------------------------------===/
14
 
15
#ifndef LLVM_ADT_FLOATINGPOINTMODE_H
16
#define LLVM_ADT_FLOATINGPOINTMODE_H
17
 
18
#include "llvm/ADT/StringSwitch.h"
19
#include "llvm/Support/raw_ostream.h"
20
 
21
namespace llvm {
22
 
23
/// Rounding mode.
24
///
25
/// Enumerates supported rounding modes, as well as some special values. The set
26
/// of the modes must agree with IEEE-754, 4.3.1 and 4.3.2. The constants
27
/// assigned to the IEEE rounding modes must agree with the values used by
28
/// FLT_ROUNDS (C11, 5.2.4.2.2p8).
29
///
30
/// This value is packed into bitfield in some cases, including \c FPOptions, so
31
/// the rounding mode values and the special value \c Dynamic must fit into the
32
/// the bit field (now - 3 bits). The value \c Invalid is used only in values
33
/// returned by intrinsics to indicate errors, it should never be stored as
34
/// rounding mode value, so it does not need to fit the bit fields.
35
///
36
enum class RoundingMode : int8_t {
37
  // Rounding mode defined in IEEE-754.
38
  TowardZero        = 0,    ///< roundTowardZero.
39
  NearestTiesToEven = 1,    ///< roundTiesToEven.
40
  TowardPositive    = 2,    ///< roundTowardPositive.
41
  TowardNegative    = 3,    ///< roundTowardNegative.
42
  NearestTiesToAway = 4,    ///< roundTiesToAway.
43
 
44
  // Special values.
45
  Dynamic = 7,    ///< Denotes mode unknown at compile time.
46
  Invalid = -1    ///< Denotes invalid value.
47
};
48
 
49
/// Returns text representation of the given rounding mode.
50
inline StringRef spell(RoundingMode RM) {
51
  switch (RM) {
52
  case RoundingMode::TowardZero: return "towardzero";
53
  case RoundingMode::NearestTiesToEven: return "tonearest";
54
  case RoundingMode::TowardPositive: return "upward";
55
  case RoundingMode::TowardNegative: return "downward";
56
  case RoundingMode::NearestTiesToAway: return "tonearestaway";
57
  case RoundingMode::Dynamic: return "dynamic";
58
  default: return "invalid";
59
  }
60
}
61
 
62
inline raw_ostream &operator << (raw_ostream &OS, RoundingMode RM) {
63
  OS << spell(RM);
64
  return OS;
65
}
66
 
67
/// Represent subnormal handling kind for floating point instruction inputs and
68
/// outputs.
69
struct DenormalMode {
70
  /// Represent handled modes for denormal (aka subnormal) modes in the floating
71
  /// point environment.
72
  enum DenormalModeKind : int8_t {
73
    Invalid = -1,
74
 
75
    /// IEEE-754 denormal numbers preserved.
76
    IEEE,
77
 
78
    /// The sign of a flushed-to-zero number is preserved in the sign of 0
79
    PreserveSign,
80
 
81
    /// Denormals are flushed to positive zero.
82
    PositiveZero
83
  };
84
 
85
  /// Denormal flushing mode for floating point instruction results in the
86
  /// default floating point environment.
87
  DenormalModeKind Output = DenormalModeKind::Invalid;
88
 
89
  /// Denormal treatment kind for floating point instruction inputs in the
90
  /// default floating-point environment. If this is not DenormalModeKind::IEEE,
91
  /// floating-point instructions implicitly treat the input value as 0.
92
  DenormalModeKind Input = DenormalModeKind::Invalid;
93
 
94
  constexpr DenormalMode() = default;
95
  constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) :
96
    Output(Out), Input(In) {}
97
 
98
 
99
  static constexpr DenormalMode getInvalid() {
100
    return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid);
101
  }
102
 
103
  static constexpr DenormalMode getIEEE() {
104
    return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE);
105
  }
106
 
107
  static constexpr DenormalMode getPreserveSign() {
108
    return DenormalMode(DenormalModeKind::PreserveSign,
109
                        DenormalModeKind::PreserveSign);
110
  }
111
 
112
  static constexpr DenormalMode getPositiveZero() {
113
    return DenormalMode(DenormalModeKind::PositiveZero,
114
                        DenormalModeKind::PositiveZero);
115
  }
116
 
117
  bool operator==(DenormalMode Other) const {
118
    return Output == Other.Output && Input == Other.Input;
119
  }
120
 
121
  bool operator!=(DenormalMode Other) const {
122
    return !(*this == Other);
123
  }
124
 
125
  bool isSimple() const {
126
    return Input == Output;
127
  }
128
 
129
  bool isValid() const {
130
    return Output != DenormalModeKind::Invalid &&
131
           Input != DenormalModeKind::Invalid;
132
  }
133
 
134
  inline void print(raw_ostream &OS) const;
135
 
136
  inline std::string str() const {
137
    std::string storage;
138
    raw_string_ostream OS(storage);
139
    print(OS);
140
    return OS.str();
141
  }
142
};
143
 
144
inline raw_ostream& operator<<(raw_ostream &OS, DenormalMode Mode) {
145
  Mode.print(OS);
146
  return OS;
147
}
148
 
149
/// Parse the expected names from the denormal-fp-math attribute.
150
inline DenormalMode::DenormalModeKind
151
parseDenormalFPAttributeComponent(StringRef Str) {
152
  // Assume ieee on unspecified attribute.
153
  return StringSwitch<DenormalMode::DenormalModeKind>(Str)
154
    .Cases("", "ieee", DenormalMode::IEEE)
155
    .Case("preserve-sign", DenormalMode::PreserveSign)
156
    .Case("positive-zero", DenormalMode::PositiveZero)
157
    .Default(DenormalMode::Invalid);
158
}
159
 
160
/// Return the name used for the denormal handling mode used by the the
161
/// expected names from the denormal-fp-math attribute.
162
inline StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode) {
163
  switch (Mode) {
164
  case DenormalMode::IEEE:
165
    return "ieee";
166
  case DenormalMode::PreserveSign:
167
    return "preserve-sign";
168
  case DenormalMode::PositiveZero:
169
    return "positive-zero";
170
  default:
171
    return "";
172
  }
173
}
174
 
175
/// Returns the denormal mode to use for inputs and outputs.
176
inline DenormalMode parseDenormalFPAttribute(StringRef Str) {
177
  StringRef OutputStr, InputStr;
178
  std::tie(OutputStr, InputStr) = Str.split(',');
179
 
180
  DenormalMode Mode;
181
  Mode.Output = parseDenormalFPAttributeComponent(OutputStr);
182
 
183
  // Maintain compatability with old form of the attribute which only specified
184
  // one component.
185
  Mode.Input = InputStr.empty() ? Mode.Output  :
186
               parseDenormalFPAttributeComponent(InputStr);
187
 
188
  return Mode;
189
}
190
 
191
void DenormalMode::print(raw_ostream &OS) const {
192
  OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input);
193
}
194
 
195
}
196
 
197
/// Floating-point class tests, supported by 'is_fpclass' intrinsic. Actual
198
/// test may be an OR combination of basic tests.
199
enum FPClassTest {
200
  fcSNan = 0x0001,
201
  fcQNan = 0x0002,
202
  fcNegInf = 0x0004,
203
  fcNegNormal = 0x0008,
204
  fcNegSubnormal = 0x0010,
205
  fcNegZero = 0x0020,
206
  fcPosZero = 0x0040,
207
  fcPosSubnormal = 0x0080,
208
  fcPosNormal = 0x0100,
209
  fcPosInf = 0x0200,
210
 
211
  fcNan = fcSNan | fcQNan,
212
  fcInf = fcPosInf | fcNegInf,
213
  fcNormal = fcPosNormal | fcNegNormal,
214
  fcSubnormal = fcPosSubnormal | fcNegSubnormal,
215
  fcZero = fcPosZero | fcNegZero,
216
  fcPosFinite = fcPosNormal | fcPosSubnormal | fcPosZero,
217
  fcNegFinite = fcNegNormal | fcNegSubnormal | fcNegZero,
218
  fcFinite = fcPosFinite | fcNegFinite,
219
  fcAllFlags = fcNan | fcInf | fcFinite
220
};
221
 
222
#endif // LLVM_ADT_FLOATINGPOINTMODE_H