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