xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/Common/PredicateExpander.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
expandCheckRegOperandSimple(raw_ostream & OS,int OpIndex,StringRef FunctionMapper)104 void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS,
105                                                     int OpIndex,
106                                                     StringRef FunctionMapper) {
107   if (shouldNegate())
108     OS << "!";
109   if (!FunctionMapper.empty())
110     OS << FunctionMapper << "(";
111   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
112      << ").getReg()";
113   if (!FunctionMapper.empty())
114     OS << ")";
115 }
116 
expandCheckInvalidRegOperand(raw_ostream & OS,int OpIndex)117 void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
118                                                      int OpIndex) {
119   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
120      << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
121 }
122 
expandCheckSameRegOperand(raw_ostream & OS,int First,int Second)123 void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
124                                                   int Second) {
125   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
126      << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
127      << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
128 }
129 
expandCheckNumOperands(raw_ostream & OS,int NumOps)130 void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
131   OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
132      << (shouldNegate() ? "!= " : "== ") << NumOps;
133 }
134 
expandCheckOpcode(raw_ostream & OS,const Record * Inst)135 void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
136   OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
137      << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
138      << "::" << Inst->getName();
139 }
140 
expandCheckOpcode(raw_ostream & OS,const RecVec & Opcodes)141 void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
142                                           const RecVec &Opcodes) {
143   assert(!Opcodes.empty() && "Expected at least one opcode to check!");
144   bool First = true;
145 
146   if (Opcodes.size() == 1) {
147     OS << "( ";
148     expandCheckOpcode(OS, Opcodes[0]);
149     OS << " )";
150     return;
151   }
152 
153   OS << '(';
154   increaseIndentLevel();
155   for (const Record *Rec : Opcodes) {
156     OS << '\n';
157     OS.indent(getIndentLevel() * 2);
158     if (!First)
159       OS << (shouldNegate() ? "&& " : "|| ");
160 
161     expandCheckOpcode(OS, Rec);
162     First = false;
163   }
164 
165   OS << '\n';
166   decreaseIndentLevel();
167   OS.indent(getIndentLevel() * 2);
168   OS << ')';
169 }
170 
expandCheckPseudo(raw_ostream & OS,const RecVec & Opcodes)171 void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
172                                           const RecVec &Opcodes) {
173   if (shouldExpandForMC())
174     expandFalse(OS);
175   else
176     expandCheckOpcode(OS, Opcodes);
177 }
178 
expandPredicateSequence(raw_ostream & OS,const RecVec & Sequence,bool IsCheckAll)179 void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
180                                                 const RecVec &Sequence,
181                                                 bool IsCheckAll) {
182   assert(!Sequence.empty() && "Found an invalid empty predicate set!");
183   if (Sequence.size() == 1)
184     return expandPredicate(OS, Sequence[0]);
185 
186   // Okay, there is more than one predicate in the set.
187   bool First = true;
188   OS << (shouldNegate() ? "!(" : "(");
189   increaseIndentLevel();
190 
191   bool OldValue = shouldNegate();
192   setNegatePredicate(false);
193   for (const Record *Rec : Sequence) {
194     OS << '\n';
195     OS.indent(getIndentLevel() * 2);
196     if (!First)
197       OS << (IsCheckAll ? "&& " : "|| ");
198     expandPredicate(OS, Rec);
199     First = false;
200   }
201   OS << '\n';
202   decreaseIndentLevel();
203   OS.indent(getIndentLevel() * 2);
204   OS << ')';
205   setNegatePredicate(OldValue);
206 }
207 
expandTIIFunctionCall(raw_ostream & OS,StringRef MethodName)208 void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
209                                               StringRef MethodName) {
210   OS << (shouldNegate() ? "!" : "");
211   OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
212   OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
213 }
214 
expandCheckIsRegOperand(raw_ostream & OS,int OpIndex)215 void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
216   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
217      << "getOperand(" << OpIndex << ").isReg() ";
218 }
219 
expandCheckIsVRegOperand(raw_ostream & OS,int OpIndex)220 void PredicateExpander::expandCheckIsVRegOperand(raw_ostream &OS, int OpIndex) {
221   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
222      << "getOperand(" << OpIndex << ").getReg().isVirtual()";
223 }
224 
expandCheckIsImmOperand(raw_ostream & OS,int OpIndex)225 void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
226   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
227      << "getOperand(" << OpIndex << ").isImm() ";
228 }
229 
expandCheckFunctionPredicateWithTII(raw_ostream & OS,StringRef MCInstFn,StringRef MachineInstrFn,StringRef TIIPtr)230 void PredicateExpander::expandCheckFunctionPredicateWithTII(
231     raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn,
232     StringRef TIIPtr) {
233   if (!shouldExpandForMC()) {
234     OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn;
235     OS << (isByRef() ? "(MI)" : "(*MI)");
236     return;
237   }
238 
239   OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)";
240 }
241 
expandCheckFunctionPredicate(raw_ostream & OS,StringRef MCInstFn,StringRef MachineInstrFn)242 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
243                                                      StringRef MCInstFn,
244                                                      StringRef MachineInstrFn) {
245   OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
246      << (isByRef() ? "(MI)" : "(*MI)");
247 }
248 
expandCheckNonPortable(raw_ostream & OS,StringRef Code)249 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
250                                                StringRef Code) {
251   if (shouldExpandForMC())
252     return expandFalse(OS);
253 
254   OS << '(' << Code << ')';
255 }
256 
expandReturnStatement(raw_ostream & OS,const Record * Rec)257 void PredicateExpander::expandReturnStatement(raw_ostream &OS,
258                                               const Record *Rec) {
259   std::string Buffer;
260   raw_string_ostream SS(Buffer);
261 
262   SS << "return ";
263   expandPredicate(SS, Rec);
264   SS << ";";
265   OS << Buffer;
266 }
267 
expandOpcodeSwitchCase(raw_ostream & OS,const Record * Rec)268 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
269                                                const Record *Rec) {
270   const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
271   for (const Record *Opcode : Opcodes) {
272     OS.indent(getIndentLevel() * 2);
273     OS << "case " << Opcode->getValueAsString("Namespace")
274        << "::" << Opcode->getName() << ":\n";
275   }
276 
277   increaseIndentLevel();
278   OS.indent(getIndentLevel() * 2);
279   expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
280   decreaseIndentLevel();
281 }
282 
expandOpcodeSwitchStatement(raw_ostream & OS,const RecVec & Cases,const Record * Default)283 void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
284                                                     const RecVec &Cases,
285                                                     const Record *Default) {
286   std::string Buffer;
287   raw_string_ostream SS(Buffer);
288 
289   SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
290   for (const Record *Rec : Cases) {
291     expandOpcodeSwitchCase(SS, Rec);
292     SS << '\n';
293   }
294 
295   // Expand the default case.
296   SS.indent(getIndentLevel() * 2);
297   SS << "default:\n";
298 
299   increaseIndentLevel();
300   SS.indent(getIndentLevel() * 2);
301   expandStatement(SS, Default);
302   decreaseIndentLevel();
303   SS << '\n';
304 
305   SS.indent(getIndentLevel() * 2);
306   SS << "} // end of switch-stmt";
307   OS << Buffer;
308 }
309 
expandStatement(raw_ostream & OS,const Record * Rec)310 void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
311   // Assume that padding has been added by the caller.
312   if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
313     expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
314                                 Rec->getValueAsDef("DefaultCase"));
315     return;
316   }
317 
318   if (Rec->isSubClassOf("MCReturnStatement")) {
319     expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
320     return;
321   }
322 
323   llvm_unreachable("No known rules to expand this MCStatement");
324 }
325 
expandPredicate(raw_ostream & OS,const Record * Rec)326 void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
327   // Assume that padding has been added by the caller.
328   if (Rec->isSubClassOf("MCTrue")) {
329     if (shouldNegate())
330       return expandFalse(OS);
331     return expandTrue(OS);
332   }
333 
334   if (Rec->isSubClassOf("MCFalse")) {
335     if (shouldNegate())
336       return expandTrue(OS);
337     return expandFalse(OS);
338   }
339 
340   if (Rec->isSubClassOf("CheckNot")) {
341     flipNegatePredicate();
342     expandPredicate(OS, Rec->getValueAsDef("Pred"));
343     flipNegatePredicate();
344     return;
345   }
346 
347   if (Rec->isSubClassOf("CheckIsRegOperand"))
348     return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
349 
350   if (Rec->isSubClassOf("CheckIsVRegOperand"))
351     return expandCheckIsVRegOperand(OS, Rec->getValueAsInt("OpIndex"));
352 
353   if (Rec->isSubClassOf("CheckIsImmOperand"))
354     return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
355 
356   if (Rec->isSubClassOf("CheckRegOperand"))
357     return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
358                                  Rec->getValueAsDef("Reg"),
359                                  Rec->getValueAsString("FunctionMapper"));
360 
361   if (Rec->isSubClassOf("CheckRegOperandSimple"))
362     return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
363                                        Rec->getValueAsString("FunctionMapper"));
364 
365   if (Rec->isSubClassOf("CheckInvalidRegOperand"))
366     return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
367 
368   if (Rec->isSubClassOf("CheckImmOperand"))
369     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
370                                  Rec->getValueAsInt("ImmVal"),
371                                  Rec->getValueAsString("FunctionMapper"));
372 
373   if (Rec->isSubClassOf("CheckImmOperand_s"))
374     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
375                                  Rec->getValueAsString("ImmVal"),
376                                  Rec->getValueAsString("FunctionMapper"));
377 
378   if (Rec->isSubClassOf("CheckImmOperandLT"))
379     return expandCheckImmOperandLT(OS, Rec->getValueAsInt("OpIndex"),
380                                    Rec->getValueAsInt("ImmVal"),
381                                    Rec->getValueAsString("FunctionMapper"));
382 
383   if (Rec->isSubClassOf("CheckImmOperandGT"))
384     return expandCheckImmOperandGT(OS, Rec->getValueAsInt("OpIndex"),
385                                    Rec->getValueAsInt("ImmVal"),
386                                    Rec->getValueAsString("FunctionMapper"));
387 
388   if (Rec->isSubClassOf("CheckImmOperandSimple"))
389     return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
390                                        Rec->getValueAsString("FunctionMapper"));
391 
392   if (Rec->isSubClassOf("CheckSameRegOperand"))
393     return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
394                                      Rec->getValueAsInt("SecondIndex"));
395 
396   if (Rec->isSubClassOf("CheckNumOperands"))
397     return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
398 
399   if (Rec->isSubClassOf("CheckPseudo"))
400     return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
401 
402   if (Rec->isSubClassOf("CheckOpcode"))
403     return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
404 
405   if (Rec->isSubClassOf("CheckAll"))
406     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
407                                    /* AllOf */ true);
408 
409   if (Rec->isSubClassOf("CheckAny"))
410     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
411                                    /* AllOf */ false);
412 
413   if (Rec->isSubClassOf("CheckFunctionPredicate")) {
414     return expandCheckFunctionPredicate(
415         OS, Rec->getValueAsString("MCInstFnName"),
416         Rec->getValueAsString("MachineInstrFnName"));
417   }
418 
419   if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) {
420     return expandCheckFunctionPredicateWithTII(
421         OS, Rec->getValueAsString("MCInstFnName"),
422         Rec->getValueAsString("MachineInstrFnName"),
423         Rec->getValueAsString("TIIPtrName"));
424   }
425 
426   if (Rec->isSubClassOf("CheckNonPortable"))
427     return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
428 
429   if (Rec->isSubClassOf("TIIPredicate"))
430     return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
431 
432   llvm_unreachable("No known rules to expand this MCInstPredicate");
433 }
434 
expandHeader(raw_ostream & OS,const STIPredicateFunction & Fn)435 void STIPredicateExpander::expandHeader(raw_ostream &OS,
436                                         const STIPredicateFunction &Fn) {
437   const Record *Rec = Fn.getDeclaration();
438   StringRef FunctionName = Rec->getValueAsString("Name");
439 
440   OS.indent(getIndentLevel() * 2);
441   OS << "bool ";
442   if (shouldExpandDefinition())
443     OS << getClassPrefix() << "::";
444   OS << FunctionName << "(";
445   if (shouldExpandForMC())
446     OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
447   else
448     OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
449   if (Rec->getValueAsBit("UpdatesOpcodeMask"))
450     OS << ", APInt &Mask";
451   OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
452   if (shouldExpandDefinition()) {
453     OS << "{\n";
454     return;
455   }
456 
457   if (Rec->getValueAsBit("OverridesBaseClassMember"))
458     OS << "override";
459   OS << ";\n";
460 }
461 
expandPrologue(raw_ostream & OS,const STIPredicateFunction & Fn)462 void STIPredicateExpander::expandPrologue(raw_ostream &OS,
463                                           const STIPredicateFunction &Fn) {
464   RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
465   bool UpdatesOpcodeMask =
466       Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
467 
468   increaseIndentLevel();
469   unsigned IndentLevel = getIndentLevel();
470   for (const Record *Delegate : Delegates) {
471     OS.indent(IndentLevel * 2);
472     OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
473     if (UpdatesOpcodeMask)
474       OS << ", Mask";
475     if (shouldExpandForMC())
476       OS << ", ProcessorID";
477     OS << "))\n";
478     OS.indent((1 + IndentLevel) * 2);
479     OS << "return true;\n\n";
480   }
481 
482   if (shouldExpandForMC())
483     return;
484 
485   OS.indent(IndentLevel * 2);
486   OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
487 }
488 
expandOpcodeGroup(raw_ostream & OS,const OpcodeGroup & Group,bool ShouldUpdateOpcodeMask)489 void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS,
490                                              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