Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  223.