1e5dd7070Spatrick //===--- SystemZ.cpp - Implement SystemZ target feature support -----------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements SystemZ TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "SystemZ.h"
14e5dd7070Spatrick #include "clang/Basic/Builtins.h"
15e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
16e5dd7070Spatrick #include "clang/Basic/MacroBuilder.h"
17e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h"
18e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
19e5dd7070Spatrick
20e5dd7070Spatrick using namespace clang;
21e5dd7070Spatrick using namespace clang::targets;
22e5dd7070Spatrick
23*12c85518Srobert static constexpr Builtin::Info BuiltinInfo[] = {
24e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS) \
25*12c85518Srobert {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
26e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
27*12c85518Srobert {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
28e5dd7070Spatrick #include "clang/Basic/BuiltinsSystemZ.def"
29e5dd7070Spatrick };
30e5dd7070Spatrick
31e5dd7070Spatrick const char *const SystemZTargetInfo::GCCRegNames[] = {
32e5dd7070Spatrick "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
33e5dd7070Spatrick "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
34e5dd7070Spatrick "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7",
35e5dd7070Spatrick "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15",
36e5dd7070Spatrick /*ap*/"", "cc", /*fp*/"", /*rp*/"", "a0", "a1",
37e5dd7070Spatrick "v16", "v18", "v20", "v22", "v17", "v19", "v21", "v23",
38e5dd7070Spatrick "v24", "v26", "v28", "v30", "v25", "v27", "v29", "v31"
39e5dd7070Spatrick };
40e5dd7070Spatrick
41e5dd7070Spatrick const TargetInfo::AddlRegName GCCAddlRegNames[] = {
42e5dd7070Spatrick {{"v0"}, 16}, {{"v2"}, 17}, {{"v4"}, 18}, {{"v6"}, 19},
43e5dd7070Spatrick {{"v1"}, 20}, {{"v3"}, 21}, {{"v5"}, 22}, {{"v7"}, 23},
44e5dd7070Spatrick {{"v8"}, 24}, {{"v10"}, 25}, {{"v12"}, 26}, {{"v14"}, 27},
45e5dd7070Spatrick {{"v9"}, 28}, {{"v11"}, 29}, {{"v13"}, 30}, {{"v15"}, 31}
46e5dd7070Spatrick };
47e5dd7070Spatrick
getGCCRegNames() const48e5dd7070Spatrick ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const {
49*12c85518Srobert return llvm::ArrayRef(GCCRegNames);
50e5dd7070Spatrick }
51e5dd7070Spatrick
getGCCAddlRegNames() const52e5dd7070Spatrick ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const {
53*12c85518Srobert return llvm::ArrayRef(GCCAddlRegNames);
54e5dd7070Spatrick }
55e5dd7070Spatrick
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const56e5dd7070Spatrick bool SystemZTargetInfo::validateAsmConstraint(
57e5dd7070Spatrick const char *&Name, TargetInfo::ConstraintInfo &Info) const {
58e5dd7070Spatrick switch (*Name) {
59e5dd7070Spatrick default:
60e5dd7070Spatrick return false;
61e5dd7070Spatrick
62*12c85518Srobert case 'Z':
63*12c85518Srobert switch (Name[1]) {
64*12c85518Srobert default:
65*12c85518Srobert return false;
66*12c85518Srobert case 'Q': // Address with base and unsigned 12-bit displacement
67*12c85518Srobert case 'R': // Likewise, plus an index
68*12c85518Srobert case 'S': // Address with base and signed 20-bit displacement
69*12c85518Srobert case 'T': // Likewise, plus an index
70*12c85518Srobert break;
71*12c85518Srobert }
72*12c85518Srobert [[fallthrough]];
73e5dd7070Spatrick case 'a': // Address register
74e5dd7070Spatrick case 'd': // Data register (equivalent to 'r')
75e5dd7070Spatrick case 'f': // Floating-point register
76e5dd7070Spatrick case 'v': // Vector register
77e5dd7070Spatrick Info.setAllowsRegister();
78e5dd7070Spatrick return true;
79e5dd7070Spatrick
80e5dd7070Spatrick case 'I': // Unsigned 8-bit constant
81e5dd7070Spatrick case 'J': // Unsigned 12-bit constant
82e5dd7070Spatrick case 'K': // Signed 16-bit constant
83e5dd7070Spatrick case 'L': // Signed 20-bit displacement (on all targets we support)
84e5dd7070Spatrick case 'M': // 0x7fffffff
85e5dd7070Spatrick return true;
86e5dd7070Spatrick
87e5dd7070Spatrick case 'Q': // Memory with base and unsigned 12-bit displacement
88e5dd7070Spatrick case 'R': // Likewise, plus an index
89e5dd7070Spatrick case 'S': // Memory with base and signed 20-bit displacement
90e5dd7070Spatrick case 'T': // Likewise, plus an index
91e5dd7070Spatrick Info.setAllowsMemory();
92e5dd7070Spatrick return true;
93e5dd7070Spatrick }
94e5dd7070Spatrick }
95e5dd7070Spatrick
96e5dd7070Spatrick struct ISANameRevision {
97e5dd7070Spatrick llvm::StringLiteral Name;
98e5dd7070Spatrick int ISARevisionID;
99e5dd7070Spatrick };
100e5dd7070Spatrick static constexpr ISANameRevision ISARevisions[] = {
101e5dd7070Spatrick {{"arch8"}, 8}, {{"z10"}, 8},
102e5dd7070Spatrick {{"arch9"}, 9}, {{"z196"}, 9},
103e5dd7070Spatrick {{"arch10"}, 10}, {{"zEC12"}, 10},
104e5dd7070Spatrick {{"arch11"}, 11}, {{"z13"}, 11},
105e5dd7070Spatrick {{"arch12"}, 12}, {{"z14"}, 12},
106a9ac8606Spatrick {{"arch13"}, 13}, {{"z15"}, 13},
107*12c85518Srobert {{"arch14"}, 14}, {{"z16"}, 14},
108e5dd7070Spatrick };
109e5dd7070Spatrick
getISARevision(StringRef Name) const110e5dd7070Spatrick int SystemZTargetInfo::getISARevision(StringRef Name) const {
111e5dd7070Spatrick const auto Rev =
112e5dd7070Spatrick llvm::find_if(ISARevisions, [Name](const ISANameRevision &CR) {
113e5dd7070Spatrick return CR.Name == Name;
114e5dd7070Spatrick });
115e5dd7070Spatrick if (Rev == std::end(ISARevisions))
116e5dd7070Spatrick return -1;
117e5dd7070Spatrick return Rev->ISARevisionID;
118e5dd7070Spatrick }
119e5dd7070Spatrick
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const120e5dd7070Spatrick void SystemZTargetInfo::fillValidCPUList(
121e5dd7070Spatrick SmallVectorImpl<StringRef> &Values) const {
122e5dd7070Spatrick for (const ISANameRevision &Rev : ISARevisions)
123e5dd7070Spatrick Values.push_back(Rev.Name);
124e5dd7070Spatrick }
125e5dd7070Spatrick
hasFeature(StringRef Feature) const126e5dd7070Spatrick bool SystemZTargetInfo::hasFeature(StringRef Feature) const {
127e5dd7070Spatrick return llvm::StringSwitch<bool>(Feature)
128e5dd7070Spatrick .Case("systemz", true)
129e5dd7070Spatrick .Case("arch8", ISARevision >= 8)
130e5dd7070Spatrick .Case("arch9", ISARevision >= 9)
131e5dd7070Spatrick .Case("arch10", ISARevision >= 10)
132e5dd7070Spatrick .Case("arch11", ISARevision >= 11)
133e5dd7070Spatrick .Case("arch12", ISARevision >= 12)
134e5dd7070Spatrick .Case("arch13", ISARevision >= 13)
135a9ac8606Spatrick .Case("arch14", ISARevision >= 14)
136e5dd7070Spatrick .Case("htm", HasTransactionalExecution)
137e5dd7070Spatrick .Case("vx", HasVector)
138e5dd7070Spatrick .Default(false);
139e5dd7070Spatrick }
140e5dd7070Spatrick
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const141e5dd7070Spatrick void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts,
142e5dd7070Spatrick MacroBuilder &Builder) const {
143e5dd7070Spatrick Builder.defineMacro("__s390__");
144e5dd7070Spatrick Builder.defineMacro("__s390x__");
145e5dd7070Spatrick Builder.defineMacro("__zarch__");
146e5dd7070Spatrick Builder.defineMacro("__LONG_DOUBLE_128__");
147e5dd7070Spatrick
148e5dd7070Spatrick Builder.defineMacro("__ARCH__", Twine(ISARevision));
149e5dd7070Spatrick
150e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
151e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
152e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
153e5dd7070Spatrick Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
154e5dd7070Spatrick
155e5dd7070Spatrick if (HasTransactionalExecution)
156e5dd7070Spatrick Builder.defineMacro("__HTM__");
157e5dd7070Spatrick if (HasVector)
158e5dd7070Spatrick Builder.defineMacro("__VX__");
159e5dd7070Spatrick if (Opts.ZVector)
160a9ac8606Spatrick Builder.defineMacro("__VEC__", "10304");
161e5dd7070Spatrick }
162e5dd7070Spatrick
getTargetBuiltins() const163e5dd7070Spatrick ArrayRef<Builtin::Info> SystemZTargetInfo::getTargetBuiltins() const {
164*12c85518Srobert return llvm::ArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin -
165e5dd7070Spatrick Builtin::FirstTSBuiltin);
166e5dd7070Spatrick }
167