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