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