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