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