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