annotate clang/utils/TableGen/ClangOpcodesEmitter.cpp @ 248:cfe92afade2b

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 16 Aug 2023 18:23:14 +0900
parents c4bab56944e8
children 1f2b6ac9f198
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //=== ClangOpcodesEmitter.cpp - constexpr interpreter opcodes ---*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 //
anatofuz
parents:
diff changeset
9 // These tablegen backends emit Clang AST node tables
anatofuz
parents:
diff changeset
10 //
anatofuz
parents:
diff changeset
11 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
12
anatofuz
parents:
diff changeset
13 #include "TableGenBackends.h"
anatofuz
parents:
diff changeset
14 #include "llvm/TableGen/Error.h"
anatofuz
parents:
diff changeset
15 #include "llvm/TableGen/Record.h"
anatofuz
parents:
diff changeset
16 #include "llvm/TableGen/StringMatcher.h"
anatofuz
parents:
diff changeset
17 #include "llvm/TableGen/TableGenBackend.h"
anatofuz
parents:
diff changeset
18
anatofuz
parents:
diff changeset
19 using namespace llvm;
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 namespace {
anatofuz
parents:
diff changeset
22 class ClangOpcodesEmitter {
anatofuz
parents:
diff changeset
23 RecordKeeper &Records;
anatofuz
parents:
diff changeset
24 Record Root;
anatofuz
parents:
diff changeset
25 unsigned NumTypes;
anatofuz
parents:
diff changeset
26
anatofuz
parents:
diff changeset
27 public:
anatofuz
parents:
diff changeset
28 ClangOpcodesEmitter(RecordKeeper &R)
anatofuz
parents:
diff changeset
29 : Records(R), Root("Opcode", SMLoc(), R),
anatofuz
parents:
diff changeset
30 NumTypes(Records.getAllDerivedDefinitions("Type").size()) {}
anatofuz
parents:
diff changeset
31
anatofuz
parents:
diff changeset
32 void run(raw_ostream &OS);
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 private:
anatofuz
parents:
diff changeset
35 /// Emits the opcode name for the opcode enum.
anatofuz
parents:
diff changeset
36 /// The name is obtained by concatenating the name with the list of types.
anatofuz
parents:
diff changeset
37 void EmitEnum(raw_ostream &OS, StringRef N, Record *R);
anatofuz
parents:
diff changeset
38
anatofuz
parents:
diff changeset
39 /// Emits the switch case and the invocation in the interpreter.
anatofuz
parents:
diff changeset
40 void EmitInterp(raw_ostream &OS, StringRef N, Record *R);
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 /// Emits the disassembler.
anatofuz
parents:
diff changeset
43 void EmitDisasm(raw_ostream &OS, StringRef N, Record *R);
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45 /// Emits the byte code emitter method.
anatofuz
parents:
diff changeset
46 void EmitEmitter(raw_ostream &OS, StringRef N, Record *R);
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 /// Emits the prototype.
anatofuz
parents:
diff changeset
49 void EmitProto(raw_ostream &OS, StringRef N, Record *R);
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 /// Emits the prototype to dispatch from a type.
anatofuz
parents:
diff changeset
52 void EmitGroup(raw_ostream &OS, StringRef N, Record *R);
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 /// Emits the evaluator method.
anatofuz
parents:
diff changeset
55 void EmitEval(raw_ostream &OS, StringRef N, Record *R);
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 void PrintTypes(raw_ostream &OS, ArrayRef<Record *> Types);
anatofuz
parents:
diff changeset
58 };
anatofuz
parents:
diff changeset
59
anatofuz
parents:
diff changeset
60 void Enumerate(const Record *R,
anatofuz
parents:
diff changeset
61 StringRef N,
anatofuz
parents:
diff changeset
62 std::function<void(ArrayRef<Record *>, Twine)> &&F) {
anatofuz
parents:
diff changeset
63 llvm::SmallVector<Record *, 2> TypePath;
anatofuz
parents:
diff changeset
64 auto *Types = R->getValueAsListInit("Types");
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 std::function<void(size_t, const Twine &)> Rec;
anatofuz
parents:
diff changeset
67 Rec = [&TypePath, Types, &Rec, &F](size_t I, const Twine &ID) {
anatofuz
parents:
diff changeset
68 if (I >= Types->size()) {
anatofuz
parents:
diff changeset
69 F(TypePath, ID);
anatofuz
parents:
diff changeset
70 return;
anatofuz
parents:
diff changeset
71 }
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 if (auto *TypeClass = dyn_cast<DefInit>(Types->getElement(I))) {
anatofuz
parents:
diff changeset
74 for (auto *Type : TypeClass->getDef()->getValueAsListOfDefs("Types")) {
anatofuz
parents:
diff changeset
75 TypePath.push_back(Type);
anatofuz
parents:
diff changeset
76 Rec(I + 1, ID + Type->getName());
anatofuz
parents:
diff changeset
77 TypePath.pop_back();
anatofuz
parents:
diff changeset
78 }
anatofuz
parents:
diff changeset
79 } else {
anatofuz
parents:
diff changeset
80 PrintFatalError("Expected a type class");
anatofuz
parents:
diff changeset
81 }
anatofuz
parents:
diff changeset
82 };
anatofuz
parents:
diff changeset
83 Rec(0, N);
anatofuz
parents:
diff changeset
84 }
anatofuz
parents:
diff changeset
85
anatofuz
parents:
diff changeset
86 } // namespace
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 void ClangOpcodesEmitter::run(raw_ostream &OS) {
anatofuz
parents:
diff changeset
89 for (auto *Opcode : Records.getAllDerivedDefinitions(Root.getName())) {
anatofuz
parents:
diff changeset
90 // The name is the record name, unless overriden.
anatofuz
parents:
diff changeset
91 StringRef N = Opcode->getValueAsString("Name");
anatofuz
parents:
diff changeset
92 if (N.empty())
anatofuz
parents:
diff changeset
93 N = Opcode->getName();
anatofuz
parents:
diff changeset
94
anatofuz
parents:
diff changeset
95 EmitEnum(OS, N, Opcode);
anatofuz
parents:
diff changeset
96 EmitInterp(OS, N, Opcode);
anatofuz
parents:
diff changeset
97 EmitDisasm(OS, N, Opcode);
anatofuz
parents:
diff changeset
98 EmitProto(OS, N, Opcode);
anatofuz
parents:
diff changeset
99 EmitGroup(OS, N, Opcode);
anatofuz
parents:
diff changeset
100 EmitEmitter(OS, N, Opcode);
anatofuz
parents:
diff changeset
101 EmitEval(OS, N, Opcode);
anatofuz
parents:
diff changeset
102 }
anatofuz
parents:
diff changeset
103 }
anatofuz
parents:
diff changeset
104
anatofuz
parents:
diff changeset
105 void ClangOpcodesEmitter::EmitEnum(raw_ostream &OS, StringRef N, Record *R) {
anatofuz
parents:
diff changeset
106 OS << "#ifdef GET_OPCODE_NAMES\n";
anatofuz
parents:
diff changeset
107 Enumerate(R, N, [&OS](ArrayRef<Record *>, const Twine &ID) {
anatofuz
parents:
diff changeset
108 OS << "OP_" << ID << ",\n";
anatofuz
parents:
diff changeset
109 });
anatofuz
parents:
diff changeset
110 OS << "#endif\n";
anatofuz
parents:
diff changeset
111 }
anatofuz
parents:
diff changeset
112
anatofuz
parents:
diff changeset
113 void ClangOpcodesEmitter::EmitInterp(raw_ostream &OS, StringRef N, Record *R) {
anatofuz
parents:
diff changeset
114 OS << "#ifdef GET_INTERP\n";
anatofuz
parents:
diff changeset
115
anatofuz
parents:
diff changeset
116 Enumerate(R, N, [this, R, &OS, &N](ArrayRef<Record *> TS, const Twine &ID) {
anatofuz
parents:
diff changeset
117 bool CanReturn = R->getValueAsBit("CanReturn");
anatofuz
parents:
diff changeset
118 bool ChangesPC = R->getValueAsBit("ChangesPC");
anatofuz
parents:
diff changeset
119 auto Args = R->getValueAsListOfDefs("Args");
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 OS << "case OP_" << ID << ": {\n";
anatofuz
parents:
diff changeset
122
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
123 if (CanReturn)
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
124 OS << " bool DoReturn = (S.Current == StartFrame);\n";
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
125
150
anatofuz
parents:
diff changeset
126 // Emit calls to read arguments.
anatofuz
parents:
diff changeset
127 for (size_t I = 0, N = Args.size(); I < N; ++I) {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
128 OS << " auto V" << I;
150
anatofuz
parents:
diff changeset
129 OS << " = ";
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
130 OS << "ReadArg<" << Args[I]->getValueAsString("Name") << ">(S, PC);\n";
150
anatofuz
parents:
diff changeset
131 }
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 // Emit a call to the template method and pass arguments.
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
134 OS << " if (!" << N;
150
anatofuz
parents:
diff changeset
135 PrintTypes(OS, TS);
anatofuz
parents:
diff changeset
136 OS << "(S";
anatofuz
parents:
diff changeset
137 if (ChangesPC)
anatofuz
parents:
diff changeset
138 OS << ", PC";
anatofuz
parents:
diff changeset
139 else
anatofuz
parents:
diff changeset
140 OS << ", OpPC";
anatofuz
parents:
diff changeset
141 if (CanReturn)
anatofuz
parents:
diff changeset
142 OS << ", Result";
anatofuz
parents:
diff changeset
143 for (size_t I = 0, N = Args.size(); I < N; ++I)
anatofuz
parents:
diff changeset
144 OS << ", V" << I;
anatofuz
parents:
diff changeset
145 OS << "))\n";
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
146 OS << " return false;\n";
150
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148 // Bail out if interpreter returned.
anatofuz
parents:
diff changeset
149 if (CanReturn) {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
150 OS << " if (!S.Current || S.Current->isRoot())\n";
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
151 OS << " return true;\n";
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
152
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
153 OS << " if (DoReturn)\n";
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
154 OS << " return true;\n";
150
anatofuz
parents:
diff changeset
155 }
anatofuz
parents:
diff changeset
156
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
157 OS << " continue;\n";
150
anatofuz
parents:
diff changeset
158 OS << "}\n";
anatofuz
parents:
diff changeset
159 });
anatofuz
parents:
diff changeset
160 OS << "#endif\n";
anatofuz
parents:
diff changeset
161 }
anatofuz
parents:
diff changeset
162
anatofuz
parents:
diff changeset
163 void ClangOpcodesEmitter::EmitDisasm(raw_ostream &OS, StringRef N, Record *R) {
anatofuz
parents:
diff changeset
164 OS << "#ifdef GET_DISASM\n";
anatofuz
parents:
diff changeset
165 Enumerate(R, N, [R, &OS](ArrayRef<Record *>, const Twine &ID) {
anatofuz
parents:
diff changeset
166 OS << "case OP_" << ID << ":\n";
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
167 OS << " PrintName(\"" << ID << "\");\n";
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
168 OS << " OS << \"\\t\"";
150
anatofuz
parents:
diff changeset
169
236
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
170 for (auto *Arg : R->getValueAsListOfDefs("Args")) {
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
171 OS << " << ReadArg<" << Arg->getValueAsString("Name") << ">(P, PC)";
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
172 OS << " << \" \"";
c4bab56944e8 LLVM 16
kono
parents: 221
diff changeset
173 }
150
anatofuz
parents:
diff changeset
174
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
175 OS << " << \"\\n\";\n";
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
176 OS << " continue;\n";
150
anatofuz
parents:
diff changeset
177 });
anatofuz
parents:
diff changeset
178 OS << "#endif\n";
anatofuz
parents:
diff changeset
179 }
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 void ClangOpcodesEmitter::EmitEmitter(raw_ostream &OS, StringRef N, Record *R) {
anatofuz
parents:
diff changeset
182 if (R->getValueAsBit("HasCustomLink"))
anatofuz
parents:
diff changeset
183 return;
anatofuz
parents:
diff changeset
184
anatofuz
parents:
diff changeset
185 OS << "#ifdef GET_LINK_IMPL\n";
anatofuz
parents:
diff changeset
186 Enumerate(R, N, [R, &OS](ArrayRef<Record *>, const Twine &ID) {
anatofuz
parents:
diff changeset
187 auto Args = R->getValueAsListOfDefs("Args");
anatofuz
parents:
diff changeset
188
anatofuz
parents:
diff changeset
189 // Emit the list of arguments.
anatofuz
parents:
diff changeset
190 OS << "bool ByteCodeEmitter::emit" << ID << "(";
anatofuz
parents:
diff changeset
191 for (size_t I = 0, N = Args.size(); I < N; ++I)
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
192 OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
150
anatofuz
parents:
diff changeset
193 OS << "const SourceInfo &L) {\n";
anatofuz
parents:
diff changeset
194
anatofuz
parents:
diff changeset
195 // Emit a call to write the opcodes.
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
196 OS << " return emitOp<";
150
anatofuz
parents:
diff changeset
197 for (size_t I = 0, N = Args.size(); I < N; ++I) {
anatofuz
parents:
diff changeset
198 if (I != 0)
anatofuz
parents:
diff changeset
199 OS << ", ";
anatofuz
parents:
diff changeset
200 OS << Args[I]->getValueAsString("Name");
anatofuz
parents:
diff changeset
201 }
anatofuz
parents:
diff changeset
202 OS << ">(OP_" << ID;
anatofuz
parents:
diff changeset
203 for (size_t I = 0, N = Args.size(); I < N; ++I)
anatofuz
parents:
diff changeset
204 OS << ", A" << I;
anatofuz
parents:
diff changeset
205 OS << ", L);\n";
anatofuz
parents:
diff changeset
206 OS << "}\n";
anatofuz
parents:
diff changeset
207 });
anatofuz
parents:
diff changeset
208 OS << "#endif\n";
anatofuz
parents:
diff changeset
209 }
anatofuz
parents:
diff changeset
210
anatofuz
parents:
diff changeset
211 void ClangOpcodesEmitter::EmitProto(raw_ostream &OS, StringRef N, Record *R) {
anatofuz
parents:
diff changeset
212 OS << "#if defined(GET_EVAL_PROTO) || defined(GET_LINK_PROTO)\n";
anatofuz
parents:
diff changeset
213 auto Args = R->getValueAsListOfDefs("Args");
anatofuz
parents:
diff changeset
214 Enumerate(R, N, [&OS, &Args](ArrayRef<Record *> TS, const Twine &ID) {
anatofuz
parents:
diff changeset
215 OS << "bool emit" << ID << "(";
anatofuz
parents:
diff changeset
216 for (auto *Arg : Args)
anatofuz
parents:
diff changeset
217 OS << Arg->getValueAsString("Name") << ", ";
anatofuz
parents:
diff changeset
218 OS << "const SourceInfo &);\n";
anatofuz
parents:
diff changeset
219 });
anatofuz
parents:
diff changeset
220
anatofuz
parents:
diff changeset
221 // Emit a template method for custom emitters to have less to implement.
anatofuz
parents:
diff changeset
222 auto TypeCount = R->getValueAsListInit("Types")->size();
anatofuz
parents:
diff changeset
223 if (R->getValueAsBit("HasCustomEval") && TypeCount) {
anatofuz
parents:
diff changeset
224 OS << "#if defined(GET_EVAL_PROTO)\n";
anatofuz
parents:
diff changeset
225 OS << "template<";
anatofuz
parents:
diff changeset
226 for (size_t I = 0; I < TypeCount; ++I) {
anatofuz
parents:
diff changeset
227 if (I != 0)
anatofuz
parents:
diff changeset
228 OS << ", ";
anatofuz
parents:
diff changeset
229 OS << "PrimType";
anatofuz
parents:
diff changeset
230 }
anatofuz
parents:
diff changeset
231 OS << ">\n";
anatofuz
parents:
diff changeset
232 OS << "bool emit" << N << "(";
anatofuz
parents:
diff changeset
233 for (auto *Arg : Args)
anatofuz
parents:
diff changeset
234 OS << Arg->getValueAsString("Name") << ", ";
anatofuz
parents:
diff changeset
235 OS << "const SourceInfo &);\n";
anatofuz
parents:
diff changeset
236 OS << "#endif\n";
anatofuz
parents:
diff changeset
237 }
anatofuz
parents:
diff changeset
238
anatofuz
parents:
diff changeset
239 OS << "#endif\n";
anatofuz
parents:
diff changeset
240 }
anatofuz
parents:
diff changeset
241
anatofuz
parents:
diff changeset
242 void ClangOpcodesEmitter::EmitGroup(raw_ostream &OS, StringRef N, Record *R) {
anatofuz
parents:
diff changeset
243 if (!R->getValueAsBit("HasGroup"))
anatofuz
parents:
diff changeset
244 return;
anatofuz
parents:
diff changeset
245
anatofuz
parents:
diff changeset
246 auto *Types = R->getValueAsListInit("Types");
anatofuz
parents:
diff changeset
247 auto Args = R->getValueAsListOfDefs("Args");
anatofuz
parents:
diff changeset
248
anatofuz
parents:
diff changeset
249 // Emit the prototype of the group emitter in the header.
anatofuz
parents:
diff changeset
250 OS << "#if defined(GET_EVAL_PROTO) || defined(GET_LINK_PROTO)\n";
anatofuz
parents:
diff changeset
251 OS << "bool emit" << N << "(";
anatofuz
parents:
diff changeset
252 for (size_t I = 0, N = Types->size(); I < N; ++I)
anatofuz
parents:
diff changeset
253 OS << "PrimType, ";
anatofuz
parents:
diff changeset
254 for (auto *Arg : Args)
anatofuz
parents:
diff changeset
255 OS << Arg->getValueAsString("Name") << ", ";
anatofuz
parents:
diff changeset
256 OS << "const SourceInfo &I);\n";
anatofuz
parents:
diff changeset
257 OS << "#endif\n";
anatofuz
parents:
diff changeset
258
anatofuz
parents:
diff changeset
259 // Emit the dispatch implementation in the source.
anatofuz
parents:
diff changeset
260 OS << "#if defined(GET_EVAL_IMPL) || defined(GET_LINK_IMPL)\n";
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
261 OS << "bool\n";
150
anatofuz
parents:
diff changeset
262 OS << "#if defined(GET_EVAL_IMPL)\n";
anatofuz
parents:
diff changeset
263 OS << "EvalEmitter\n";
anatofuz
parents:
diff changeset
264 OS << "#else\n";
anatofuz
parents:
diff changeset
265 OS << "ByteCodeEmitter\n";
anatofuz
parents:
diff changeset
266 OS << "#endif\n";
anatofuz
parents:
diff changeset
267 OS << "::emit" << N << "(";
anatofuz
parents:
diff changeset
268 for (size_t I = 0, N = Types->size(); I < N; ++I)
anatofuz
parents:
diff changeset
269 OS << "PrimType T" << I << ", ";
anatofuz
parents:
diff changeset
270 for (size_t I = 0, N = Args.size(); I < N; ++I)
anatofuz
parents:
diff changeset
271 OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
anatofuz
parents:
diff changeset
272 OS << "const SourceInfo &I) {\n";
anatofuz
parents:
diff changeset
273
anatofuz
parents:
diff changeset
274 std::function<void(size_t, const Twine &)> Rec;
anatofuz
parents:
diff changeset
275 llvm::SmallVector<Record *, 2> TS;
anatofuz
parents:
diff changeset
276 Rec = [this, &Rec, &OS, Types, &Args, R, &TS, N](size_t I, const Twine &ID) {
anatofuz
parents:
diff changeset
277 if (I >= Types->size()) {
anatofuz
parents:
diff changeset
278 // Print a call to the emitter method.
anatofuz
parents:
diff changeset
279 // Custom evaluator methods dispatch to template methods.
anatofuz
parents:
diff changeset
280 if (R->getValueAsBit("HasCustomEval")) {
anatofuz
parents:
diff changeset
281 OS << "#ifdef GET_LINK_IMPL\n";
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
282 OS << " return emit" << ID << "\n";
150
anatofuz
parents:
diff changeset
283 OS << "#else\n";
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
284 OS << " return emit" << N;
150
anatofuz
parents:
diff changeset
285 PrintTypes(OS, TS);
anatofuz
parents:
diff changeset
286 OS << "\n#endif\n";
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
287 OS << " ";
150
anatofuz
parents:
diff changeset
288 } else {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
289 OS << " return emit" << ID;
150
anatofuz
parents:
diff changeset
290 }
anatofuz
parents:
diff changeset
291
anatofuz
parents:
diff changeset
292 OS << "(";
anatofuz
parents:
diff changeset
293 for (size_t I = 0; I < Args.size(); ++I) {
anatofuz
parents:
diff changeset
294 OS << "A" << I << ", ";
anatofuz
parents:
diff changeset
295 }
anatofuz
parents:
diff changeset
296 OS << "I);\n";
anatofuz
parents:
diff changeset
297 return;
anatofuz
parents:
diff changeset
298 }
anatofuz
parents:
diff changeset
299
anatofuz
parents:
diff changeset
300 // Print a switch statement selecting T.
anatofuz
parents:
diff changeset
301 if (auto *TypeClass = dyn_cast<DefInit>(Types->getElement(I))) {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
302 OS << " switch (T" << I << ") {\n";
150
anatofuz
parents:
diff changeset
303 auto Cases = TypeClass->getDef()->getValueAsListOfDefs("Types");
anatofuz
parents:
diff changeset
304 for (auto *Case : Cases) {
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
305 OS << " case PT_" << Case->getName() << ":\n";
150
anatofuz
parents:
diff changeset
306 TS.push_back(Case);
anatofuz
parents:
diff changeset
307 Rec(I + 1, ID + Case->getName());
anatofuz
parents:
diff changeset
308 TS.pop_back();
anatofuz
parents:
diff changeset
309 }
anatofuz
parents:
diff changeset
310 // Emit a default case if not all types are present.
anatofuz
parents:
diff changeset
311 if (Cases.size() < NumTypes)
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
312 OS << " default: llvm_unreachable(\"invalid type\");\n";
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
313 OS << " }\n";
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
314 OS << " llvm_unreachable(\"invalid enum value\");\n";
150
anatofuz
parents:
diff changeset
315 } else {
anatofuz
parents:
diff changeset
316 PrintFatalError("Expected a type class");
anatofuz
parents:
diff changeset
317 }
anatofuz
parents:
diff changeset
318 };
anatofuz
parents:
diff changeset
319 Rec(0, N);
anatofuz
parents:
diff changeset
320
anatofuz
parents:
diff changeset
321 OS << "}\n";
anatofuz
parents:
diff changeset
322 OS << "#endif\n";
anatofuz
parents:
diff changeset
323 }
anatofuz
parents:
diff changeset
324
anatofuz
parents:
diff changeset
325 void ClangOpcodesEmitter::EmitEval(raw_ostream &OS, StringRef N, Record *R) {
anatofuz
parents:
diff changeset
326 if (R->getValueAsBit("HasCustomEval"))
anatofuz
parents:
diff changeset
327 return;
anatofuz
parents:
diff changeset
328
anatofuz
parents:
diff changeset
329 OS << "#ifdef GET_EVAL_IMPL\n";
anatofuz
parents:
diff changeset
330 Enumerate(R, N, [this, R, &N, &OS](ArrayRef<Record *> TS, const Twine &ID) {
anatofuz
parents:
diff changeset
331 auto Args = R->getValueAsListOfDefs("Args");
anatofuz
parents:
diff changeset
332
anatofuz
parents:
diff changeset
333 OS << "bool EvalEmitter::emit" << ID << "(";
anatofuz
parents:
diff changeset
334 for (size_t I = 0, N = Args.size(); I < N; ++I)
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
335 OS << Args[I]->getValueAsString("Name") << " A" << I << ", ";
150
anatofuz
parents:
diff changeset
336 OS << "const SourceInfo &L) {\n";
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
337 OS << " if (!isActive()) return true;\n";
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
338 OS << " CurrentSource = L;\n";
150
anatofuz
parents:
diff changeset
339
221
79ff65ed7e25 LLVM12 Original
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
340 OS << " return " << N;
150
anatofuz
parents:
diff changeset
341 PrintTypes(OS, TS);
anatofuz
parents:
diff changeset
342 OS << "(S, OpPC";
anatofuz
parents:
diff changeset
343 for (size_t I = 0, N = Args.size(); I < N; ++I)
anatofuz
parents:
diff changeset
344 OS << ", A" << I;
anatofuz
parents:
diff changeset
345 OS << ");\n";
anatofuz
parents:
diff changeset
346 OS << "}\n";
anatofuz
parents:
diff changeset
347 });
anatofuz
parents:
diff changeset
348
anatofuz
parents:
diff changeset
349 OS << "#endif\n";
anatofuz
parents:
diff changeset
350 }
anatofuz
parents:
diff changeset
351
anatofuz
parents:
diff changeset
352 void ClangOpcodesEmitter::PrintTypes(raw_ostream &OS, ArrayRef<Record *> Types) {
anatofuz
parents:
diff changeset
353 if (Types.empty())
anatofuz
parents:
diff changeset
354 return;
anatofuz
parents:
diff changeset
355 OS << "<";
anatofuz
parents:
diff changeset
356 for (size_t I = 0, N = Types.size(); I < N; ++I) {
anatofuz
parents:
diff changeset
357 if (I != 0)
anatofuz
parents:
diff changeset
358 OS << ", ";
anatofuz
parents:
diff changeset
359 OS << "PT_" << Types[I]->getName();
anatofuz
parents:
diff changeset
360 }
anatofuz
parents:
diff changeset
361 OS << ">";
anatofuz
parents:
diff changeset
362 }
anatofuz
parents:
diff changeset
363
anatofuz
parents:
diff changeset
364 void clang::EmitClangOpcodes(RecordKeeper &Records, raw_ostream &OS) {
anatofuz
parents:
diff changeset
365 ClangOpcodesEmitter(Records).run(OS);
anatofuz
parents:
diff changeset
366 }