1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "SystemZ.h" |
14 | #include "clang/Basic/Builtins.h" |
15 | #include "clang/Basic/LangOptions.h" |
16 | #include "clang/Basic/MacroBuilder.h" |
17 | #include "clang/Basic/TargetBuiltins.h" |
18 | #include "llvm/ADT/StringSwitch.h" |
19 | |
20 | using namespace clang; |
21 | using namespace clang::targets; |
22 | |
23 | const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = { |
24 | #define BUILTIN(ID, TYPE, ATTRS) \ |
25 | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
26 | #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ |
27 | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE}, |
28 | #include "clang/Basic/BuiltinsSystemZ.def" |
29 | }; |
30 | |
31 | const char *const SystemZTargetInfo::GCCRegNames[] = { |
32 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", |
33 | "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", |
34 | "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7", |
35 | "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15", |
36 | , "cc", , , "a0", "a1", |
37 | "v16", "v18", "v20", "v22", "v17", "v19", "v21", "v23", |
38 | "v24", "v26", "v28", "v30", "v25", "v27", "v29", "v31" |
39 | }; |
40 | |
41 | const TargetInfo::AddlRegName GCCAddlRegNames[] = { |
42 | {{"v0"}, 16}, {{"v2"}, 17}, {{"v4"}, 18}, {{"v6"}, 19}, |
43 | {{"v1"}, 20}, {{"v3"}, 21}, {{"v5"}, 22}, {{"v7"}, 23}, |
44 | {{"v8"}, 24}, {{"v10"}, 25}, {{"v12"}, 26}, {{"v14"}, 27}, |
45 | {{"v9"}, 28}, {{"v11"}, 29}, {{"v13"}, 30}, {{"v15"}, 31} |
46 | }; |
47 | |
48 | ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const { |
49 | return llvm::makeArrayRef(GCCRegNames); |
50 | } |
51 | |
52 | ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const { |
53 | return llvm::makeArrayRef(GCCAddlRegNames); |
54 | } |
55 | |
56 | bool SystemZTargetInfo::validateAsmConstraint( |
57 | const char *&Name, TargetInfo::ConstraintInfo &Info) const { |
58 | switch (*Name) { |
59 | default: |
60 | return false; |
61 | |
62 | case 'a': |
63 | case 'd': |
64 | case 'f': |
65 | case 'v': |
66 | Info.setAllowsRegister(); |
67 | return true; |
68 | |
69 | case 'I': |
70 | case 'J': |
71 | case 'K': |
72 | case 'L': |
73 | case 'M': |
74 | return true; |
75 | |
76 | case 'Q': |
77 | case 'R': |
78 | case 'S': |
79 | case 'T': |
80 | Info.setAllowsMemory(); |
81 | return true; |
82 | } |
83 | } |
84 | |
85 | struct ISANameRevision { |
86 | llvm::StringLiteral Name; |
87 | int ISARevisionID; |
88 | }; |
89 | static constexpr ISANameRevision ISARevisions[] = { |
90 | {{"arch8"}, 8}, {{"z10"}, 8}, |
91 | {{"arch9"}, 9}, {{"z196"}, 9}, |
92 | {{"arch10"}, 10}, {{"zEC12"}, 10}, |
93 | {{"arch11"}, 11}, {{"z13"}, 11}, |
94 | {{"arch12"}, 12}, {{"z14"}, 12} |
95 | }; |
96 | |
97 | int SystemZTargetInfo::getISARevision(StringRef Name) const { |
98 | const auto Rev = |
99 | llvm::find_if(ISARevisions, [Name](const ISANameRevision &CR) { |
100 | return CR.Name == Name; |
101 | }); |
102 | if (Rev == std::end(ISARevisions)) |
103 | return -1; |
104 | return Rev->ISARevisionID; |
105 | } |
106 | |
107 | void SystemZTargetInfo::fillValidCPUList( |
108 | SmallVectorImpl<StringRef> &Values) const { |
109 | for (const ISANameRevision &Rev : ISARevisions) |
110 | Values.push_back(Rev.Name); |
111 | } |
112 | |
113 | bool SystemZTargetInfo::hasFeature(StringRef Feature) const { |
114 | return llvm::StringSwitch<bool>(Feature) |
115 | .Case("systemz", true) |
116 | .Case("arch8", ISARevision >= 8) |
117 | .Case("arch9", ISARevision >= 9) |
118 | .Case("arch10", ISARevision >= 10) |
119 | .Case("arch11", ISARevision >= 11) |
120 | .Case("arch12", ISARevision >= 12) |
121 | .Case("htm", HasTransactionalExecution) |
122 | .Case("vx", HasVector) |
123 | .Default(false); |
124 | } |
125 | |
126 | void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts, |
127 | MacroBuilder &Builder) const { |
128 | Builder.defineMacro("__s390__"); |
129 | Builder.defineMacro("__s390x__"); |
130 | Builder.defineMacro("__zarch__"); |
131 | Builder.defineMacro("__LONG_DOUBLE_128__"); |
132 | |
133 | Builder.defineMacro("__ARCH__", Twine(ISARevision)); |
134 | |
135 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
136 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
137 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
138 | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
139 | |
140 | if (HasTransactionalExecution) |
141 | Builder.defineMacro("__HTM__"); |
142 | if (HasVector) |
143 | Builder.defineMacro("__VX__"); |
144 | if (Opts.ZVector) |
145 | Builder.defineMacro("__VEC__", "10302"); |
146 | } |
147 | |
148 | ArrayRef<Builtin::Info> SystemZTargetInfo::getTargetBuiltins() const { |
149 | return llvm::makeArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin - |
150 | Builtin::FirstTSBuiltin); |
151 | } |
152 | |