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