296 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares SystemZ TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H14#define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H15 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 21namespace clang {22namespace targets {23 24static const unsigned ZOSAddressMap[] = {25 0, // Default26 0, // opencl_global27 0, // opencl_local28 0, // opencl_constant29 0, // opencl_private30 0, // opencl_generic31 0, // opencl_global_device32 0, // opencl_global_host33 0, // cuda_device34 0, // cuda_constant35 0, // cuda_shared36 0, // sycl_global37 0, // sycl_global_device38 0, // sycl_global_host39 0, // sycl_local40 0, // sycl_private41 0, // ptr32_sptr42 1, // ptr32_uptr43 0, // ptr6444 0, // hlsl_groupshared45 0, // hlsl_constant46 0, // hlsl_private47 0, // hlsl_device48 0, // hlsl_input49 0 // wasm_funcref50};51 52class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {53 54 static const char *const GCCRegNames[];55 int ISARevision;56 bool HasTransactionalExecution;57 bool HasVector;58 bool SoftFloat;59 bool UnalignedSymbols;60 enum AddrSpace { ptr32 = 1 };61 62public:63 SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)64 : TargetInfo(Triple), ISARevision(getISARevision("z10")),65 HasTransactionalExecution(false), HasVector(false), SoftFloat(false),66 UnalignedSymbols(false) {67 IntMaxType = SignedLong;68 Int64Type = SignedLong;69 IntWidth = IntAlign = 32;70 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;71 Int128Align = 64;72 PointerWidth = PointerAlign = 64;73 LongDoubleWidth = 128;74 LongDoubleAlign = 64;75 LongDoubleFormat = &llvm::APFloat::IEEEquad();76 DefaultAlignForAttributeAligned = 64;77 MinGlobalAlign = 16;78 HasUnalignedAccess = true;79 if (Triple.isOSzOS()) {80 if (Triple.isArch64Bit()) {81 AddrSpaceMap = &ZOSAddressMap;82 }83 TLSSupported = false;84 // All vector types are default aligned on an 8-byte boundary, even if the85 // vector facility is not available. That is different from Linux.86 MaxVectorAlign = 64;87 // Compared to Linux/ELF, the data layout differs only in some details:88 // - name mangling is GOFF.89 // - 32 bit pointers, either as default or special address space90 resetDataLayout("E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"91 "a:8:16-n32:64");92 } else {93 // Support _Float16.94 HasFloat16 = true;95 TLSSupported = true;96 resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"97 "-v128:64-a:8:16-n32:64");98 }99 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128;100 101 // True if the backend supports operations on the half LLVM IR type.102 // By setting this to false, conversions will happen for _Float16 around103 // a statement by default, with operations done in float. However, if104 // -ffloat16-excess-precision=none is given, no conversions will be made105 // and instead the backend will promote each half operation to float106 // individually.107 HasFastHalfType = false;108 109 HasStrictFP = true;110 }111 112 unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override;113 114 bool useFP16ConversionIntrinsics() const override { return false; }115 116 void getTargetDefines(const LangOptions &Opts,117 MacroBuilder &Builder) const override;118 119 llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;120 121 ArrayRef<const char *> getGCCRegNames() const override;122 123 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {124 // No aliases.125 return {};126 }127 128 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;129 130 bool isSPRegName(StringRef RegName) const override {131 return RegName == "r15";132 }133 134 bool validateAsmConstraint(const char *&Name,135 TargetInfo::ConstraintInfo &info) const override;136 137 std::string convertConstraint(const char *&Constraint) const override {138 switch (Constraint[0]) {139 case '@': // Flag output operand.140 if (llvm::StringRef(Constraint) == "@cc") {141 Constraint += 2;142 return std::string("{@cc}");143 }144 break;145 case 'p': // Keep 'p' constraint.146 return std::string("p");147 case 'Z':148 switch (Constraint[1]) {149 case 'Q': // Address with base and unsigned 12-bit displacement150 case 'R': // Likewise, plus an index151 case 'S': // Address with base and signed 20-bit displacement152 case 'T': // Likewise, plus an index153 // "^" hints llvm that this is a 2 letter constraint.154 // "Constraint++" is used to promote the string iterator155 // to the next constraint.156 return std::string("^") + std::string(Constraint++, 2);157 default:158 break;159 }160 break;161 default:162 break;163 }164 return TargetInfo::convertConstraint(Constraint);165 }166 167 std::string_view getClobbers() const override {168 // FIXME: Is this really right?169 return "";170 }171 172 BuiltinVaListKind getBuiltinVaListKind() const override {173 return TargetInfo::SystemZBuiltinVaList;174 }175 176 int getISARevision(StringRef Name) const;177 178 bool isValidCPUName(StringRef Name) const override {179 return getISARevision(Name) != -1;180 }181 182 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;183 184 bool isValidTuneCPUName(StringRef Name) const override {185 return isValidCPUName(Name);186 }187 188 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override {189 fillValidCPUList(Values);190 }191 192 bool setCPU(const std::string &Name) override {193 ISARevision = getISARevision(Name);194 return ISARevision != -1;195 }196 197 bool198 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,199 StringRef CPU,200 const std::vector<std::string> &FeaturesVec) const override {201 int ISARevision = getISARevision(CPU);202 if (ISARevision >= 10)203 Features["transactional-execution"] = true;204 if (ISARevision >= 11)205 Features["vector"] = true;206 if (ISARevision >= 12)207 Features["vector-enhancements-1"] = true;208 if (ISARevision >= 13)209 Features["vector-enhancements-2"] = true;210 if (ISARevision >= 14)211 Features["nnp-assist"] = true;212 if (ISARevision >= 15) {213 Features["miscellaneous-extensions-4"] = true;214 Features["vector-enhancements-3"] = true;215 }216 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);217 }218 219 bool handleTargetFeatures(std::vector<std::string> &Features,220 DiagnosticsEngine &Diags) override {221 HasTransactionalExecution = false;222 HasVector = false;223 SoftFloat = false;224 UnalignedSymbols = false;225 for (const auto &Feature : Features) {226 if (Feature == "+transactional-execution")227 HasTransactionalExecution = true;228 else if (Feature == "+vector")229 HasVector = true;230 else if (Feature == "+soft-float")231 SoftFloat = true;232 else if (Feature == "+unaligned-symbols")233 UnalignedSymbols = true;234 }235 HasVector &= !SoftFloat;236 237 // If we use the vector ABI, vector types are 64-bit aligned. The238 // DataLayout string is always set to this alignment as it is not a239 // requirement that it follows the alignment emitted by the front end. It240 // is assumed generally that the Datalayout should reflect only the241 // target triple and not any specific feature.242 if (HasVector && !getTriple().isOSzOS())243 MaxVectorAlign = 64;244 245 return true;246 }247 248 bool hasFeature(StringRef Feature) const override;249 250 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {251 switch (CC) {252 case CC_C:253 case CC_Swift:254 case CC_DeviceKernel:255 return CCCR_OK;256 case CC_SwiftAsync:257 return CCCR_Error;258 default:259 return CCCR_Warning;260 }261 }262 263 StringRef getABI() const override {264 if (HasVector)265 return "vector";266 return "";267 }268 269 const char *getLongDoubleMangling() const override { return "g"; }270 271 bool hasBitIntType() const override { return true; }272 273 int getEHDataRegisterNumber(unsigned RegNo) const override {274 return RegNo < 4 ? 6 + RegNo : -1;275 }276 277 bool hasSjLjLowering() const override { return true; }278 279 std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {280 return std::make_pair(256, 256);281 }282 uint64_t getPointerWidthV(LangAS AddrSpace) const override {283 return (getTriple().isOSzOS() && getTriple().isArch64Bit() &&284 getTargetAddressSpace(AddrSpace) == ptr32)285 ? 32286 : PointerWidth;287 }288 289 uint64_t getPointerAlignV(LangAS AddrSpace) const override {290 return getPointerWidthV(AddrSpace);291 }292};293} // namespace targets294} // namespace clang295#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H296