xref: /llvm-project/flang/include/flang/Tools/TargetSetup.h (revision 9d8dc45d17088300e9e2086594ca581b119193c8)
1 //===-- Tools/TargetSetup.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 #ifndef FORTRAN_TOOLS_TARGET_SETUP_H
10 #define FORTRAN_TOOLS_TARGET_SETUP_H
11 
12 #include "flang/Common/float128.h"
13 #include "flang/Evaluate/target.h"
14 #include "flang/Frontend/TargetOptions.h"
15 #include "llvm/Target/TargetMachine.h"
16 #include <cfloat>
17 
18 namespace Fortran::tools {
19 
20 [[maybe_unused]] inline static void setUpTargetCharacteristics(
21     Fortran::evaluate::TargetCharacteristics &targetCharacteristics,
22     const llvm::TargetMachine &targetMachine,
23     const Fortran::frontend::TargetOptions &targetOptions,
24     const std::string &compilerVersion, const std::string &compilerOptions) {
25 
26   const llvm::Triple &targetTriple{targetMachine.getTargetTriple()};
27 
28   targetCharacteristics.set_ieeeFeature(evaluate::IeeeFeature::Halting, true);
29 
30   if (targetTriple.getArch() == llvm::Triple::ArchType::x86_64) {
31     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/3);
32     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/4);
33     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/8);
34   }
35 
36   if (targetTriple.isARM() || targetTriple.isAArch64()) {
37     targetCharacteristics.set_haltingSupportIsUnknownAtCompileTime();
38     targetCharacteristics.set_ieeeFeature(
39         evaluate::IeeeFeature::Halting, false);
40     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/3);
41     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/4);
42     targetCharacteristics.set_hasSubnormalFlushingControl(/*kind=*/8);
43   }
44 
45   if (targetTriple.getArch() != llvm::Triple::ArchType::x86_64) {
46     targetCharacteristics.DisableType(
47         Fortran::common::TypeCategory::Real, /*kind=*/10);
48   }
49 
50   // Check for kind=16 support. See flang/runtime/Float128Math/math-entries.h.
51   // TODO: Take this from TargetInfo::getLongDoubleFormat for cross compilation.
52 #ifdef FLANG_RUNTIME_F128_MATH_LIB
53   constexpr bool f128Support = true; // use libquadmath wrappers
54 #elif HAS_LDBL128
55   constexpr bool f128Support = true; // use libm wrappers
56 #else
57   constexpr bool f128Support = false;
58 #endif
59 
60   if constexpr (!f128Support)
61     targetCharacteristics.DisableType(Fortran::common::TypeCategory::Real, 16);
62 
63   for (auto realKind : targetOptions.disabledRealKinds)
64     targetCharacteristics.DisableType(common::TypeCategory::Real, realKind);
65 
66   for (auto intKind : targetOptions.disabledIntegerKinds)
67     targetCharacteristics.DisableType(common::TypeCategory::Integer, intKind);
68 
69   targetCharacteristics.set_compilerOptionsString(compilerOptions)
70       .set_compilerVersionString(compilerVersion);
71 
72   if (targetTriple.isPPC())
73     targetCharacteristics.set_isPPC(true);
74 
75   if (targetTriple.isSPARC())
76     targetCharacteristics.set_isSPARC(true);
77 
78   if (targetTriple.isOSWindows())
79     targetCharacteristics.set_isOSWindows(true);
80 
81   // TODO: use target machine data layout to set-up the target characteristics
82   // type size and alignment info.
83 }
84 
85 } // namespace Fortran::tools
86 
87 #endif // FORTRAN_TOOLS_TARGET_SETUP_H
88