106f32e7eSjoerg //===--- SystemZ.h - Declare SystemZ target feature support -----*- C++ -*-===// 206f32e7eSjoerg // 306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg // 706f32e7eSjoerg //===----------------------------------------------------------------------===// 806f32e7eSjoerg // 906f32e7eSjoerg // This file declares SystemZ TargetInfo objects. 1006f32e7eSjoerg // 1106f32e7eSjoerg //===----------------------------------------------------------------------===// 1206f32e7eSjoerg 1306f32e7eSjoerg #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 1406f32e7eSjoerg #define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 1506f32e7eSjoerg 1606f32e7eSjoerg #include "clang/Basic/TargetInfo.h" 1706f32e7eSjoerg #include "clang/Basic/TargetOptions.h" 1806f32e7eSjoerg #include "llvm/ADT/Triple.h" 1906f32e7eSjoerg #include "llvm/Support/Compiler.h" 2006f32e7eSjoerg 2106f32e7eSjoerg namespace clang { 2206f32e7eSjoerg namespace targets { 2306f32e7eSjoerg 2406f32e7eSjoerg class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { 2506f32e7eSjoerg 2606f32e7eSjoerg static const Builtin::Info BuiltinInfo[]; 2706f32e7eSjoerg static const char *const GCCRegNames[]; 2806f32e7eSjoerg std::string CPU; 2906f32e7eSjoerg int ISARevision; 3006f32e7eSjoerg bool HasTransactionalExecution; 3106f32e7eSjoerg bool HasVector; 32*13fbcb42Sjoerg bool SoftFloat; 3306f32e7eSjoerg 3406f32e7eSjoerg public: SystemZTargetInfo(const llvm::Triple & Triple,const TargetOptions &)3506f32e7eSjoerg SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 3606f32e7eSjoerg : TargetInfo(Triple), CPU("z10"), ISARevision(8), 37*13fbcb42Sjoerg HasTransactionalExecution(false), HasVector(false), SoftFloat(false) { 3806f32e7eSjoerg IntMaxType = SignedLong; 3906f32e7eSjoerg Int64Type = SignedLong; 4006f32e7eSjoerg TLSSupported = true; 4106f32e7eSjoerg IntWidth = IntAlign = 32; 4206f32e7eSjoerg LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; 4306f32e7eSjoerg PointerWidth = PointerAlign = 64; 4406f32e7eSjoerg LongDoubleWidth = 128; 4506f32e7eSjoerg LongDoubleAlign = 64; 4606f32e7eSjoerg LongDoubleFormat = &llvm::APFloat::IEEEquad(); 4706f32e7eSjoerg DefaultAlignForAttributeAligned = 64; 4806f32e7eSjoerg MinGlobalAlign = 16; 4906f32e7eSjoerg resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); 5006f32e7eSjoerg MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 51*13fbcb42Sjoerg HasStrictFP = true; 5206f32e7eSjoerg } 5306f32e7eSjoerg 5406f32e7eSjoerg void getTargetDefines(const LangOptions &Opts, 5506f32e7eSjoerg MacroBuilder &Builder) const override; 5606f32e7eSjoerg 5706f32e7eSjoerg ArrayRef<Builtin::Info> getTargetBuiltins() const override; 5806f32e7eSjoerg 5906f32e7eSjoerg ArrayRef<const char *> getGCCRegNames() const override; 6006f32e7eSjoerg getGCCRegAliases()6106f32e7eSjoerg ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 6206f32e7eSjoerg // No aliases. 6306f32e7eSjoerg return None; 6406f32e7eSjoerg } 6506f32e7eSjoerg 6606f32e7eSjoerg ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; 6706f32e7eSjoerg isSPRegName(StringRef RegName)68*13fbcb42Sjoerg bool isSPRegName(StringRef RegName) const override { 69*13fbcb42Sjoerg return RegName.equals("r15"); 70*13fbcb42Sjoerg } 71*13fbcb42Sjoerg 7206f32e7eSjoerg bool validateAsmConstraint(const char *&Name, 7306f32e7eSjoerg TargetInfo::ConstraintInfo &info) const override; 7406f32e7eSjoerg getClobbers()7506f32e7eSjoerg const char *getClobbers() const override { 7606f32e7eSjoerg // FIXME: Is this really right? 7706f32e7eSjoerg return ""; 7806f32e7eSjoerg } 7906f32e7eSjoerg getBuiltinVaListKind()8006f32e7eSjoerg BuiltinVaListKind getBuiltinVaListKind() const override { 8106f32e7eSjoerg return TargetInfo::SystemZBuiltinVaList; 8206f32e7eSjoerg } 8306f32e7eSjoerg 8406f32e7eSjoerg int getISARevision(StringRef Name) const; 8506f32e7eSjoerg isValidCPUName(StringRef Name)8606f32e7eSjoerg bool isValidCPUName(StringRef Name) const override { 8706f32e7eSjoerg return getISARevision(Name) != -1; 8806f32e7eSjoerg } 8906f32e7eSjoerg 9006f32e7eSjoerg void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 9106f32e7eSjoerg setCPU(const std::string & Name)9206f32e7eSjoerg bool setCPU(const std::string &Name) override { 9306f32e7eSjoerg CPU = Name; 9406f32e7eSjoerg ISARevision = getISARevision(CPU); 9506f32e7eSjoerg return ISARevision != -1; 9606f32e7eSjoerg } 9706f32e7eSjoerg 9806f32e7eSjoerg bool initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec)9906f32e7eSjoerg initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 10006f32e7eSjoerg StringRef CPU, 10106f32e7eSjoerg const std::vector<std::string> &FeaturesVec) const override { 10206f32e7eSjoerg int ISARevision = getISARevision(CPU); 10306f32e7eSjoerg if (ISARevision >= 10) 10406f32e7eSjoerg Features["transactional-execution"] = true; 10506f32e7eSjoerg if (ISARevision >= 11) 10606f32e7eSjoerg Features["vector"] = true; 10706f32e7eSjoerg if (ISARevision >= 12) 10806f32e7eSjoerg Features["vector-enhancements-1"] = true; 10906f32e7eSjoerg if (ISARevision >= 13) 11006f32e7eSjoerg Features["vector-enhancements-2"] = true; 11106f32e7eSjoerg return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 11206f32e7eSjoerg } 11306f32e7eSjoerg handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)11406f32e7eSjoerg bool handleTargetFeatures(std::vector<std::string> &Features, 11506f32e7eSjoerg DiagnosticsEngine &Diags) override { 11606f32e7eSjoerg HasTransactionalExecution = false; 11706f32e7eSjoerg HasVector = false; 118*13fbcb42Sjoerg SoftFloat = false; 11906f32e7eSjoerg for (const auto &Feature : Features) { 12006f32e7eSjoerg if (Feature == "+transactional-execution") 12106f32e7eSjoerg HasTransactionalExecution = true; 12206f32e7eSjoerg else if (Feature == "+vector") 12306f32e7eSjoerg HasVector = true; 124*13fbcb42Sjoerg else if (Feature == "+soft-float") 125*13fbcb42Sjoerg SoftFloat = true; 12606f32e7eSjoerg } 127*13fbcb42Sjoerg HasVector &= !SoftFloat; 128*13fbcb42Sjoerg 12906f32e7eSjoerg // If we use the vector ABI, vector types are 64-bit aligned. 13006f32e7eSjoerg if (HasVector) { 13106f32e7eSjoerg MaxVectorAlign = 64; 13206f32e7eSjoerg resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" 13306f32e7eSjoerg "-v128:64-a:8:16-n32:64"); 13406f32e7eSjoerg } 13506f32e7eSjoerg return true; 13606f32e7eSjoerg } 13706f32e7eSjoerg 13806f32e7eSjoerg bool hasFeature(StringRef Feature) const override; 13906f32e7eSjoerg checkCallingConvention(CallingConv CC)14006f32e7eSjoerg CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 14106f32e7eSjoerg switch (CC) { 14206f32e7eSjoerg case CC_C: 14306f32e7eSjoerg case CC_Swift: 14406f32e7eSjoerg case CC_OpenCLKernel: 14506f32e7eSjoerg return CCCR_OK; 14606f32e7eSjoerg default: 14706f32e7eSjoerg return CCCR_Warning; 14806f32e7eSjoerg } 14906f32e7eSjoerg } 15006f32e7eSjoerg getABI()15106f32e7eSjoerg StringRef getABI() const override { 15206f32e7eSjoerg if (HasVector) 15306f32e7eSjoerg return "vector"; 15406f32e7eSjoerg return ""; 15506f32e7eSjoerg } 15606f32e7eSjoerg getLongDoubleMangling()15706f32e7eSjoerg const char *getLongDoubleMangling() const override { return "g"; } 158*13fbcb42Sjoerg hasExtIntType()159*13fbcb42Sjoerg bool hasExtIntType() const override { return true; } 160*13fbcb42Sjoerg getEHDataRegisterNumber(unsigned RegNo)161*13fbcb42Sjoerg int getEHDataRegisterNumber(unsigned RegNo) const override { 162*13fbcb42Sjoerg return RegNo < 4 ? 6 + RegNo : -1; 163*13fbcb42Sjoerg } 16406f32e7eSjoerg }; 16506f32e7eSjoerg } // namespace targets 16606f32e7eSjoerg } // namespace clang 16706f32e7eSjoerg #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H 168