1 //===-- include/flang/Evaluate/target.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 // Represents the minimal amount of target architecture information required by
10 // semantics.
11 
12 #ifndef FORTRAN_EVALUATE_TARGET_H_
13 #define FORTRAN_EVALUATE_TARGET_H_
14 
15 #include "flang/Common/Fortran.h"
16 #include "flang/Evaluate/common.h"
17 #include <cstdint>
18 
19 namespace Fortran::evaluate {
20 
21 // Floating-point rounding control
22 struct Rounding {
23   common::RoundingMode mode{common::RoundingMode::TiesToEven};
24   // When set, emulate status flag behavior peculiar to x86
25   // (viz., fail to set the Underflow flag when an inexact product of a
26   // multiplication is rounded up to a normal number from a subnormal
27   // in some rounding modes)
28 #if __x86_64__
29   bool x86CompatibleBehavior{true};
30 #else
31   bool x86CompatibleBehavior{false};
32 #endif
33 };
34 
35 class TargetCharacteristics {
36 public:
37   TargetCharacteristics();
38   TargetCharacteristics &operator=(const TargetCharacteristics &) = default;
39 
isBigEndian()40   bool isBigEndian() const { return isBigEndian_; }
41   void set_isBigEndian(bool isBig = true);
42 
areSubnormalsFlushedToZero()43   bool areSubnormalsFlushedToZero() const {
44     return areSubnormalsFlushedToZero_;
45   }
46   void set_areSubnormalsFlushedToZero(bool yes = true);
47 
roundingMode()48   Rounding roundingMode() const { return roundingMode_; }
49   void set_roundingMode(Rounding);
50 
procedurePointerByteSize()51   std::size_t procedurePointerByteSize() const {
52     return procedurePointerByteSize_;
53   }
procedurePointerAlignment()54   std::size_t procedurePointerAlignment() const {
55     return procedurePointerAlignment_;
56   }
descriptorAlignment()57   std::size_t descriptorAlignment() const { return descriptorAlignment_; }
maxByteSize()58   std::size_t maxByteSize() const { return maxByteSize_; }
maxAlignment()59   std::size_t maxAlignment() const { return maxAlignment_; }
60 
61   static bool CanSupportType(common::TypeCategory, std::int64_t kind);
62   bool EnableType(common::TypeCategory category, std::int64_t kind,
63       std::size_t byteSize, std::size_t align);
64   void DisableType(common::TypeCategory category, std::int64_t kind);
65 
66   std::size_t GetByteSize(
67       common::TypeCategory category, std::int64_t kind) const;
68   std::size_t GetAlignment(
69       common::TypeCategory category, std::int64_t kind) const;
70   bool IsTypeEnabled(common::TypeCategory category, std::int64_t kind) const;
71 
72   int SelectedIntKind(std::int64_t precision = 0) const;
73   int SelectedRealKind(std::int64_t precision = 0, std::int64_t range = 0,
74       std::int64_t radix = 2) const;
75 
76   static Rounding defaultRounding;
77 
78 private:
79   static constexpr int maxKind{32};
80   std::uint8_t byteSize_[common::TypeCategory_enumSize][maxKind]{};
81   std::uint8_t align_[common::TypeCategory_enumSize][maxKind]{};
82   bool isBigEndian_{false};
83   bool areSubnormalsFlushedToZero_{false};
84   Rounding roundingMode_{defaultRounding};
85   std::size_t procedurePointerByteSize_{8};
86   std::size_t procedurePointerAlignment_{8};
87   std::size_t descriptorAlignment_{8};
88   std::size_t maxByteSize_{8 /*at least*/};
89   std::size_t maxAlignment_{8 /*at least*/};
90 };
91 
92 } // namespace Fortran::evaluate
93 #endif // FORTRAN_EVALUATE_TARGET_H_
94