Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Basic/Targets/SystemZ.h
Line
Count
Source (jump to first uncovered line)
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/Support/Compiler.h"
19
#include "llvm/TargetParser/Triple.h"
20
21
namespace clang {
22
namespace targets {
23
24
class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
25
26
  static const char *const GCCRegNames[];
27
  std::string CPU;
28
  int ISARevision;
29
  bool HasTransactionalExecution;
30
  bool HasVector;
31
  bool SoftFloat;
32
33
public:
34
  SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
35
      : TargetInfo(Triple), CPU("z10"), ISARevision(8),
36
0
        HasTransactionalExecution(false), HasVector(false), SoftFloat(false) {
37
0
    IntMaxType = SignedLong;
38
0
    Int64Type = SignedLong;
39
0
    IntWidth = IntAlign = 32;
40
0
    LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
41
0
    Int128Align = 64;
42
0
    PointerWidth = PointerAlign = 64;
43
0
    LongDoubleWidth = 128;
44
0
    LongDoubleAlign = 64;
45
0
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
46
0
    DefaultAlignForAttributeAligned = 64;
47
0
    MinGlobalAlign = 16;
48
0
    if (Triple.isOSzOS()) {
49
0
      TLSSupported = false;
50
      // All vector types are default aligned on an 8-byte boundary, even if the
51
      // vector facility is not available. That is different from Linux.
52
0
      MaxVectorAlign = 64;
53
      // Compared to Linux/ELF, the data layout differs only in some details:
54
      // - name mangling is GOFF.
55
      // - 32 bit pointers, either as default or special address space
56
0
      resetDataLayout("E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
57
0
                      "a:8:16-n32:64");
58
0
    } else {
59
0
      TLSSupported = true;
60
0
      resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"
61
0
                      "-v128:64-a:8:16-n32:64");
62
0
    }
63
0
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128;
64
0
    HasStrictFP = true;
65
0
  }
66
67
  void getTargetDefines(const LangOptions &Opts,
68
                        MacroBuilder &Builder) const override;
69
70
  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
71
72
  ArrayRef<const char *> getGCCRegNames() const override;
73
74
0
  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
75
    // No aliases.
76
0
    return std::nullopt;
77
0
  }
78
79
  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
80
81
0
  bool isSPRegName(StringRef RegName) const override {
82
0
    return RegName.equals("r15");
83
0
  }
84
85
  bool validateAsmConstraint(const char *&Name,
86
                             TargetInfo::ConstraintInfo &info) const override;
87
88
0
  std::string convertConstraint(const char *&Constraint) const override {
89
0
    switch (Constraint[0]) {
90
0
    case 'p': // Keep 'p' constraint.
91
0
      return std::string("p");
92
0
    case 'Z':
93
0
      switch (Constraint[1]) {
94
0
      case 'Q': // Address with base and unsigned 12-bit displacement
95
0
      case 'R': // Likewise, plus an index
96
0
      case 'S': // Address with base and signed 20-bit displacement
97
0
      case 'T': // Likewise, plus an index
98
        // "^" hints llvm that this is a 2 letter constraint.
99
        // "Constraint++" is used to promote the string iterator
100
        // to the next constraint.
101
0
        return std::string("^") + std::string(Constraint++, 2);
102
0
      default:
103
0
        break;
104
0
      }
105
0
      break;
106
0
    default:
107
0
      break;
108
0
    }
109
0
    return TargetInfo::convertConstraint(Constraint);
110
0
  }
111
112
0
  std::string_view getClobbers() const override {
113
    // FIXME: Is this really right?
114
0
    return "";
115
0
  }
116
117
0
  BuiltinVaListKind getBuiltinVaListKind() const override {
118
0
    return TargetInfo::SystemZBuiltinVaList;
119
0
  }
120
121
  int getISARevision(StringRef Name) const;
122
123
0
  bool isValidCPUName(StringRef Name) const override {
124
0
    return getISARevision(Name) != -1;
125
0
  }
126
127
  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
128
129
0
  bool isValidTuneCPUName(StringRef Name) const override {
130
0
    return isValidCPUName(Name);
131
0
  }
132
133
0
  void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override {
134
0
    fillValidCPUList(Values);
135
0
  }
136
137
0
  bool setCPU(const std::string &Name) override {
138
0
    CPU = Name;
139
0
    ISARevision = getISARevision(CPU);
140
0
    return ISARevision != -1;
141
0
  }
142
143
  bool
144
  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
145
                 StringRef CPU,
146
0
                 const std::vector<std::string> &FeaturesVec) const override {
147
0
    int ISARevision = getISARevision(CPU);
148
0
    if (ISARevision >= 10)
149
0
      Features["transactional-execution"] = true;
150
0
    if (ISARevision >= 11)
151
0
      Features["vector"] = true;
152
0
    if (ISARevision >= 12)
153
0
      Features["vector-enhancements-1"] = true;
154
0
    if (ISARevision >= 13)
155
0
      Features["vector-enhancements-2"] = true;
156
0
    if (ISARevision >= 14)
157
0
      Features["nnp-assist"] = true;
158
0
    return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
159
0
  }
160
161
  bool handleTargetFeatures(std::vector<std::string> &Features,
162
0
                            DiagnosticsEngine &Diags) override {
163
0
    HasTransactionalExecution = false;
164
0
    HasVector = false;
165
0
    SoftFloat = false;
166
0
    for (const auto &Feature : Features) {
167
0
      if (Feature == "+transactional-execution")
168
0
        HasTransactionalExecution = true;
169
0
      else if (Feature == "+vector")
170
0
        HasVector = true;
171
0
      else if (Feature == "+soft-float")
172
0
        SoftFloat = true;
173
0
    }
174
0
    HasVector &= !SoftFloat;
175
176
    // If we use the vector ABI, vector types are 64-bit aligned. The
177
    // DataLayout string is always set to this alignment as it is not a
178
    // requirement that it follows the alignment emitted by the front end. It
179
    // is assumed generally that the Datalayout should reflect only the
180
    // target triple and not any specific feature.
181
0
    if (HasVector && !getTriple().isOSzOS())
182
0
      MaxVectorAlign = 64;
183
184
0
    return true;
185
0
  }
186
187
  bool hasFeature(StringRef Feature) const override;
188
189
0
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
190
0
    switch (CC) {
191
0
    case CC_C:
192
0
    case CC_Swift:
193
0
    case CC_OpenCLKernel:
194
0
      return CCCR_OK;
195
0
    case CC_SwiftAsync:
196
0
      return CCCR_Error;
197
0
    default:
198
0
      return CCCR_Warning;
199
0
    }
200
0
  }
201
202
0
  StringRef getABI() const override {
203
0
    if (HasVector)
204
0
      return "vector";
205
0
    return "";
206
0
  }
207
208
0
  const char *getLongDoubleMangling() const override { return "g"; }
209
210
0
  bool hasBitIntType() const override { return true; }
211
212
0
  int getEHDataRegisterNumber(unsigned RegNo) const override {
213
0
    return RegNo < 4 ? 6 + RegNo : -1;
214
0
  }
215
};
216
} // namespace targets
217
} // namespace clang
218
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H