blob: 2e01b7c3138e534a0ee2d99b99dec0170aacfa35 [file] [log] [blame]
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +00001//===--------------------- PredicateExpander.cpp --------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// Functionalities used by the Tablegen backends to expand machine predicates.
11//
12//===----------------------------------------------------------------------===//
13
14#include "PredicateExpander.h"
Andrea Di Biagioa9c15c12018-09-19 15:57:45 +000015#include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +000016
17namespace llvm {
18
Andrea Di Biagio87972c42018-08-13 15:13:35 +000019void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
20void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +000021
Andrea Di Biagio87972c42018-08-13 15:13:35 +000022void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000023 int ImmVal,
24 StringRef FunctionMapper) {
25 if (!FunctionMapper.empty())
26 OS << FunctionMapper << "(";
Andrea Di Biagio18850772018-07-17 16:11:37 +000027 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000028 << ").getImm()";
Evandro Menezes5f1a7662018-11-30 21:03:24 +000029 if (!FunctionMapper.empty())
30 OS << ")";
31 OS << (shouldNegate() ? " != " : " == ") << ImmVal;
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +000032}
33
Andrea Di Biagio87972c42018-08-13 15:13:35 +000034void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000035 StringRef ImmVal,
36 StringRef FunctionMapper) {
Evandro Menezes5f1a7662018-11-30 21:03:24 +000037 if (ImmVal.empty())
38 expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper);
39
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000040 if (!FunctionMapper.empty())
41 OS << FunctionMapper << "(";
Andrea Di Biagio18850772018-07-17 16:11:37 +000042 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000043 << ").getImm()";
Evandro Menezes5f1a7662018-11-30 21:03:24 +000044 if (!FunctionMapper.empty())
45 OS << ")";
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000046 OS << (shouldNegate() ? " != " : " == ") << ImmVal;
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +000047}
48
Evandro Menezes5f1a7662018-11-30 21:03:24 +000049void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS,
50 int OpIndex,
51 StringRef FunctionMapper) {
52 if (shouldNegate())
53 OS << "!";
54 if (!FunctionMapper.empty())
55 OS << FunctionMapper << "(";
56 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
57 << ").getImm()";
58 if (!FunctionMapper.empty())
59 OS << ")";
60}
61
Andrea Di Biagio87972c42018-08-13 15:13:35 +000062void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000063 const Record *Reg,
64 StringRef FunctionMapper) {
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +000065 assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
66
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000067 if (!FunctionMapper.empty())
68 OS << FunctionMapper << "(";
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +000069 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000070 << ").getReg()";
Evandro Menezes5f1a7662018-11-30 21:03:24 +000071 if (!FunctionMapper.empty())
72 OS << ")";
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +000073 OS << (shouldNegate() ? " != " : " == ");
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +000074 const StringRef Str = Reg->getValueAsString("Namespace");
75 if (!Str.empty())
76 OS << Str << "::";
77 OS << Reg->getName();
78}
79
Evandro Menezes5f1a7662018-11-30 21:03:24 +000080
81void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS,
82 int OpIndex,
83 StringRef FunctionMapper) {
84 if (shouldNegate())
85 OS << "!";
86 if (!FunctionMapper.empty())
87 OS << FunctionMapper << "(";
88 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
89 << ").getReg()";
90 if (!FunctionMapper.empty())
91 OS << ")";
92}
93
Andrea Di Biagio87972c42018-08-13 15:13:35 +000094void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
Andrea Di Biagio3ac65c42018-07-18 11:03:22 +000095 int OpIndex) {
96 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
97 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
98}
99
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000100void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
101 int Second) {
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000102 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
103 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
104 << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
105}
106
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000107void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000108 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
109 << (shouldNegate() ? "!= " : "== ") << NumOps;
110}
111
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000112void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000113 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
114 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
115 << "::" << Inst->getName();
116}
117
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000118void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000119 const RecVec &Opcodes) {
120 assert(!Opcodes.empty() && "Expected at least one opcode to check!");
121 bool First = true;
122
123 if (Opcodes.size() == 1) {
124 OS << "( ";
125 expandCheckOpcode(OS, Opcodes[0]);
126 OS << " )";
127 return;
128 }
129
130 OS << '(';
131 increaseIndentLevel();
132 for (const Record *Rec : Opcodes) {
133 OS << '\n';
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000134 OS.indent(getIndentLevel() * 2);
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000135 if (!First)
136 OS << (shouldNegate() ? "&& " : "|| ");
137
138 expandCheckOpcode(OS, Rec);
139 First = false;
140 }
141
142 OS << '\n';
143 decreaseIndentLevel();
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000144 OS.indent(getIndentLevel() * 2);
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000145 OS << ')';
146}
147
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000148void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000149 const RecVec &Opcodes) {
150 if (shouldExpandForMC())
151 expandFalse(OS);
152 else
153 expandCheckOpcode(OS, Opcodes);
154}
155
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000156void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000157 const RecVec &Sequence,
158 bool IsCheckAll) {
159 assert(!Sequence.empty() && "Found an invalid empty predicate set!");
160 if (Sequence.size() == 1)
161 return expandPredicate(OS, Sequence[0]);
162
163 // Okay, there is more than one predicate in the set.
164 bool First = true;
165 OS << (shouldNegate() ? "!(" : "(");
166 increaseIndentLevel();
167
168 bool OldValue = shouldNegate();
169 setNegatePredicate(false);
170 for (const Record *Rec : Sequence) {
171 OS << '\n';
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000172 OS.indent(getIndentLevel() * 2);
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000173 if (!First)
174 OS << (IsCheckAll ? "&& " : "|| ");
175 expandPredicate(OS, Rec);
176 First = false;
177 }
178 OS << '\n';
179 decreaseIndentLevel();
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000180 OS.indent(getIndentLevel() * 2);
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000181 OS << ')';
182 setNegatePredicate(OldValue);
183}
184
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000185void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000186 StringRef MethodName) {
187 OS << (shouldNegate() ? "!" : "");
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +0000188 OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000189 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
190}
191
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000192void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000193 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
194 << "getOperand(" << OpIndex << ").isReg() ";
195}
196
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000197void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000198 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
199 << "getOperand(" << OpIndex << ").isImm() ";
200}
201
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000202void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000203 StringRef MCInstFn,
204 StringRef MachineInstrFn) {
205 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
206 << (isByRef() ? "(MI)" : "(*MI)");
207}
208
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000209void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000210 StringRef Code) {
211 if (shouldExpandForMC())
212 return expandFalse(OS);
213
214 OS << '(' << Code << ')';
215}
216
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000217void PredicateExpander::expandReturnStatement(raw_ostream &OS,
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000218 const Record *Rec) {
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000219 std::string Buffer;
220 raw_string_ostream SS(Buffer);
221
222 SS << "return ";
223 expandPredicate(SS, Rec);
224 SS << ";";
225 SS.flush();
226 OS << Buffer;
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000227}
228
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000229void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000230 const Record *Rec) {
231 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
232 for (const Record *Opcode : Opcodes) {
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000233 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000234 OS << "case " << Opcode->getValueAsString("Namespace")
Evandro Menezese41f7782018-11-27 20:59:01 +0000235 << "::" << Opcode->getName() << ":\n";
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000236 }
237
238 increaseIndentLevel();
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000239 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000240 expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
241 decreaseIndentLevel();
242}
243
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000244void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000245 const RecVec &Cases,
246 const Record *Default) {
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000247 std::string Buffer;
248 raw_string_ostream SS(Buffer);
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000249
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000250 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000251 for (const Record *Rec : Cases) {
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000252 expandOpcodeSwitchCase(SS, Rec);
253 SS << '\n';
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000254 }
255
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000256 // Expand the default case.
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000257 SS.indent(getIndentLevel() * 2);
Evandro Menezese41f7782018-11-27 20:59:01 +0000258 SS << "default:\n";
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000259
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000260 increaseIndentLevel();
261 SS.indent(getIndentLevel() * 2);
262 expandStatement(SS, Default);
263 decreaseIndentLevel();
264 SS << '\n';
265
266 SS.indent(getIndentLevel() * 2);
267 SS << "} // end of switch-stmt";
268 SS.flush();
269 OS << Buffer;
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000270}
271
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000272void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
273 // Assume that padding has been added by the caller.
Andrea Di Biagiod99d6572018-08-09 15:32:48 +0000274 if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
275 expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
276 Rec->getValueAsDef("DefaultCase"));
277 return;
278 }
279
280 if (Rec->isSubClassOf("MCReturnStatement")) {
281 expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
282 return;
283 }
284
285 llvm_unreachable("No known rules to expand this MCStatement");
286}
287
Andrea Di Biagio87972c42018-08-13 15:13:35 +0000288void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
289 // Assume that padding has been added by the caller.
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000290 if (Rec->isSubClassOf("MCTrue")) {
291 if (shouldNegate())
292 return expandFalse(OS);
293 return expandTrue(OS);
294 }
295
296 if (Rec->isSubClassOf("MCFalse")) {
297 if (shouldNegate())
298 return expandTrue(OS);
299 return expandFalse(OS);
300 }
301
302 if (Rec->isSubClassOf("CheckNot")) {
303 flipNegatePredicate();
304 expandPredicate(OS, Rec->getValueAsDef("Pred"));
305 flipNegatePredicate();
306 return;
307 }
308
309 if (Rec->isSubClassOf("CheckIsRegOperand"))
310 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
311
312 if (Rec->isSubClassOf("CheckIsImmOperand"))
313 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
314
315 if (Rec->isSubClassOf("CheckRegOperand"))
316 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +0000317 Rec->getValueAsDef("Reg"),
318 Rec->getValueAsString("FunctionMapper"));
319
320 if (Rec->isSubClassOf("CheckRegOperandSimple"))
Evandro Menezes5f1a7662018-11-30 21:03:24 +0000321 return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
322 Rec->getValueAsString("FunctionMapper"));
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000323
Andrea Di Biagio3ac65c42018-07-18 11:03:22 +0000324 if (Rec->isSubClassOf("CheckInvalidRegOperand"))
325 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
326
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000327 if (Rec->isSubClassOf("CheckImmOperand"))
328 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +0000329 Rec->getValueAsInt("ImmVal"),
330 Rec->getValueAsString("FunctionMapper"));
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000331
332 if (Rec->isSubClassOf("CheckImmOperand_s"))
333 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
Andrea Di Biagiocf7570b2018-10-31 12:28:05 +0000334 Rec->getValueAsString("ImmVal"),
335 Rec->getValueAsString("FunctionMapper"));
336
337 if (Rec->isSubClassOf("CheckImmOperandSimple"))
Evandro Menezes5f1a7662018-11-30 21:03:24 +0000338 return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
339 Rec->getValueAsString("FunctionMapper"));
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000340
341 if (Rec->isSubClassOf("CheckSameRegOperand"))
342 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
343 Rec->getValueAsInt("SecondIndex"));
344
345 if (Rec->isSubClassOf("CheckNumOperands"))
346 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
347
348 if (Rec->isSubClassOf("CheckPseudo"))
349 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
350
351 if (Rec->isSubClassOf("CheckOpcode"))
352 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
353
354 if (Rec->isSubClassOf("CheckAll"))
355 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
356 /* AllOf */ true);
357
358 if (Rec->isSubClassOf("CheckAny"))
359 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
360 /* AllOf */ false);
361
362 if (Rec->isSubClassOf("CheckFunctionPredicate"))
363 return expandCheckFunctionPredicate(
364 OS, Rec->getValueAsString("MCInstFnName"),
365 Rec->getValueAsString("MachineInstrFnName"));
366
367 if (Rec->isSubClassOf("CheckNonPortable"))
368 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
369
370 if (Rec->isSubClassOf("TIIPredicate"))
Andrea Di Biagioe9759dd2018-08-14 18:36:54 +0000371 return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000372
373 llvm_unreachable("No known rules to expand this MCInstPredicate");
374}
375
Andrea Di Biagioa9c15c12018-09-19 15:57:45 +0000376void STIPredicateExpander::expandHeader(raw_ostream &OS,
377 const STIPredicateFunction &Fn) {
378 const Record *Rec = Fn.getDeclaration();
379 StringRef FunctionName = Rec->getValueAsString("Name");
380
381 OS.indent(getIndentLevel() * 2);
382 OS << "bool ";
383 if (shouldExpandDefinition())
384 OS << getClassPrefix() << "::";
385 OS << FunctionName << "(";
386 if (shouldExpandForMC())
387 OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
388 else
389 OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
390 if (Rec->getValueAsBit("UpdatesOpcodeMask"))
391 OS << ", APInt &Mask";
392 OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
393 if (shouldExpandDefinition()) {
394 OS << "{\n";
395 return;
396 }
397
398 if (Rec->getValueAsBit("OverridesBaseClassMember"))
399 OS << "override";
400 OS << ";\n";
401}
402
403void STIPredicateExpander::expandPrologue(raw_ostream &OS,
404 const STIPredicateFunction &Fn) {
405 RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
406 bool UpdatesOpcodeMask =
407 Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
408
409 increaseIndentLevel();
410 unsigned IndentLevel = getIndentLevel();
411 for (const Record *Delegate : Delegates) {
412 OS.indent(IndentLevel * 2);
413 OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
414 if (UpdatesOpcodeMask)
415 OS << ", Mask";
416 if (shouldExpandForMC())
417 OS << ", ProcessorID";
418 OS << "))\n";
419 OS.indent((1 + IndentLevel) * 2);
420 OS << "return true;\n\n";
421 }
422
423 if (shouldExpandForMC())
424 return;
425
426 OS.indent(IndentLevel * 2);
427 OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
428}
429
430void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
431 bool ShouldUpdateOpcodeMask) {
432 const OpcodeInfo &OI = Group.getOpcodeInfo();
433 for (const PredicateInfo &PI : OI.getPredicates()) {
434 const APInt &ProcModelMask = PI.ProcModelMask;
435 bool FirstProcID = true;
436 for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
437 if (!ProcModelMask[I])
438 continue;
439
440 if (FirstProcID) {
441 OS.indent(getIndentLevel() * 2);
442 OS << "if (ProcessorID == " << I;
443 } else {
444 OS << " || ProcessorID == " << I;
445 }
446 FirstProcID = false;
447 }
448
449 OS << ") {\n";
450
451 increaseIndentLevel();
452 OS.indent(getIndentLevel() * 2);
453 if (ShouldUpdateOpcodeMask) {
454 if (PI.OperandMask.isNullValue())
455 OS << "Mask.clearAllBits();\n";
456 else
457 OS << "Mask = " << PI.OperandMask << ";\n";
458 OS.indent(getIndentLevel() * 2);
459 }
460 OS << "return ";
461 expandPredicate(OS, PI.Predicate);
462 OS << ";\n";
463 decreaseIndentLevel();
464 OS.indent(getIndentLevel() * 2);
465 OS << "}\n";
466 }
467}
468
469void STIPredicateExpander::expandBody(raw_ostream &OS,
470 const STIPredicateFunction &Fn) {
471 bool UpdatesOpcodeMask =
472 Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
473
474 unsigned IndentLevel = getIndentLevel();
475 OS.indent(IndentLevel * 2);
476 OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
477 OS.indent(IndentLevel * 2);
478 OS << "default:\n";
479 OS.indent(IndentLevel * 2);
480 OS << " break;";
481
482 for (const OpcodeGroup &Group : Fn.getGroups()) {
483 for (const Record *Opcode : Group.getOpcodes()) {
484 OS << '\n';
485 OS.indent(IndentLevel * 2);
486 OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
487 }
488
489 OS << '\n';
490 increaseIndentLevel();
491 expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
492
493 OS.indent(getIndentLevel() * 2);
494 OS << "break;\n";
495 decreaseIndentLevel();
496 }
497
498 OS.indent(IndentLevel * 2);
499 OS << "}\n";
500}
501
502void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
503 const STIPredicateFunction &Fn) {
504 OS << '\n';
505 OS.indent(getIndentLevel() * 2);
506 OS << "return ";
507 expandPredicate(OS, Fn.getDefaultReturnPredicate());
508 OS << ";\n";
509
510 decreaseIndentLevel();
511 OS.indent(getIndentLevel() * 2);
512 StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
513 OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
514}
515
516void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
517 const STIPredicateFunction &Fn) {
518 const Record *Rec = Fn.getDeclaration();
519 if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
520 return;
521
522 expandHeader(OS, Fn);
523 if (shouldExpandDefinition()) {
524 expandPrologue(OS, Fn);
525 expandBody(OS, Fn);
526 expandEpilogue(OS, Fn);
527 }
528}
529
Andrea Di Biagioe68d92b2018-05-25 15:55:37 +0000530} // namespace llvm