17330f729Sjoerg //===--- SystemZ.h - Declare SystemZ target feature support -----*- C++ -*-===// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg // 97330f729Sjoerg // This file declares SystemZ TargetInfo objects. 107330f729Sjoerg // 117330f729Sjoerg //===----------------------------------------------------------------------===// 127330f729Sjoerg 137330f729Sjoerg #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 147330f729Sjoerg #define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 157330f729Sjoerg 167330f729Sjoerg #include "clang/Basic/TargetInfo.h" 177330f729Sjoerg #include "clang/Basic/TargetOptions.h" 187330f729Sjoerg #include "llvm/ADT/Triple.h" 197330f729Sjoerg #include "llvm/Support/Compiler.h" 207330f729Sjoerg 217330f729Sjoerg namespace clang { 227330f729Sjoerg namespace targets { 237330f729Sjoerg 247330f729Sjoerg class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { 257330f729Sjoerg 267330f729Sjoerg static const Builtin::Info BuiltinInfo[]; 277330f729Sjoerg static const char *const GCCRegNames[]; 287330f729Sjoerg std::string CPU; 297330f729Sjoerg int ISARevision; 307330f729Sjoerg bool HasTransactionalExecution; 317330f729Sjoerg bool HasVector; 32*e038c9c4Sjoerg bool SoftFloat; 337330f729Sjoerg 347330f729Sjoerg public: SystemZTargetInfo(const llvm::Triple & Triple,const TargetOptions &)357330f729Sjoerg SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 367330f729Sjoerg : TargetInfo(Triple), CPU("z10"), ISARevision(8), 37*e038c9c4Sjoerg HasTransactionalExecution(false), HasVector(false), SoftFloat(false) { 387330f729Sjoerg IntMaxType = SignedLong; 397330f729Sjoerg Int64Type = SignedLong; 407330f729Sjoerg TLSSupported = true; 417330f729Sjoerg IntWidth = IntAlign = 32; 427330f729Sjoerg LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 437330f729Sjoerg PointerWidth = PointerAlign = 64; 447330f729Sjoerg LongDoubleWidth = 128; 457330f729Sjoerg LongDoubleAlign = 64; 467330f729Sjoerg LongDoubleFormat = &llvm::APFloat::IEEEquad(); 477330f729Sjoerg DefaultAlignForAttributeAligned = 64; 487330f729Sjoerg MinGlobalAlign = 16; 497330f729Sjoerg resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); 507330f729Sjoerg MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 51*e038c9c4Sjoerg HasStrictFP = true; 527330f729Sjoerg } 537330f729Sjoerg 547330f729Sjoerg void getTargetDefines(const LangOptions &Opts, 557330f729Sjoerg MacroBuilder &Builder) const override; 567330f729Sjoerg 577330f729Sjoerg ArrayRef<Builtin::Info> getTargetBuiltins() const override; 587330f729Sjoerg 597330f729Sjoerg ArrayRef<const char *> getGCCRegNames() const override; 607330f729Sjoerg getGCCRegAliases()617330f729Sjoerg ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 627330f729Sjoerg // No aliases. 637330f729Sjoerg return None; 647330f729Sjoerg } 657330f729Sjoerg 667330f729Sjoerg ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; 677330f729Sjoerg isSPRegName(StringRef RegName)68*e038c9c4Sjoerg bool isSPRegName(StringRef RegName) const override { 69*e038c9c4Sjoerg return RegName.equals("r15"); 70*e038c9c4Sjoerg } 71*e038c9c4Sjoerg 727330f729Sjoerg bool validateAsmConstraint(const char *&Name, 737330f729Sjoerg TargetInfo::ConstraintInfo &info) const override; 747330f729Sjoerg getClobbers()757330f729Sjoerg const char *getClobbers() const override { 767330f729Sjoerg // FIXME: Is this really right? 777330f729Sjoerg return ""; 787330f729Sjoerg } 797330f729Sjoerg getBuiltinVaListKind()807330f729Sjoerg BuiltinVaListKind getBuiltinVaListKind() const override { 817330f729Sjoerg return TargetInfo::SystemZBuiltinVaList; 827330f729Sjoerg } 837330f729Sjoerg 847330f729Sjoerg int getISARevision(StringRef Name) const; 857330f729Sjoerg isValidCPUName(StringRef Name)867330f729Sjoerg bool isValidCPUName(StringRef Name) const override { 877330f729Sjoerg return getISARevision(Name) != -1; 887330f729Sjoerg } 897330f729Sjoerg 907330f729Sjoerg void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 917330f729Sjoerg setCPU(const std::string & Name)927330f729Sjoerg bool setCPU(const std::string &Name) override { 937330f729Sjoerg CPU = Name; 947330f729Sjoerg ISARevision = getISARevision(CPU); 957330f729Sjoerg return ISARevision != -1; 967330f729Sjoerg } 977330f729Sjoerg 987330f729Sjoerg bool initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec)997330f729Sjoerg initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 1007330f729Sjoerg StringRef CPU, 1017330f729Sjoerg const std::vector<std::string> &FeaturesVec) const override { 1027330f729Sjoerg int ISARevision = getISARevision(CPU); 1037330f729Sjoerg if (ISARevision >= 10) 1047330f729Sjoerg Features["transactional-execution"] = true; 1057330f729Sjoerg if (ISARevision >= 11) 1067330f729Sjoerg Features["vector"] = true; 1077330f729Sjoerg if (ISARevision >= 12) 1087330f729Sjoerg Features["vector-enhancements-1"] = true; 1097330f729Sjoerg if (ISARevision >= 13) 1107330f729Sjoerg Features["vector-enhancements-2"] = true; 1117330f729Sjoerg return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 1127330f729Sjoerg } 1137330f729Sjoerg handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)1147330f729Sjoerg bool handleTargetFeatures(std::vector<std::string> &Features, 1157330f729Sjoerg DiagnosticsEngine &Diags) override { 1167330f729Sjoerg HasTransactionalExecution = false; 1177330f729Sjoerg HasVector = false; 118*e038c9c4Sjoerg SoftFloat = false; 1197330f729Sjoerg for (const auto &Feature : Features) { 1207330f729Sjoerg if (Feature == "+transactional-execution") 1217330f729Sjoerg HasTransactionalExecution = true; 1227330f729Sjoerg else if (Feature == "+vector") 1237330f729Sjoerg HasVector = true; 124*e038c9c4Sjoerg else if (Feature == "+soft-float") 125*e038c9c4Sjoerg SoftFloat = true; 1267330f729Sjoerg } 127*e038c9c4Sjoerg HasVector &= !SoftFloat; 128*e038c9c4Sjoerg 1297330f729Sjoerg // If we use the vector ABI, vector types are 64-bit aligned. 1307330f729Sjoerg if (HasVector) { 1317330f729Sjoerg MaxVectorAlign = 64; 1327330f729Sjoerg resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" 1337330f729Sjoerg "-v128:64-a:8:16-n32:64"); 1347330f729Sjoerg } 1357330f729Sjoerg return true; 1367330f729Sjoerg } 1377330f729Sjoerg 1387330f729Sjoerg bool hasFeature(StringRef Feature) const override; 1397330f729Sjoerg checkCallingConvention(CallingConv CC)1407330f729Sjoerg CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 1417330f729Sjoerg switch (CC) { 1427330f729Sjoerg case CC_C: 1437330f729Sjoerg case CC_Swift: 1447330f729Sjoerg case CC_OpenCLKernel: 1457330f729Sjoerg return CCCR_OK; 1467330f729Sjoerg default: 1477330f729Sjoerg return CCCR_Warning; 1487330f729Sjoerg } 1497330f729Sjoerg } 1507330f729Sjoerg getABI()1517330f729Sjoerg StringRef getABI() const override { 1527330f729Sjoerg if (HasVector) 1537330f729Sjoerg return "vector"; 1547330f729Sjoerg return ""; 1557330f729Sjoerg } 1567330f729Sjoerg getLongDoubleMangling()1577330f729Sjoerg const char *getLongDoubleMangling() const override { return "g"; } 158*e038c9c4Sjoerg hasExtIntType()159*e038c9c4Sjoerg bool hasExtIntType() const override { return true; } 160*e038c9c4Sjoerg getEHDataRegisterNumber(unsigned RegNo)161*e038c9c4Sjoerg int getEHDataRegisterNumber(unsigned RegNo) const override { 162*e038c9c4Sjoerg return RegNo < 4 ? 6 + RegNo : -1; 163*e038c9c4Sjoerg } 1647330f729Sjoerg }; 1657330f729Sjoerg } // namespace targets 1667330f729Sjoerg } // namespace clang 1677330f729Sjoerg #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 168