xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/SystemZ.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
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