10b57cec5SDimitry Andric //===--- SystemZ.h - Declare SystemZ target feature support -----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares SystemZ TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 180b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace clang { 220b57cec5SDimitry Andric namespace targets { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric static const Builtin::Info BuiltinInfo[]; 270b57cec5SDimitry Andric static const char *const GCCRegNames[]; 280b57cec5SDimitry Andric std::string CPU; 290b57cec5SDimitry Andric int ISARevision; 300b57cec5SDimitry Andric bool HasTransactionalExecution; 310b57cec5SDimitry Andric bool HasVector; 325ffd83dbSDimitry Andric bool SoftFloat; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric public: 350b57cec5SDimitry Andric SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 360b57cec5SDimitry Andric : TargetInfo(Triple), CPU("z10"), ISARevision(8), 375ffd83dbSDimitry Andric HasTransactionalExecution(false), HasVector(false), SoftFloat(false) { 380b57cec5SDimitry Andric IntMaxType = SignedLong; 390b57cec5SDimitry Andric Int64Type = SignedLong; 400b57cec5SDimitry Andric TLSSupported = true; 410b57cec5SDimitry Andric IntWidth = IntAlign = 32; 420b57cec5SDimitry Andric LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 430b57cec5SDimitry Andric PointerWidth = PointerAlign = 64; 440b57cec5SDimitry Andric LongDoubleWidth = 128; 450b57cec5SDimitry Andric LongDoubleAlign = 64; 460b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEquad(); 470b57cec5SDimitry Andric DefaultAlignForAttributeAligned = 64; 480b57cec5SDimitry Andric MinGlobalAlign = 16; 490b57cec5SDimitry Andric resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); 500b57cec5SDimitry Andric MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 515ffd83dbSDimitry Andric HasStrictFP = true; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 550b57cec5SDimitry Andric MacroBuilder &Builder) const override; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 620b57cec5SDimitry Andric // No aliases. 630b57cec5SDimitry Andric return None; 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; 670b57cec5SDimitry Andric 685ffd83dbSDimitry Andric bool isSPRegName(StringRef RegName) const override { 695ffd83dbSDimitry Andric return RegName.equals("r15"); 705ffd83dbSDimitry Andric } 715ffd83dbSDimitry Andric 720b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 730b57cec5SDimitry Andric TargetInfo::ConstraintInfo &info) const override; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric const char *getClobbers() const override { 760b57cec5SDimitry Andric // FIXME: Is this really right? 770b57cec5SDimitry Andric return ""; 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 810b57cec5SDimitry Andric return TargetInfo::SystemZBuiltinVaList; 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric int getISARevision(StringRef Name) const; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const override { 870b57cec5SDimitry Andric return getISARevision(Name) != -1; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric bool setCPU(const std::string &Name) override { 930b57cec5SDimitry Andric CPU = Name; 940b57cec5SDimitry Andric ISARevision = getISARevision(CPU); 950b57cec5SDimitry Andric return ISARevision != -1; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric bool 990b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 1000b57cec5SDimitry Andric StringRef CPU, 1010b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override { 1020b57cec5SDimitry Andric int ISARevision = getISARevision(CPU); 1030b57cec5SDimitry Andric if (ISARevision >= 10) 1040b57cec5SDimitry Andric Features["transactional-execution"] = true; 1050b57cec5SDimitry Andric if (ISARevision >= 11) 1060b57cec5SDimitry Andric Features["vector"] = true; 1070b57cec5SDimitry Andric if (ISARevision >= 12) 1080b57cec5SDimitry Andric Features["vector-enhancements-1"] = true; 1090b57cec5SDimitry Andric if (ISARevision >= 13) 1100b57cec5SDimitry Andric Features["vector-enhancements-2"] = true; 1110b57cec5SDimitry Andric return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 1150b57cec5SDimitry Andric DiagnosticsEngine &Diags) override { 1160b57cec5SDimitry Andric HasTransactionalExecution = false; 1170b57cec5SDimitry Andric HasVector = false; 1185ffd83dbSDimitry Andric SoftFloat = false; 1190b57cec5SDimitry Andric for (const auto &Feature : Features) { 1200b57cec5SDimitry Andric if (Feature == "+transactional-execution") 1210b57cec5SDimitry Andric HasTransactionalExecution = true; 1220b57cec5SDimitry Andric else if (Feature == "+vector") 1230b57cec5SDimitry Andric HasVector = true; 1245ffd83dbSDimitry Andric else if (Feature == "+soft-float") 1255ffd83dbSDimitry Andric SoftFloat = true; 1260b57cec5SDimitry Andric } 1275ffd83dbSDimitry Andric HasVector &= !SoftFloat; 1285ffd83dbSDimitry Andric 1290b57cec5SDimitry Andric // If we use the vector ABI, vector types are 64-bit aligned. 1300b57cec5SDimitry Andric if (HasVector) { 1310b57cec5SDimitry Andric MaxVectorAlign = 64; 1320b57cec5SDimitry Andric resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" 1330b57cec5SDimitry Andric "-v128:64-a:8:16-n32:64"); 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric return true; 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 1410b57cec5SDimitry Andric switch (CC) { 1420b57cec5SDimitry Andric case CC_C: 1430b57cec5SDimitry Andric case CC_Swift: 1440b57cec5SDimitry Andric case CC_OpenCLKernel: 1450b57cec5SDimitry Andric return CCCR_OK; 1460b57cec5SDimitry Andric default: 1470b57cec5SDimitry Andric return CCCR_Warning; 1480b57cec5SDimitry Andric } 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric StringRef getABI() const override { 1520b57cec5SDimitry Andric if (HasVector) 1530b57cec5SDimitry Andric return "vector"; 1540b57cec5SDimitry Andric return ""; 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric const char *getLongDoubleMangling() const override { return "g"; } 1585ffd83dbSDimitry Andric 1595ffd83dbSDimitry Andric bool hasExtIntType() const override { return true; } 160*e8d8bef9SDimitry Andric 161*e8d8bef9SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override { 162*e8d8bef9SDimitry Andric return RegNo < 4 ? 6 + RegNo : -1; 163*e8d8bef9SDimitry Andric } 1640b57cec5SDimitry Andric }; 1650b57cec5SDimitry Andric } // namespace targets 1660b57cec5SDimitry Andric } // namespace clang 1670b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 168