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