1 //===--------------------- PredicateExpander.cpp --------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// Functionalities used by the Tablegen backends to expand machine predicates.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "PredicateExpander.h"
14 #include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
15 #include "llvm/TableGen/Record.h"
16
17 namespace llvm {
18
expandTrue(raw_ostream & OS)19 void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
expandFalse(raw_ostream & OS)20 void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
21
expandCheckImmOperand(raw_ostream & OS,int OpIndex,int ImmVal,StringRef FunctionMapper)22 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
23 int ImmVal,
24 StringRef FunctionMapper) {
25 if (!FunctionMapper.empty())
26 OS << FunctionMapper << "(";
27 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
28 << ").getImm()";
29 if (!FunctionMapper.empty())
30 OS << ")";
31 OS << (shouldNegate() ? " != " : " == ") << ImmVal;
32 }
33
expandCheckImmOperand(raw_ostream & OS,int OpIndex,StringRef ImmVal,StringRef FunctionMapper)34 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
35 StringRef ImmVal,
36 StringRef FunctionMapper) {
37 if (ImmVal.empty())
38 expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper);
39
40 if (!FunctionMapper.empty())
41 OS << FunctionMapper << "(";
42 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
43 << ").getImm()";
44 if (!FunctionMapper.empty())
45 OS << ")";
46 OS << (shouldNegate() ? " != " : " == ") << ImmVal;
47 }
48
expandCheckImmOperandSimple(raw_ostream & OS,int OpIndex,StringRef FunctionMapper)49 void 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
expandCheckImmOperandLT(raw_ostream & OS,int OpIndex,int ImmVal,StringRef FunctionMapper)62 void PredicateExpander::expandCheckImmOperandLT(raw_ostream &OS, int OpIndex,
63 int ImmVal,
64 StringRef FunctionMapper) {
65 if (!FunctionMapper.empty())
66 OS << FunctionMapper << "(";
67 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
68 << ").getImm()";
69 if (!FunctionMapper.empty())
70 OS << ")";
71 OS << (shouldNegate() ? " >= " : " < ") << ImmVal;
72 }
73
expandCheckImmOperandGT(raw_ostream & OS,int OpIndex,int ImmVal,StringRef FunctionMapper)74 void PredicateExpander::expandCheckImmOperandGT(raw_ostream &OS, int OpIndex,
75 int ImmVal,
76 StringRef FunctionMapper) {
77 if (!FunctionMapper.empty())
78 OS << FunctionMapper << "(";
79 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
80 << ").getImm()";
81 if (!FunctionMapper.empty())
82 OS << ")";
83 OS << (shouldNegate() ? " <= " : " > ") << ImmVal;
84 }
85
expandCheckRegOperand(raw_ostream & OS,int OpIndex,const Record * Reg,StringRef FunctionMapper)86 void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
87 const Record *Reg,
88 StringRef FunctionMapper) {
89 assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
90
91 if (!FunctionMapper.empty())
92 OS << FunctionMapper << "(";
93 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
94 << ").getReg()";
95 if (!FunctionMapper.empty())
96 OS << ")";
97 OS << (shouldNegate() ? " != " : " == ");
98 const StringRef Str = Reg->getValueAsString("Namespace");
99 if (!Str.empty())
100 OS << Str << "::";
101 OS << Reg->getName();
102 }
103
104
expandCheckRegOperandSimple(raw_ostream & OS,int OpIndex,StringRef FunctionMapper)105 void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS,
106 int OpIndex,
107 StringRef FunctionMapper) {
108 if (shouldNegate())
109 OS << "!";
110 if (!FunctionMapper.empty())
111 OS << FunctionMapper << "(";
112 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
113 << ").getReg()";
114 if (!FunctionMapper.empty())
115 OS << ")";
116 }
117
expandCheckInvalidRegOperand(raw_ostream & OS,int OpIndex)118 void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
119 int OpIndex) {
120 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
121 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
122 }
123
expandCheckSameRegOperand(raw_ostream & OS,int First,int Second)124 void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
125 int Second) {
126 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
127 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
128 << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
129 }
130
expandCheckNumOperands(raw_ostream & OS,int NumOps)131 void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
132 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
133 << (shouldNegate() ? "!= " : "== ") << NumOps;
134 }
135
expandCheckOpcode(raw_ostream & OS,const Record * Inst)136 void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
137 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
138 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
139 << "::" << Inst->getName();
140 }
141
expandCheckOpcode(raw_ostream & OS,const RecVec & Opcodes)142 void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
143 const RecVec &Opcodes) {
144 assert(!Opcodes.empty() && "Expected at least one opcode to check!");
145 bool First = true;
146
147 if (Opcodes.size() == 1) {
148 OS << "( ";
149 expandCheckOpcode(OS, Opcodes[0]);
150 OS << " )";
151 return;
152 }
153
154 OS << '(';
155 increaseIndentLevel();
156 for (const Record *Rec : Opcodes) {
157 OS << '\n';
158 OS.indent(getIndentLevel() * 2);
159 if (!First)
160 OS << (shouldNegate() ? "&& " : "|| ");
161
162 expandCheckOpcode(OS, Rec);
163 First = false;
164 }
165
166 OS << '\n';
167 decreaseIndentLevel();
168 OS.indent(getIndentLevel() * 2);
169 OS << ')';
170 }
171
expandCheckPseudo(raw_ostream & OS,const RecVec & Opcodes)172 void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
173 const RecVec &Opcodes) {
174 if (shouldExpandForMC())
175 expandFalse(OS);
176 else
177 expandCheckOpcode(OS, Opcodes);
178 }
179
expandPredicateSequence(raw_ostream & OS,const RecVec & Sequence,bool IsCheckAll)180 void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
181 const RecVec &Sequence,
182 bool IsCheckAll) {
183 assert(!Sequence.empty() && "Found an invalid empty predicate set!");
184 if (Sequence.size() == 1)
185 return expandPredicate(OS, Sequence[0]);
186
187 // Okay, there is more than one predicate in the set.
188 bool First = true;
189 OS << (shouldNegate() ? "!(" : "(");
190 increaseIndentLevel();
191
192 bool OldValue = shouldNegate();
193 setNegatePredicate(false);
194 for (const Record *Rec : Sequence) {
195 OS << '\n';
196 OS.indent(getIndentLevel() * 2);
197 if (!First)
198 OS << (IsCheckAll ? "&& " : "|| ");
199 expandPredicate(OS, Rec);
200 First = false;
201 }
202 OS << '\n';
203 decreaseIndentLevel();
204 OS.indent(getIndentLevel() * 2);
205 OS << ')';
206 setNegatePredicate(OldValue);
207 }
208
expandTIIFunctionCall(raw_ostream & OS,StringRef MethodName)209 void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
210 StringRef MethodName) {
211 OS << (shouldNegate() ? "!" : "");
212 OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
213 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
214 }
215
expandCheckIsRegOperand(raw_ostream & OS,int OpIndex)216 void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
217 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
218 << "getOperand(" << OpIndex << ").isReg() ";
219 }
220
expandCheckIsVRegOperand(raw_ostream & OS,int OpIndex)221 void PredicateExpander::expandCheckIsVRegOperand(raw_ostream &OS, int OpIndex) {
222 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
223 << "getOperand(" << OpIndex << ").getReg().isVirtual()";
224 }
225
expandCheckIsImmOperand(raw_ostream & OS,int OpIndex)226 void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
227 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
228 << "getOperand(" << OpIndex << ").isImm() ";
229 }
230
expandCheckFunctionPredicateWithTII(raw_ostream & OS,StringRef MCInstFn,StringRef MachineInstrFn,StringRef TIIPtr)231 void PredicateExpander::expandCheckFunctionPredicateWithTII(
232 raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn,
233 StringRef TIIPtr) {
234 if (!shouldExpandForMC()) {
235 OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn;
236 OS << (isByRef() ? "(MI)" : "(*MI)");
237 return;
238 }
239
240 OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)";
241 }
242
expandCheckFunctionPredicate(raw_ostream & OS,StringRef MCInstFn,StringRef MachineInstrFn)243 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
244 StringRef MCInstFn,
245 StringRef MachineInstrFn) {
246 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
247 << (isByRef() ? "(MI)" : "(*MI)");
248 }
249
expandCheckNonPortable(raw_ostream & OS,StringRef Code)250 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
251 StringRef Code) {
252 if (shouldExpandForMC())
253 return expandFalse(OS);
254
255 OS << '(' << Code << ')';
256 }
257
expandReturnStatement(raw_ostream & OS,const Record * Rec)258 void PredicateExpander::expandReturnStatement(raw_ostream &OS,
259 const Record *Rec) {
260 std::string Buffer;
261 raw_string_ostream SS(Buffer);
262
263 SS << "return ";
264 expandPredicate(SS, Rec);
265 SS << ";";
266 OS << Buffer;
267 }
268
expandOpcodeSwitchCase(raw_ostream & OS,const Record * Rec)269 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
270 const Record *Rec) {
271 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
272 for (const Record *Opcode : Opcodes) {
273 OS.indent(getIndentLevel() * 2);
274 OS << "case " << Opcode->getValueAsString("Namespace")
275 << "::" << Opcode->getName() << ":\n";
276 }
277
278 increaseIndentLevel();
279 OS.indent(getIndentLevel() * 2);
280 expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
281 decreaseIndentLevel();
282 }
283
expandOpcodeSwitchStatement(raw_ostream & OS,const RecVec & Cases,const Record * Default)284 void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
285 const RecVec &Cases,
286 const Record *Default) {
287 std::string Buffer;
288 raw_string_ostream SS(Buffer);
289
290 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
291 for (const Record *Rec : Cases) {
292 expandOpcodeSwitchCase(SS, Rec);
293 SS << '\n';
294 }
295
296 // Expand the default case.
297 SS.indent(getIndentLevel() * 2);
298 SS << "default:\n";
299
300 increaseIndentLevel();
301 SS.indent(getIndentLevel() * 2);
302 expandStatement(SS, Default);
303 decreaseIndentLevel();
304 SS << '\n';
305
306 SS.indent(getIndentLevel() * 2);
307 SS << "} // end of switch-stmt";
308 OS << Buffer;
309 }
310
expandStatement(raw_ostream & OS,const Record * Rec)311 void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
312 // Assume that padding has been added by the caller.
313 if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
314 expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
315 Rec->getValueAsDef("DefaultCase"));
316 return;
317 }
318
319 if (Rec->isSubClassOf("MCReturnStatement")) {
320 expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
321 return;
322 }
323
324 llvm_unreachable("No known rules to expand this MCStatement");
325 }
326
expandPredicate(raw_ostream & OS,const Record * Rec)327 void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
328 // Assume that padding has been added by the caller.
329 if (Rec->isSubClassOf("MCTrue")) {
330 if (shouldNegate())
331 return expandFalse(OS);
332 return expandTrue(OS);
333 }
334
335 if (Rec->isSubClassOf("MCFalse")) {
336 if (shouldNegate())
337 return expandTrue(OS);
338 return expandFalse(OS);
339 }
340
341 if (Rec->isSubClassOf("CheckNot")) {
342 flipNegatePredicate();
343 expandPredicate(OS, Rec->getValueAsDef("Pred"));
344 flipNegatePredicate();
345 return;
346 }
347
348 if (Rec->isSubClassOf("CheckIsRegOperand"))
349 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
350
351 if (Rec->isSubClassOf("CheckIsVRegOperand"))
352 return expandCheckIsVRegOperand(OS, Rec->getValueAsInt("OpIndex"));
353
354 if (Rec->isSubClassOf("CheckIsImmOperand"))
355 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
356
357 if (Rec->isSubClassOf("CheckRegOperand"))
358 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
359 Rec->getValueAsDef("Reg"),
360 Rec->getValueAsString("FunctionMapper"));
361
362 if (Rec->isSubClassOf("CheckRegOperandSimple"))
363 return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
364 Rec->getValueAsString("FunctionMapper"));
365
366 if (Rec->isSubClassOf("CheckInvalidRegOperand"))
367 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
368
369 if (Rec->isSubClassOf("CheckImmOperand"))
370 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
371 Rec->getValueAsInt("ImmVal"),
372 Rec->getValueAsString("FunctionMapper"));
373
374 if (Rec->isSubClassOf("CheckImmOperand_s"))
375 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
376 Rec->getValueAsString("ImmVal"),
377 Rec->getValueAsString("FunctionMapper"));
378
379 if (Rec->isSubClassOf("CheckImmOperandLT"))
380 return expandCheckImmOperandLT(OS, Rec->getValueAsInt("OpIndex"),
381 Rec->getValueAsInt("ImmVal"),
382 Rec->getValueAsString("FunctionMapper"));
383
384 if (Rec->isSubClassOf("CheckImmOperandGT"))
385 return expandCheckImmOperandGT(OS, Rec->getValueAsInt("OpIndex"),
386 Rec->getValueAsInt("ImmVal"),
387 Rec->getValueAsString("FunctionMapper"));
388
389 if (Rec->isSubClassOf("CheckImmOperandSimple"))
390 return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
391 Rec->getValueAsString("FunctionMapper"));
392
393 if (Rec->isSubClassOf("CheckSameRegOperand"))
394 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
395 Rec->getValueAsInt("SecondIndex"));
396
397 if (Rec->isSubClassOf("CheckNumOperands"))
398 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
399
400 if (Rec->isSubClassOf("CheckPseudo"))
401 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
402
403 if (Rec->isSubClassOf("CheckOpcode"))
404 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
405
406 if (Rec->isSubClassOf("CheckAll"))
407 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
408 /* AllOf */ true);
409
410 if (Rec->isSubClassOf("CheckAny"))
411 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
412 /* AllOf */ false);
413
414 if (Rec->isSubClassOf("CheckFunctionPredicate")) {
415 return expandCheckFunctionPredicate(
416 OS, Rec->getValueAsString("MCInstFnName"),
417 Rec->getValueAsString("MachineInstrFnName"));
418 }
419
420 if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) {
421 return expandCheckFunctionPredicateWithTII(
422 OS, Rec->getValueAsString("MCInstFnName"),
423 Rec->getValueAsString("MachineInstrFnName"),
424 Rec->getValueAsString("TIIPtrName"));
425 }
426
427 if (Rec->isSubClassOf("CheckNonPortable"))
428 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
429
430 if (Rec->isSubClassOf("TIIPredicate"))
431 return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
432
433 llvm_unreachable("No known rules to expand this MCInstPredicate");
434 }
435
expandHeader(raw_ostream & OS,const STIPredicateFunction & Fn)436 void STIPredicateExpander::expandHeader(raw_ostream &OS,
437 const STIPredicateFunction &Fn) {
438 const Record *Rec = Fn.getDeclaration();
439 StringRef FunctionName = Rec->getValueAsString("Name");
440
441 OS.indent(getIndentLevel() * 2);
442 OS << "bool ";
443 if (shouldExpandDefinition())
444 OS << getClassPrefix() << "::";
445 OS << FunctionName << "(";
446 if (shouldExpandForMC())
447 OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
448 else
449 OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
450 if (Rec->getValueAsBit("UpdatesOpcodeMask"))
451 OS << ", APInt &Mask";
452 OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
453 if (shouldExpandDefinition()) {
454 OS << "{\n";
455 return;
456 }
457
458 if (Rec->getValueAsBit("OverridesBaseClassMember"))
459 OS << "override";
460 OS << ";\n";
461 }
462
expandPrologue(raw_ostream & OS,const STIPredicateFunction & Fn)463 void STIPredicateExpander::expandPrologue(raw_ostream &OS,
464 const STIPredicateFunction &Fn) {
465 RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
466 bool UpdatesOpcodeMask =
467 Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
468
469 increaseIndentLevel();
470 unsigned IndentLevel = getIndentLevel();
471 for (const Record *Delegate : Delegates) {
472 OS.indent(IndentLevel * 2);
473 OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
474 if (UpdatesOpcodeMask)
475 OS << ", Mask";
476 if (shouldExpandForMC())
477 OS << ", ProcessorID";
478 OS << "))\n";
479 OS.indent((1 + IndentLevel) * 2);
480 OS << "return true;\n\n";
481 }
482
483 if (shouldExpandForMC())
484 return;
485
486 OS.indent(IndentLevel * 2);
487 OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
488 }
489
expandOpcodeGroup(raw_ostream & OS,const OpcodeGroup & Group,bool ShouldUpdateOpcodeMask)490 void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
491 bool ShouldUpdateOpcodeMask) {
492 const OpcodeInfo &OI = Group.getOpcodeInfo();
493 for (const PredicateInfo &PI : OI.getPredicates()) {
494 const APInt &ProcModelMask = PI.ProcModelMask;
495 bool FirstProcID = true;
496 for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
497 if (!ProcModelMask[I])
498 continue;
499
500 if (FirstProcID) {
501 OS.indent(getIndentLevel() * 2);
502 OS << "if (ProcessorID == " << I;
503 } else {
504 OS << " || ProcessorID == " << I;
505 }
506 FirstProcID = false;
507 }
508
509 OS << ") {\n";
510
511 increaseIndentLevel();
512 OS.indent(getIndentLevel() * 2);
513 if (ShouldUpdateOpcodeMask) {
514 if (PI.OperandMask.isZero())
515 OS << "Mask.clearAllBits();\n";
516 else
517 OS << "Mask = " << PI.OperandMask << ";\n";
518 OS.indent(getIndentLevel() * 2);
519 }
520 OS << "return ";
521 expandPredicate(OS, PI.Predicate);
522 OS << ";\n";
523 decreaseIndentLevel();
524 OS.indent(getIndentLevel() * 2);
525 OS << "}\n";
526 }
527 }
528
expandBody(raw_ostream & OS,const STIPredicateFunction & Fn)529 void STIPredicateExpander::expandBody(raw_ostream &OS,
530 const STIPredicateFunction &Fn) {
531 bool UpdatesOpcodeMask =
532 Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
533
534 unsigned IndentLevel = getIndentLevel();
535 OS.indent(IndentLevel * 2);
536 OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
537 OS.indent(IndentLevel * 2);
538 OS << "default:\n";
539 OS.indent(IndentLevel * 2);
540 OS << " break;";
541
542 for (const OpcodeGroup &Group : Fn.getGroups()) {
543 for (const Record *Opcode : Group.getOpcodes()) {
544 OS << '\n';
545 OS.indent(IndentLevel * 2);
546 OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
547 }
548
549 OS << '\n';
550 increaseIndentLevel();
551 expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
552
553 OS.indent(getIndentLevel() * 2);
554 OS << "break;\n";
555 decreaseIndentLevel();
556 }
557
558 OS.indent(IndentLevel * 2);
559 OS << "}\n";
560 }
561
expandEpilogue(raw_ostream & OS,const STIPredicateFunction & Fn)562 void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
563 const STIPredicateFunction &Fn) {
564 OS << '\n';
565 OS.indent(getIndentLevel() * 2);
566 OS << "return ";
567 expandPredicate(OS, Fn.getDefaultReturnPredicate());
568 OS << ";\n";
569
570 decreaseIndentLevel();
571 OS.indent(getIndentLevel() * 2);
572 StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
573 OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
574 }
575
expandSTIPredicate(raw_ostream & OS,const STIPredicateFunction & Fn)576 void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
577 const STIPredicateFunction &Fn) {
578 const Record *Rec = Fn.getDeclaration();
579 if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
580 return;
581
582 expandHeader(OS, Fn);
583 if (shouldExpandDefinition()) {
584 expandPrologue(OS, Fn);
585 expandBody(OS, Fn);
586 expandEpilogue(OS, Fn);
587 }
588 }
589
590 } // namespace llvm
591