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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares SystemZ TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H
14#define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H
15
16#include "clang/Basic/TargetInfo.h"
17#include "clang/Basic/TargetOptions.h"
18#include "llvm/ADT/Triple.h"
19#include "llvm/Support/Compiler.h"
20
21namespace clang {
22namespace targets {
23
24class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
25
26  static const Builtin::Info BuiltinInfo[];
27  static const char *const GCCRegNames[];
28  std::string CPU;
29  int ISARevision;
30  bool HasTransactionalExecution;
31  bool HasVector;
32
33public:
34  SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
35      : TargetInfo(Triple), CPU("z10"), ISARevision(8),
36        HasTransactionalExecution(false), HasVector(false) {
37    IntMaxType = SignedLong;
38    Int64Type = SignedLong;
39    TLSSupported = true;
40    IntWidth = IntAlign = 32;
41    LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
42    PointerWidth = PointerAlign = 64;
43    LongDoubleWidth = 128;
44    LongDoubleAlign = 64;
45    LongDoubleFormat = &llvm::APFloat::IEEEquad();
46    DefaultAlignForAttributeAligned = 64;
47    MinGlobalAlign = 16;
48    resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64");
49    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
50  }
51
52  void getTargetDefines(const LangOptions &Opts,
53                        MacroBuilder &Builder) const override;
54
55  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
56
57  ArrayRef<const char *> getGCCRegNames() const override;
58
59  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
60    // No aliases.
61    return None;
62  }
63
64  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
65
66  bool validateAsmConstraint(const char *&Name,
67                             TargetInfo::ConstraintInfo &info) const override;
68
69  const char *getClobbers() const override {
70    // FIXME: Is this really right?
71    return "";
72  }
73
74  BuiltinVaListKind getBuiltinVaListKind() const override {
75    return TargetInfo::SystemZBuiltinVaList;
76  }
77
78  int getISARevision(StringRef Name) const;
79
80  bool isValidCPUName(StringRef Name) const override {
81    return getISARevision(Name) != -1;
82  }
83
84  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
85
86  bool setCPU(const std::string &Name) override {
87    CPU = Name;
88    ISARevision = getISARevision(CPU);
89    return ISARevision != -1;
90  }
91
92  bool
93  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
94                 StringRef CPU,
95                 const std::vector<std::string> &FeaturesVec) const override {
96    int ISARevision = getISARevision(CPU);
97    if (ISARevision >= 10)
98      Features["transactional-execution"] = true;
99    if (ISARevision >= 11)
100      Features["vector"] = true;
101    if (ISARevision >= 12)
102      Features["vector-enhancements-1"] = true;
103    if (ISARevision >= 13)
104      Features["vector-enhancements-2"] = true;
105    return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
106  }
107
108  bool handleTargetFeatures(std::vector<std::string> &Features,
109                            DiagnosticsEngine &Diags) override {
110    HasTransactionalExecution = false;
111    HasVector = false;
112    for (const auto &Feature : Features) {
113      if (Feature == "+transactional-execution")
114        HasTransactionalExecution = true;
115      else if (Feature == "+vector")
116        HasVector = true;
117    }
118    // If we use the vector ABI, vector types are 64-bit aligned.
119    if (HasVector) {
120      MaxVectorAlign = 64;
121      resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"
122                      "-v128:64-a:8:16-n32:64");
123    }
124    return true;
125  }
126
127  bool hasFeature(StringRef Feature) const override;
128
129  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
130    switch (CC) {
131    case CC_C:
132    case CC_Swift:
133    case CC_OpenCLKernel:
134      return CCCR_OK;
135    default:
136      return CCCR_Warning;
137    }
138  }
139
140  StringRef getABI() const override {
141    if (HasVector)
142      return "vector";
143    return "";
144  }
145
146  const char *getLongDoubleMangling() const override { return "g"; }
147};
148} // namespace targets
149} // namespace clang
150#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H
151