1 //===-- Target.cpp --------------------------------------------------------===// 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 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "Target.h" 14 #include "flang/Optimizer/Dialect/FIRType.h" 15 #include "flang/Optimizer/Support/KindMapping.h" 16 #include "mlir/IR/BuiltinTypes.h" 17 #include "mlir/IR/TypeRange.h" 18 19 #define DEBUG_TYPE "flang-codegen-target" 20 21 using namespace fir; 22 23 namespace { 24 template <typename S> 25 struct GenericTarget : public CodeGenSpecifics { 26 using CodeGenSpecifics::CodeGenSpecifics; 27 using AT = CodeGenSpecifics::Attributes; 28 29 Marshalling boxcharArgumentType(mlir::Type eleTy, bool sret) const override { 30 CodeGenSpecifics::Marshalling marshal; 31 auto idxTy = mlir::IntegerType::get(eleTy.getContext(), S::defaultWidth); 32 auto ptrTy = fir::ReferenceType::get(eleTy); 33 marshal.emplace_back(ptrTy, AT{}); 34 // Return value arguments are grouped as a pair. Others are passed in a 35 // split format with all pointers first (in the declared position) and all 36 // LEN arguments appended after all of the dummy arguments. 37 // NB: Other conventions/ABIs can/should be supported via options. 38 marshal.emplace_back(idxTy, AT{/*append=*/!sret}); 39 return marshal; 40 } 41 }; 42 } // namespace 43 44 //===----------------------------------------------------------------------===// 45 // i386 (x86 32 bit) linux target specifics. 46 //===----------------------------------------------------------------------===// 47 48 namespace { 49 struct TargetI386 : public GenericTarget<TargetI386> { 50 using GenericTarget::GenericTarget; 51 52 static constexpr int defaultWidth = 32; 53 }; 54 } // namespace 55 56 //===----------------------------------------------------------------------===// 57 // x86_64 (x86 64 bit) linux target specifics. 58 //===----------------------------------------------------------------------===// 59 60 namespace { 61 struct TargetX86_64 : public GenericTarget<TargetX86_64> { 62 using GenericTarget::GenericTarget; 63 64 static constexpr int defaultWidth = 64; 65 }; 66 } // namespace 67 68 //===----------------------------------------------------------------------===// 69 // AArch64 linux target specifics. 70 //===----------------------------------------------------------------------===// 71 72 namespace { 73 struct TargetAArch64 : public GenericTarget<TargetAArch64> { 74 using GenericTarget::GenericTarget; 75 76 static constexpr int defaultWidth = 64; 77 }; 78 } // namespace 79 80 //===----------------------------------------------------------------------===// 81 // PPC64le linux target specifics. 82 //===----------------------------------------------------------------------===// 83 84 namespace { 85 struct TargetPPC64le : public GenericTarget<TargetPPC64le> { 86 using GenericTarget::GenericTarget; 87 88 static constexpr int defaultWidth = 64; 89 }; 90 } // namespace 91 92 // Instantiate the overloaded target instance based on the triple value. 93 // Currently, the implementation only instantiates `i386-unknown-linux-gnu`, 94 // `x86_64-unknown-linux-gnu`, aarch64 and ppc64le like triples. Other targets 95 // should be added to this file as needed. 96 std::unique_ptr<fir::CodeGenSpecifics> 97 fir::CodeGenSpecifics::get(mlir::MLIRContext *ctx, llvm::Triple &&trp, 98 KindMapping &&kindMap) { 99 switch (trp.getArch()) { 100 default: 101 break; 102 case llvm::Triple::ArchType::x86: 103 switch (trp.getOS()) { 104 default: 105 break; 106 case llvm::Triple::OSType::Linux: 107 case llvm::Triple::OSType::Darwin: 108 return std::make_unique<TargetI386>(ctx, std::move(trp), 109 std::move(kindMap)); 110 } 111 break; 112 case llvm::Triple::ArchType::x86_64: 113 switch (trp.getOS()) { 114 default: 115 break; 116 case llvm::Triple::OSType::Linux: 117 case llvm::Triple::OSType::Darwin: 118 return std::make_unique<TargetX86_64>(ctx, std::move(trp), 119 std::move(kindMap)); 120 } 121 break; 122 case llvm::Triple::ArchType::aarch64: 123 switch (trp.getOS()) { 124 default: 125 break; 126 case llvm::Triple::OSType::Linux: 127 case llvm::Triple::OSType::Darwin: 128 return std::make_unique<TargetAArch64>(ctx, std::move(trp), 129 std::move(kindMap)); 130 } 131 break; 132 case llvm::Triple::ArchType::ppc64le: 133 switch (trp.getOS()) { 134 default: 135 break; 136 case llvm::Triple::OSType::Linux: 137 return std::make_unique<TargetPPC64le>(ctx, std::move(trp), 138 std::move(kindMap)); 139 } 140 break; 141 } 142 llvm::report_fatal_error("target not implemented"); 143 } 144