1 //===--- SystemZ.h - Declare SystemZ target feature support -----*- 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 // This file declares SystemZ TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 14 #define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 15 16 #include "clang/Basic/TargetInfo.h" 17 #include "clang/Basic/TargetOptions.h" 18 #include "llvm/Support/Compiler.h" 19 #include "llvm/TargetParser/Triple.h" 20 21 namespace clang { 22 namespace targets { 23 24 class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { 25 26 static const char *const GCCRegNames[]; 27 std::string CPU; 28 int ISARevision; 29 bool HasTransactionalExecution; 30 bool HasVector; 31 bool SoftFloat; 32 33 public: 34 SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 35 : TargetInfo(Triple), CPU("z10"), ISARevision(8), 36 HasTransactionalExecution(false), HasVector(false), SoftFloat(false) { 37 IntMaxType = SignedLong; 38 Int64Type = SignedLong; 39 IntWidth = IntAlign = 32; 40 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 41 Int128Align = 64; 42 PointerWidth = PointerAlign = 64; 43 LongDoubleWidth = 128; 44 LongDoubleAlign = 64; 45 LongDoubleFormat = &llvm::APFloat::IEEEquad(); 46 DefaultAlignForAttributeAligned = 64; 47 MinGlobalAlign = 16; 48 if (Triple.isOSzOS()) { 49 TLSSupported = false; 50 // All vector types are default aligned on an 8-byte boundary, even if the 51 // vector facility is not available. That is different from Linux. 52 MaxVectorAlign = 64; 53 // Compared to Linux/ELF, the data layout differs only in some details: 54 // - name mangling is GOFF. 55 // - 32 bit pointers, either as default or special address space 56 resetDataLayout("E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-" 57 "a:8:16-n32:64"); 58 } else { 59 TLSSupported = true; 60 resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" 61 "-v128:64-a:8:16-n32:64"); 62 } 63 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; 64 HasStrictFP = true; 65 } 66 67 void getTargetDefines(const LangOptions &Opts, 68 MacroBuilder &Builder) const override; 69 70 ArrayRef<Builtin::Info> getTargetBuiltins() const override; 71 72 ArrayRef<const char *> getGCCRegNames() const override; 73 74 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 75 // No aliases. 76 return std::nullopt; 77 } 78 79 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; 80 81 bool isSPRegName(StringRef RegName) const override { 82 return RegName.equals("r15"); 83 } 84 85 bool validateAsmConstraint(const char *&Name, 86 TargetInfo::ConstraintInfo &info) const override; 87 88 std::string convertConstraint(const char *&Constraint) const override { 89 switch (Constraint[0]) { 90 case 'p': // Keep 'p' constraint. 91 return std::string("p"); 92 case 'Z': 93 switch (Constraint[1]) { 94 case 'Q': // Address with base and unsigned 12-bit displacement 95 case 'R': // Likewise, plus an index 96 case 'S': // Address with base and signed 20-bit displacement 97 case 'T': // Likewise, plus an index 98 // "^" hints llvm that this is a 2 letter constraint. 99 // "Constraint++" is used to promote the string iterator 100 // to the next constraint. 101 return std::string("^") + std::string(Constraint++, 2); 102 default: 103 break; 104 } 105 break; 106 default: 107 break; 108 } 109 return TargetInfo::convertConstraint(Constraint); 110 } 111 112 std::string_view getClobbers() const override { 113 // FIXME: Is this really right? 114 return ""; 115 } 116 117 BuiltinVaListKind getBuiltinVaListKind() const override { 118 return TargetInfo::SystemZBuiltinVaList; 119 } 120 121 int getISARevision(StringRef Name) const; 122 123 bool isValidCPUName(StringRef Name) const override { 124 return getISARevision(Name) != -1; 125 } 126 127 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 128 129 bool isValidTuneCPUName(StringRef Name) const override { 130 return isValidCPUName(Name); 131 } 132 133 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override { 134 fillValidCPUList(Values); 135 } 136 137 bool setCPU(const std::string &Name) override { 138 CPU = Name; 139 ISARevision = getISARevision(CPU); 140 return ISARevision != -1; 141 } 142 143 bool 144 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 145 StringRef CPU, 146 const std::vector<std::string> &FeaturesVec) const override { 147 int ISARevision = getISARevision(CPU); 148 if (ISARevision >= 10) 149 Features["transactional-execution"] = true; 150 if (ISARevision >= 11) 151 Features["vector"] = true; 152 if (ISARevision >= 12) 153 Features["vector-enhancements-1"] = true; 154 if (ISARevision >= 13) 155 Features["vector-enhancements-2"] = true; 156 if (ISARevision >= 14) 157 Features["nnp-assist"] = true; 158 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 159 } 160 161 bool handleTargetFeatures(std::vector<std::string> &Features, 162 DiagnosticsEngine &Diags) override { 163 HasTransactionalExecution = false; 164 HasVector = false; 165 SoftFloat = false; 166 for (const auto &Feature : Features) { 167 if (Feature == "+transactional-execution") 168 HasTransactionalExecution = true; 169 else if (Feature == "+vector") 170 HasVector = true; 171 else if (Feature == "+soft-float") 172 SoftFloat = true; 173 } 174 HasVector &= !SoftFloat; 175 176 // If we use the vector ABI, vector types are 64-bit aligned. The 177 // DataLayout string is always set to this alignment as it is not a 178 // requirement that it follows the alignment emitted by the front end. It 179 // is assumed generally that the Datalayout should reflect only the 180 // target triple and not any specific feature. 181 if (HasVector && !getTriple().isOSzOS()) 182 MaxVectorAlign = 64; 183 184 return true; 185 } 186 187 bool hasFeature(StringRef Feature) const override; 188 189 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 190 switch (CC) { 191 case CC_C: 192 case CC_Swift: 193 case CC_OpenCLKernel: 194 return CCCR_OK; 195 case CC_SwiftAsync: 196 return CCCR_Error; 197 default: 198 return CCCR_Warning; 199 } 200 } 201 202 StringRef getABI() const override { 203 if (HasVector) 204 return "vector"; 205 return ""; 206 } 207 208 const char *getLongDoubleMangling() const override { return "g"; } 209 210 bool hasBitIntType() const override { return true; } 211 212 int getEHDataRegisterNumber(unsigned RegNo) const override { 213 return RegNo < 4 ? 6 + RegNo : -1; 214 } 215 }; 216 } // namespace targets 217 } // namespace clang 218 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 219