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 | |
19 | void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true" ; } |
20 | void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false" ; } |
21 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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(FieldName: "Namespace" ); |
99 | if (!Str.empty()) |
100 | OS << Str << "::" ; |
101 | OS << Reg->getName(); |
102 | } |
103 | |
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 | |
117 | void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS, |
118 | int OpIndex) { |
119 | OS << "MI" << (isByRef() ? "." : "->" ) << "getOperand(" << OpIndex |
120 | << ").getReg() " << (shouldNegate() ? "!= " : "== " ) << "0" ; |
121 | } |
122 | |
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 | |
130 | void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) { |
131 | OS << "MI" << (isByRef() ? "." : "->" ) << "getNumOperands() " |
132 | << (shouldNegate() ? "!= " : "== " ) << NumOps; |
133 | } |
134 | |
135 | void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) { |
136 | OS << "MI" << (isByRef() ? "." : "->" ) << "getOpcode() " |
137 | << (shouldNegate() ? "!= " : "== " ) << Inst->getValueAsString(FieldName: "Namespace" ) |
138 | << "::" << Inst->getName(); |
139 | } |
140 | |
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, Inst: Opcodes[0]); |
149 | OS << " )" ; |
150 | return; |
151 | } |
152 | |
153 | OS << '('; |
154 | increaseIndentLevel(); |
155 | for (const Record *Rec : Opcodes) { |
156 | OS << '\n'; |
157 | OS.indent(NumSpaces: getIndentLevel() * 2); |
158 | if (!First) |
159 | OS << (shouldNegate() ? "&& " : "|| " ); |
160 | |
161 | expandCheckOpcode(OS, Inst: Rec); |
162 | First = false; |
163 | } |
164 | |
165 | OS << '\n'; |
166 | decreaseIndentLevel(); |
167 | OS.indent(NumSpaces: getIndentLevel() * 2); |
168 | OS << ')'; |
169 | } |
170 | |
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 | |
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, Rec: 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(NumSpaces: getIndentLevel() * 2); |
196 | if (!First) |
197 | OS << (IsCheckAll ? "&& " : "|| " ); |
198 | expandPredicate(OS, Rec); |
199 | First = false; |
200 | } |
201 | OS << '\n'; |
202 | decreaseIndentLevel(); |
203 | OS.indent(NumSpaces: getIndentLevel() * 2); |
204 | OS << ')'; |
205 | setNegatePredicate(OldValue); |
206 | } |
207 | |
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 | |
215 | void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { |
216 | OS << (shouldNegate() ? "!" : "" ) << "MI" << (isByRef() ? "." : "->" ) |
217 | << "getOperand(" << OpIndex << ").isReg() " ; |
218 | } |
219 | |
220 | void PredicateExpander::expandCheckIsVRegOperand(raw_ostream &OS, int OpIndex) { |
221 | OS << (shouldNegate() ? "!" : "" ) << "MI" << (isByRef() ? "." : "->" ) |
222 | << "getOperand(" << OpIndex << ").getReg().isVirtual()" ; |
223 | } |
224 | |
225 | void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { |
226 | OS << (shouldNegate() ? "!" : "" ) << "MI" << (isByRef() ? "." : "->" ) |
227 | << "getOperand(" << OpIndex << ").isImm() " ; |
228 | } |
229 | |
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 | |
242 | void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, |
243 | StringRef MCInstFn, |
244 | StringRef MachineInstrFn) { |
245 | OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) |
246 | << (isByRef() ? "(MI)" : "(*MI)" ); |
247 | } |
248 | |
249 | void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, |
250 | StringRef Code) { |
251 | if (shouldExpandForMC()) |
252 | return expandFalse(OS); |
253 | |
254 | OS << '(' << Code << ')'; |
255 | } |
256 | |
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(OS&: SS, Rec); |
264 | SS << ";" ; |
265 | OS << Buffer; |
266 | } |
267 | |
268 | void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, |
269 | const Record *Rec) { |
270 | const RecVec &Opcodes = Rec->getValueAsListOfDefs(FieldName: "Opcodes" ); |
271 | for (const Record *Opcode : Opcodes) { |
272 | OS.indent(NumSpaces: getIndentLevel() * 2); |
273 | OS << "case " << Opcode->getValueAsString(FieldName: "Namespace" ) |
274 | << "::" << Opcode->getName() << ":\n" ; |
275 | } |
276 | |
277 | increaseIndentLevel(); |
278 | OS.indent(NumSpaces: getIndentLevel() * 2); |
279 | expandStatement(OS, Rec: Rec->getValueAsDef(FieldName: "CaseStmt" )); |
280 | decreaseIndentLevel(); |
281 | } |
282 | |
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(OS&: SS, Rec); |
292 | SS << '\n'; |
293 | } |
294 | |
295 | // Expand the default case. |
296 | SS.indent(NumSpaces: getIndentLevel() * 2); |
297 | SS << "default:\n" ; |
298 | |
299 | increaseIndentLevel(); |
300 | SS.indent(NumSpaces: getIndentLevel() * 2); |
301 | expandStatement(OS&: SS, Rec: Default); |
302 | decreaseIndentLevel(); |
303 | SS << '\n'; |
304 | |
305 | SS.indent(NumSpaces: getIndentLevel() * 2); |
306 | SS << "} // end of switch-stmt" ; |
307 | OS << Buffer; |
308 | } |
309 | |
310 | void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { |
311 | // Assume that padding has been added by the caller. |
312 | if (Rec->isSubClassOf(Name: "MCOpcodeSwitchStatement" )) { |
313 | expandOpcodeSwitchStatement(OS, Cases: Rec->getValueAsListOfDefs(FieldName: "Cases" ), |
314 | Default: Rec->getValueAsDef(FieldName: "DefaultCase" )); |
315 | return; |
316 | } |
317 | |
318 | if (Rec->isSubClassOf(Name: "MCReturnStatement" )) { |
319 | expandReturnStatement(OS, Rec: Rec->getValueAsDef(FieldName: "Pred" )); |
320 | return; |
321 | } |
322 | |
323 | llvm_unreachable("No known rules to expand this MCStatement" ); |
324 | } |
325 | |
326 | void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { |
327 | // Assume that padding has been added by the caller. |
328 | if (Rec->isSubClassOf(Name: "MCTrue" )) { |
329 | if (shouldNegate()) |
330 | return expandFalse(OS); |
331 | return expandTrue(OS); |
332 | } |
333 | |
334 | if (Rec->isSubClassOf(Name: "MCFalse" )) { |
335 | if (shouldNegate()) |
336 | return expandTrue(OS); |
337 | return expandFalse(OS); |
338 | } |
339 | |
340 | if (Rec->isSubClassOf(Name: "CheckNot" )) { |
341 | flipNegatePredicate(); |
342 | expandPredicate(OS, Rec: Rec->getValueAsDef(FieldName: "Pred" )); |
343 | flipNegatePredicate(); |
344 | return; |
345 | } |
346 | |
347 | if (Rec->isSubClassOf(Name: "CheckIsRegOperand" )) |
348 | return expandCheckIsRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" )); |
349 | |
350 | if (Rec->isSubClassOf(Name: "CheckIsVRegOperand" )) |
351 | return expandCheckIsVRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" )); |
352 | |
353 | if (Rec->isSubClassOf(Name: "CheckIsImmOperand" )) |
354 | return expandCheckIsImmOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" )); |
355 | |
356 | if (Rec->isSubClassOf(Name: "CheckRegOperand" )) |
357 | return expandCheckRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" ), |
358 | Reg: Rec->getValueAsDef(FieldName: "Reg" ), |
359 | FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper" )); |
360 | |
361 | if (Rec->isSubClassOf(Name: "CheckRegOperandSimple" )) |
362 | return expandCheckRegOperandSimple(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" ), |
363 | FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper" )); |
364 | |
365 | if (Rec->isSubClassOf(Name: "CheckInvalidRegOperand" )) |
366 | return expandCheckInvalidRegOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" )); |
367 | |
368 | if (Rec->isSubClassOf(Name: "CheckImmOperand" )) |
369 | return expandCheckImmOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" ), |
370 | ImmVal: Rec->getValueAsInt(FieldName: "ImmVal" ), |
371 | FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper" )); |
372 | |
373 | if (Rec->isSubClassOf(Name: "CheckImmOperand_s" )) |
374 | return expandCheckImmOperand(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" ), |
375 | ImmVal: Rec->getValueAsString(FieldName: "ImmVal" ), |
376 | FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper" )); |
377 | |
378 | if (Rec->isSubClassOf(Name: "CheckImmOperandLT" )) |
379 | return expandCheckImmOperandLT(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" ), |
380 | ImmVal: Rec->getValueAsInt(FieldName: "ImmVal" ), |
381 | FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper" )); |
382 | |
383 | if (Rec->isSubClassOf(Name: "CheckImmOperandGT" )) |
384 | return expandCheckImmOperandGT(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" ), |
385 | ImmVal: Rec->getValueAsInt(FieldName: "ImmVal" ), |
386 | FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper" )); |
387 | |
388 | if (Rec->isSubClassOf(Name: "CheckImmOperandSimple" )) |
389 | return expandCheckImmOperandSimple(OS, OpIndex: Rec->getValueAsInt(FieldName: "OpIndex" ), |
390 | FunctionMapper: Rec->getValueAsString(FieldName: "FunctionMapper" )); |
391 | |
392 | if (Rec->isSubClassOf(Name: "CheckSameRegOperand" )) |
393 | return expandCheckSameRegOperand(OS, First: Rec->getValueAsInt(FieldName: "FirstIndex" ), |
394 | Second: Rec->getValueAsInt(FieldName: "SecondIndex" )); |
395 | |
396 | if (Rec->isSubClassOf(Name: "CheckNumOperands" )) |
397 | return expandCheckNumOperands(OS, NumOps: Rec->getValueAsInt(FieldName: "NumOps" )); |
398 | |
399 | if (Rec->isSubClassOf(Name: "CheckPseudo" )) |
400 | return expandCheckPseudo(OS, Opcodes: Rec->getValueAsListOfDefs(FieldName: "ValidOpcodes" )); |
401 | |
402 | if (Rec->isSubClassOf(Name: "CheckOpcode" )) |
403 | return expandCheckOpcode(OS, Opcodes: Rec->getValueAsListOfDefs(FieldName: "ValidOpcodes" )); |
404 | |
405 | if (Rec->isSubClassOf(Name: "CheckAll" )) |
406 | return expandPredicateSequence(OS, Sequence: Rec->getValueAsListOfDefs(FieldName: "Predicates" ), |
407 | /* AllOf */ IsCheckAll: true); |
408 | |
409 | if (Rec->isSubClassOf(Name: "CheckAny" )) |
410 | return expandPredicateSequence(OS, Sequence: Rec->getValueAsListOfDefs(FieldName: "Predicates" ), |
411 | /* AllOf */ IsCheckAll: false); |
412 | |
413 | if (Rec->isSubClassOf(Name: "CheckFunctionPredicate" )) { |
414 | return expandCheckFunctionPredicate( |
415 | OS, MCInstFn: Rec->getValueAsString(FieldName: "MCInstFnName" ), |
416 | MachineInstrFn: Rec->getValueAsString(FieldName: "MachineInstrFnName" )); |
417 | } |
418 | |
419 | if (Rec->isSubClassOf(Name: "CheckFunctionPredicateWithTII" )) { |
420 | return expandCheckFunctionPredicateWithTII( |
421 | OS, MCInstFn: Rec->getValueAsString(FieldName: "MCInstFnName" ), |
422 | MachineInstrFn: Rec->getValueAsString(FieldName: "MachineInstrFnName" ), |
423 | TIIPtr: Rec->getValueAsString(FieldName: "TIIPtrName" )); |
424 | } |
425 | |
426 | if (Rec->isSubClassOf(Name: "CheckNonPortable" )) |
427 | return expandCheckNonPortable(OS, Code: Rec->getValueAsString(FieldName: "CodeBlock" )); |
428 | |
429 | if (Rec->isSubClassOf(Name: "TIIPredicate" )) |
430 | return expandTIIFunctionCall(OS, MethodName: Rec->getValueAsString(FieldName: "FunctionName" )); |
431 | |
432 | llvm_unreachable("No known rules to expand this MCInstPredicate" ); |
433 | } |
434 | |
435 | void STIPredicateExpander::expandHeader(raw_ostream &OS, |
436 | const STIPredicateFunction &Fn) { |
437 | const Record *Rec = Fn.getDeclaration(); |
438 | StringRef FunctionName = Rec->getValueAsString(FieldName: "Name" ); |
439 | |
440 | OS.indent(NumSpaces: 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(FieldName: "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(FieldName: "OverridesBaseClassMember" )) |
458 | OS << "override" ; |
459 | OS << ";\n" ; |
460 | } |
461 | |
462 | void STIPredicateExpander::expandPrologue(raw_ostream &OS, |
463 | const STIPredicateFunction &Fn) { |
464 | RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs(FieldName: "Delegates" ); |
465 | bool UpdatesOpcodeMask = |
466 | Fn.getDeclaration()->getValueAsBit(FieldName: "UpdatesOpcodeMask" ); |
467 | |
468 | increaseIndentLevel(); |
469 | unsigned IndentLevel = getIndentLevel(); |
470 | for (const Record *Delegate : Delegates) { |
471 | OS.indent(NumSpaces: IndentLevel * 2); |
472 | OS << "if (" << Delegate->getValueAsString(FieldName: "Name" ) << "(MI" ; |
473 | if (UpdatesOpcodeMask) |
474 | OS << ", Mask" ; |
475 | if (shouldExpandForMC()) |
476 | OS << ", ProcessorID" ; |
477 | OS << "))\n" ; |
478 | OS.indent(NumSpaces: (1 + IndentLevel) * 2); |
479 | OS << "return true;\n\n" ; |
480 | } |
481 | |
482 | if (shouldExpandForMC()) |
483 | return; |
484 | |
485 | OS.indent(NumSpaces: IndentLevel * 2); |
486 | OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n" ; |
487 | } |
488 | |
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(NumSpaces: 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(NumSpaces: 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(NumSpaces: getIndentLevel() * 2); |
519 | } |
520 | OS << "return " ; |
521 | expandPredicate(OS, Rec: PI.Predicate); |
522 | OS << ";\n" ; |
523 | decreaseIndentLevel(); |
524 | OS.indent(NumSpaces: getIndentLevel() * 2); |
525 | OS << "}\n" ; |
526 | } |
527 | } |
528 | |
529 | void STIPredicateExpander::expandBody(raw_ostream &OS, |
530 | const STIPredicateFunction &Fn) { |
531 | bool UpdatesOpcodeMask = |
532 | Fn.getDeclaration()->getValueAsBit(FieldName: "UpdatesOpcodeMask" ); |
533 | |
534 | unsigned IndentLevel = getIndentLevel(); |
535 | OS.indent(NumSpaces: IndentLevel * 2); |
536 | OS << "switch(MI" << (isByRef() ? "." : "->" ) << "getOpcode()) {\n" ; |
537 | OS.indent(NumSpaces: IndentLevel * 2); |
538 | OS << "default:\n" ; |
539 | OS.indent(NumSpaces: 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(NumSpaces: IndentLevel * 2); |
546 | OS << "case " << getTargetName() << "::" << Opcode->getName() << ":" ; |
547 | } |
548 | |
549 | OS << '\n'; |
550 | increaseIndentLevel(); |
551 | expandOpcodeGroup(OS, Group, ShouldUpdateOpcodeMask: UpdatesOpcodeMask); |
552 | |
553 | OS.indent(NumSpaces: getIndentLevel() * 2); |
554 | OS << "break;\n" ; |
555 | decreaseIndentLevel(); |
556 | } |
557 | |
558 | OS.indent(NumSpaces: IndentLevel * 2); |
559 | OS << "}\n" ; |
560 | } |
561 | |
562 | void STIPredicateExpander::expandEpilogue(raw_ostream &OS, |
563 | const STIPredicateFunction &Fn) { |
564 | OS << '\n'; |
565 | OS.indent(NumSpaces: getIndentLevel() * 2); |
566 | OS << "return " ; |
567 | expandPredicate(OS, Rec: Fn.getDefaultReturnPredicate()); |
568 | OS << ";\n" ; |
569 | |
570 | decreaseIndentLevel(); |
571 | OS.indent(NumSpaces: getIndentLevel() * 2); |
572 | StringRef FunctionName = Fn.getDeclaration()->getValueAsString(FieldName: "Name" ); |
573 | OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n" ; |
574 | } |
575 | |
576 | void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS, |
577 | const STIPredicateFunction &Fn) { |
578 | const Record *Rec = Fn.getDeclaration(); |
579 | if (shouldExpandForMC() && !Rec->getValueAsBit(FieldName: "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 | |