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 static const unsigned ZOSAddressMap[] = { 25 0, // Default 26 0, // opencl_global 27 0, // opencl_local 28 0, // opencl_constant 29 0, // opencl_private 30 0, // opencl_generic 31 0, // opencl_global_device 32 0, // opencl_global_host 33 0, // cuda_device 34 0, // cuda_constant 35 0, // cuda_shared 36 0, // sycl_global 37 0, // sycl_global_device 38 0, // sycl_global_host 39 0, // sycl_local 40 0, // sycl_private 41 0, // ptr32_sptr 42 1, // ptr32_uptr 43 0, // ptr64 44 0, // hlsl_groupshared 45 0, // hlsl_constant 46 0 // wasm_funcref 47 }; 48 49 class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { 50 51 static const char *const GCCRegNames[]; 52 int ISARevision; 53 bool HasTransactionalExecution; 54 bool HasVector; 55 bool SoftFloat; 56 bool UnalignedSymbols; 57 enum AddrSpace { ptr32 = 1 }; 58 59 public: 60 SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 61 : TargetInfo(Triple), ISARevision(getISARevision("z10")), 62 HasTransactionalExecution(false), HasVector(false), SoftFloat(false), 63 UnalignedSymbols(false) { 64 IntMaxType = SignedLong; 65 Int64Type = SignedLong; 66 IntWidth = IntAlign = 32; 67 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 68 Int128Align = 64; 69 PointerWidth = PointerAlign = 64; 70 LongDoubleWidth = 128; 71 LongDoubleAlign = 64; 72 LongDoubleFormat = &llvm::APFloat::IEEEquad(); 73 DefaultAlignForAttributeAligned = 64; 74 MinGlobalAlign = 16; 75 HasUnalignedAccess = true; 76 if (Triple.isOSzOS()) { 77 if (Triple.isArch64Bit()) { 78 AddrSpaceMap = &ZOSAddressMap; 79 } 80 TLSSupported = false; 81 // All vector types are default aligned on an 8-byte boundary, even if the 82 // vector facility is not available. That is different from Linux. 83 MaxVectorAlign = 64; 84 // Compared to Linux/ELF, the data layout differs only in some details: 85 // - name mangling is GOFF. 86 // - 32 bit pointers, either as default or special address space 87 resetDataLayout("E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-" 88 "a:8:16-n32:64"); 89 } else { 90 TLSSupported = true; 91 resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" 92 "-v128:64-a:8:16-n32:64"); 93 } 94 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; 95 HasStrictFP = true; 96 } 97 98 unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override; 99 100 void getTargetDefines(const LangOptions &Opts, 101 MacroBuilder &Builder) const override; 102 103 ArrayRef<Builtin::Info> getTargetBuiltins() const override; 104 105 ArrayRef<const char *> getGCCRegNames() const override; 106 107 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 108 // No aliases. 109 return {}; 110 } 111 112 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; 113 114 bool isSPRegName(StringRef RegName) const override { 115 return RegName == "r15"; 116 } 117 118 bool validateAsmConstraint(const char *&Name, 119 TargetInfo::ConstraintInfo &info) const override; 120 121 std::string convertConstraint(const char *&Constraint) const override { 122 switch (Constraint[0]) { 123 case 'p': // Keep 'p' constraint. 124 return std::string("p"); 125 case 'Z': 126 switch (Constraint[1]) { 127 case 'Q': // Address with base and unsigned 12-bit displacement 128 case 'R': // Likewise, plus an index 129 case 'S': // Address with base and signed 20-bit displacement 130 case 'T': // Likewise, plus an index 131 // "^" hints llvm that this is a 2 letter constraint. 132 // "Constraint++" is used to promote the string iterator 133 // to the next constraint. 134 return std::string("^") + std::string(Constraint++, 2); 135 default: 136 break; 137 } 138 break; 139 default: 140 break; 141 } 142 return TargetInfo::convertConstraint(Constraint); 143 } 144 145 std::string_view getClobbers() const override { 146 // FIXME: Is this really right? 147 return ""; 148 } 149 150 BuiltinVaListKind getBuiltinVaListKind() const override { 151 return TargetInfo::SystemZBuiltinVaList; 152 } 153 154 int getISARevision(StringRef Name) const; 155 156 bool isValidCPUName(StringRef Name) const override { 157 return getISARevision(Name) != -1; 158 } 159 160 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 161 162 bool isValidTuneCPUName(StringRef Name) const override { 163 return isValidCPUName(Name); 164 } 165 166 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override { 167 fillValidCPUList(Values); 168 } 169 170 bool setCPU(const std::string &Name) override { 171 ISARevision = getISARevision(Name); 172 return ISARevision != -1; 173 } 174 175 bool 176 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 177 StringRef CPU, 178 const std::vector<std::string> &FeaturesVec) const override { 179 int ISARevision = getISARevision(CPU); 180 if (ISARevision >= 10) 181 Features["transactional-execution"] = true; 182 if (ISARevision >= 11) 183 Features["vector"] = true; 184 if (ISARevision >= 12) 185 Features["vector-enhancements-1"] = true; 186 if (ISARevision >= 13) 187 Features["vector-enhancements-2"] = true; 188 if (ISARevision >= 14) 189 Features["nnp-assist"] = true; 190 if (ISARevision >= 15) { 191 Features["miscellaneous-extensions-4"] = true; 192 Features["vector-enhancements-3"] = true; 193 } 194 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 195 } 196 197 bool handleTargetFeatures(std::vector<std::string> &Features, 198 DiagnosticsEngine &Diags) override { 199 HasTransactionalExecution = false; 200 HasVector = false; 201 SoftFloat = false; 202 UnalignedSymbols = false; 203 for (const auto &Feature : Features) { 204 if (Feature == "+transactional-execution") 205 HasTransactionalExecution = true; 206 else if (Feature == "+vector") 207 HasVector = true; 208 else if (Feature == "+soft-float") 209 SoftFloat = true; 210 else if (Feature == "+unaligned-symbols") 211 UnalignedSymbols = true; 212 } 213 HasVector &= !SoftFloat; 214 215 // If we use the vector ABI, vector types are 64-bit aligned. The 216 // DataLayout string is always set to this alignment as it is not a 217 // requirement that it follows the alignment emitted by the front end. It 218 // is assumed generally that the Datalayout should reflect only the 219 // target triple and not any specific feature. 220 if (HasVector && !getTriple().isOSzOS()) 221 MaxVectorAlign = 64; 222 223 return true; 224 } 225 226 bool hasFeature(StringRef Feature) const override; 227 228 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 229 switch (CC) { 230 case CC_C: 231 case CC_Swift: 232 case CC_OpenCLKernel: 233 return CCCR_OK; 234 case CC_SwiftAsync: 235 return CCCR_Error; 236 default: 237 return CCCR_Warning; 238 } 239 } 240 241 StringRef getABI() const override { 242 if (HasVector) 243 return "vector"; 244 return ""; 245 } 246 247 const char *getLongDoubleMangling() const override { return "g"; } 248 249 bool hasBitIntType() const override { return true; } 250 251 int getEHDataRegisterNumber(unsigned RegNo) const override { 252 return RegNo < 4 ? 6 + RegNo : -1; 253 } 254 255 bool hasSjLjLowering() const override { return true; } 256 257 std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override { 258 return std::make_pair(256, 256); 259 } 260 uint64_t getPointerWidthV(LangAS AddrSpace) const override { 261 return (getTriple().isOSzOS() && getTriple().isArch64Bit() && 262 getTargetAddressSpace(AddrSpace) == ptr32) 263 ? 32 264 : PointerWidth; 265 } 266 267 uint64_t getPointerAlignV(LangAS AddrSpace) const override { 268 return getPointerWidthV(AddrSpace); 269 } 270 }; 271 } // namespace targets 272 } // namespace clang 273 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 274